//土尔逊Torson 编写于2023/06/21
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAXN = 100;

struct Edge13001 {
	int from;      //边的起点
	int to;        //边的终点
	int length;    //边的长度
	bool operator<(const Edge13001& e) const {
		return length < e.length;
	}
};

Edge13001 edge13001[MAXN*MAXN]; //边集
int father13001[MAXN];     //父亲结点
int height13001[MAXN];     //结点高度

void Initial13001(int n) { //初始化
	for (int i = 0; i <= n; i++) {
		father13001[i] = i;
		height13001[i] = 0;
	}
}

int Find13001(int x) {
	if (x != father13001[x]) {
		father13001[x] = Find13001(father13001[x]);
	}
	return father13001[x];
}

void Union13001(int x, int y) {
	x = Find13001(x);
	y = Find13001(y);
	if (x != y) {
		if (height13001[x] < height13001[y]) {
			father13001[x] = y;
		}
		else if (height13001[y] < height13001[x]) {
			father13001[y] = x;
		}
		else {
			father13001[y] = x;
			height13001[x]++;
		}
	}
	return;
}

int Kruskal(int n, int edgeNumber) {
	Initial13001(n);
	sort(edge13001, edge13001 + edgeNumber); //按权值排序
	int sum = 0;
	for (int i = 0; i < edgeNumber; ++i) {
		Edge13001 current = edge13001[i];
		if (Find13001(current.from) != Find13001(current.to)) {
			Union13001(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", &edge13001[i].from, &edge13001[i].to, &edge13001[i].length);
		}
		int answer = Kruskal(n, edgeNumber);
		printf("%d\n", answer);
	}
	system("pause");
	return EXIT_SUCCESS;
}
// 64 位输出请用 printf("%lld")