#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=28;
int father[maxn];
int height[maxn];
struct Road{
    char from;
    char to;
    int weight;
    bool operator<(const Road& e) const{
        return weight<e.weight;
    }
};
Road road[100];
void initial(int n){
    for(int i=0;i<n;i++){
        father[i]=i;
        height[i]=0;
    }
}
int find(int x){
    if(x!=father[x]){
        father[x]=find(father[x]);
    }
    return father[x];
}
void Union(int x,int y){
    x=find(x);
    y=find(y);
    if(x!=y){
        if(height[x]<height[y]){
            father[x]=y;
        }
        else if(height[x]>height[y]){
            father[y]=x;
        }
        else{
            father[y]=x;
            height[x]++;
        }
    }
}
int Kruskal(int n,int edgenumber){
    initial(n);
    sort(road,road+edgenumber);
    int answer=0;
    for(int i=0;i<edgenumber;i++){
        int x=road[i].from-'A';
        int y=road[i].to-'A';
        if(find(x)!=find(y)){
            answer+=road[i].weight;
            Union(x,y);
        }
    }
    return answer;
}
int main(){
    int n;
    while(cin>>n){
        if(n==0){
            break;
        }
        int k=0;
        int num=0;
        for(int i=0;i<n-1;i++){
            char c;
            int m;
            cin>>c>>m;
            if(m>0){
                for(int i=0;i<m;i++){
                    cin>>road[k].to>>road[k].weight;
                    road[k].from=c;
                    num++;
                    k++;
                }
            }
        }
        cout<<Kruskal(n,num)<<endl;
    }
}