#include<iostream>
#include<cstdio>
#include<algorithm>
 
using namespace std;
 
const int MAX=1000;

struct Edge{
    int from;                //边起点
    int to;                    //边终点
    int length;                //边长度
    bool operator < (const Edge& e)const{        ////为了使map能用自定义的结构体作为关键字
        return length < e.length;
    }
};

Edge edge[MAX * MAX];        //边集
int father[MAX];
int height[MAX];

void Initial(int n){
    for(int i=0;i<n;i++){                //初始化,每个节点父节点是自己,高度为0
        father[i]=i;                        //模拟初始时每个城镇都是孤立的
        height[i]=0;
    }
}

int Find(int x){                            //查找根结点
    if(x!=father[x])
        father[x]=Find(father[x]);            //一直循环找到x=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{                            //遇到相同情况,让y加入到x中去
            father[y]=x;
            height[x]++;
        }
    }
    return ;
}

int Kruskal(int n,int edgeNumber){
    Initial(n);
    sort(edge, edge + edgeNumber);
    int sum=0;
    for(int i=0;i<edgeNumber;i++){
        Edge current=edge[i];
        if(Find(current.from) != Find(current.to)){
            Union(current.from,current.to);
            sum += current.length;
        }
    }
    return sum;
}

int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        if(n==0)
            break;
        int edgeNumber=n*(n-1)/2;
        for(int i=0;i<edgeNumber;i++)
            scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].length);
        int answer=Kruskal(n,edgeNumber);
        printf("%d\n",answer);
    }
    return 0;
}