#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<P, int> P3;
const ll MOD = ll(1e9)+7;
const int IINF = INT_MAX;
const ll LLINF = LLONG_MAX;
const int MAX_N = int(1e5 + 5);
const double EPS = 1e-11;
const int di[] = {0, 1, 0, -1}, dj[] = {1, 0, -1, 0};
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define SORT(v) sort((v).begin(), (v).end())
#define ALL(v) (v).begin(), (v).end()

const int MAX_V = 100000;

struct UnionFindTree {
    int par[MAX_V];
    int rank[MAX_V];

    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]);
        }
    }

    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]++;
        }
    }

    bool same(int x, int y) { return find(x) == find(y); }
};

struct edge {
    int u, v, cost;
};

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

vector<edge> es;
int V, E;

int kruskal() {
    sort(es.begin(), es.end(), comp);
    UnionFindTree a;
    a.init(V);
    int res = 0;
    for (int i = 0; i < es.size(); i++) {
        edge e = es[i];
        if (!a.same(e.u, e.v)) {
            a.unite(e.u, e.v);
            res += e.cost;
        }
    }
    return res;
}
int main() {
    while(cin >> V >> E, V){
        REP(i,E){
            int a, b, c;
            cin >> a >> b >> c;
            es.push_back({a,b,c});
        }
        cout << kruskal() << endl;
        es.clear();
    }
    return 0;
}

