#include <stdio.h>
#include <math.h>
struct Point
{
double x;
double y;
};
struct Edge
{
int from;
int to;
int length;
};
const int MAXN = 101;
struct Edge edge[MAXN * MAXN];
struct Point point[MAXN];
int father[MAXN];
int height[MAXN];
// 定义比较函数,用于排序
int compare(const void *a, const void *b) {
// 将void指针转换为Edge结构体指针
const struct Edge *edgeA = (const struct Edge *)a;
const struct Edge *edgeB = (const struct Edge *)b;
// 根据边的长度进行比较
if (edgeA->length < edgeB->length)
return -1;
else if (edgeA->length > edgeB->length)
return 1;
else
return 0;
}
void InitialF(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[y] = x;
else if (height[y] > height[x])
father[x] = y;
else
{
father[y] = x;
height[x]++;
}
}
return;
}
int KrusKal(struct Edge edge[], int father[], int height[], int n, int edgeNumber)
{
InitialF(n);
int s =0;
qsort(edge, edgeNumber, sizeof(struct Edge), compare);
double answer = 0;
for (int i = 0; i < edgeNumber; i++)
{
if (Find(edge[i].from) != Find(edge[i].to))
{
Union(edge[i].from, edge[i].to);
s+=edge[i].length;
answer += sqrt(edge[i].length);
}
}
return s;
}
int main()
{
int n, a, b, c;
while (scanf("%d", &n) == 1)
{
if (n <= 0) break;
int edgeNumber = n * (n - 1) / 2;
for (int i = 0; i < n*(n-1)/2; i++)
scanf("%d %d %d", &edge[i].from, &edge[i].to, &edge[i].length);
//Initial(n);
printf("%d\n", KrusKal(edge, father, height, n, edgeNumber));
}
return 0;
}