#include<map>
#include<set>
#include<list>
#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<vector>
#include<complex>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<numeric>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cctype>

#define mp make_pair
#define pb push_back
#define REP(i,a,n) for(int i = a;i < (n);i++)
#define rep(i,n) for(int i = 0;i < (n);i++)
#define all(s) s.begin(), s.end()
#define rall(s) s.rbegin(), s.rend()
#define range(x,min,max) ((min) <= (x) && (x) <= (max))

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef vector<vector<int> > VII;
typedef pair<int,int> PII;

const int DX[]={1,0,-1,0},DY[]={0,-1,0,1};

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

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

vector<Edge> es;
VI parent;
VI rank;

void init(int n){
	rep(i,n){
		parent.pb(i);
		rank.pb(0);
	}
}

int find(int x){
	if(parent[x] == x){
		return x;
	}
	return parent[x] = find(parent[x]);
}

bool unite(int x, int y){
	x = find(x);
	y = find(y);

	if(x == y)
		return false;

	if(rank[x] < rank[y]){
		parent[x] = y;
	}else{
		parent[y] = x;
		if(rank[x] == rank[y]) rank[x]++;
	}
	return true;
}	

int main(){
	cin.tie(0);
   	ios::sync_with_stdio(false);

	while(1){
		int n, m;
		int ans = 0;

		cin >> n >> m;

		if(n == 0 && m == 0) break;

		rep(i,m){
			Edge e;
			cin >> e.from >> e.to >> e.cost;
			es.pb(e);
		}

		init(n);
		sort(all(es), comp);
		
		rep(i,es.size()){
			Edge e = es[i];
			if(!unite(e.from, e.to)){
				continue;
			}
			ans += e.cost;
		}

		cout << ans << endl;

		parent.clear();
		rank.clear();
		es.clear();
	}
	return 0;
}