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

using namespace std;

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

struct UnionFind {
    vector<int> data;
    UnionFind(int size) : data(size, -1) { }
    bool unionSet(int x, int y) {
        x = root(x); y = root(y);
        if (x != y) {
            if (data[y] < data[x]) swap(x, y);
            data[x] += data[y]; data[y] = x;
        }
        return x != y;
    }
    bool findSet(int x, int y) {
        return root(x) == root(y);
    }
    int root(int x) {
        return data[x] < 0 ? x : data[x] = root(data[x]);
    }
    int size(int x) {
        return -data[root(x)];
    }
};

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

const int MAX_M = (100 - 1) * 50 + 1;
int N, M;
edge es[MAX_M];

void Kruskal()
{
    sort(es, es + M, comp);
    UnionFind uf(N);
    int res = 0;
    int cnt = 0;

    for (int i = 0; i < M; i++) {
        edge e = es[i];
        if (!uf.findSet(e.u, e.v)) {
            uf.unionSet(e.u, e.v);
            res += e.cost;
            cnt++;
        }
    }

    cout << res << endl;
}

int main()
{
    while (cin >> N >> M, N || M) {
        for (int i = 0; i < M; ++i)
            cin >> es[i].u >> es[i].v >> es[i].cost;
        Kruskal();
    }

    return 0;
}