#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; } }