#include <iostream>
#include <algorithm>
#include <vector>

#define MAX_N (100)

struct edge { int from, to, cost; };

bool comp ( const edge& e1, const edge& e2 )
{
	return e1.cost < e2.cost;
}

int par[MAX_N];		/// 親
int rank[MAX_N];	/// 木の深さ

/// n要素で初期化
void init ( int n )
{
	for (int i = 0; i < n; ++i) {
		par[i] = i;
		rank[i] = 0;
	}
}

/// 木の根を求める
int find ( int x ) 
{
	if (par[x] == x) {
		return x;
	}
	else {
		return par[x] = find(par[x]);
	}
}

/// xとyの属する集合を合併
void unite ( int x, int y )
{
	x = find(x);
	y = find(y);

	if (x == y) { return; }

	if (rank[x] < rank[y]) {
		par[x] = y;
	}
	else {
		par[y] = x;
		if (rank[x] == rank[y]) { ++rank[x]; }
	}
}

/// xとyが同じ集合に属するか否か
bool same ( int x, int y )
{
	return find(x) == find(y);
}

using namespace std;

int main ( void )
{
	int n, m;

	while (cin >> n >> m, n | m) {
		vector<edge> es;
		for (int i = 0; i < m; ++i) {
			edge e;
			cin >> e.from >> e.to >> e.cost;
			es.push_back(e);
		}

		sort(es.begin(), es.end(), comp);
		init(n);
		int ans = 0;
		for (int i = 0; i < m; ++i) {
			edge e = es[i];
			if (!same(e.from, e.to)) {
				unite(e.from, e.to);
				ans += e.cost;
			}
		}

		cout << ans << endl;
	}
	return 0;
}