#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
#include <utility>
#include <set>
#include <cctype>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
using namespace std;
#define INF 100000000

typedef long long ll;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};

struct edge {
    int u;
    int v;
    int cost;
    bool operator<(const edge& r) const {
        return cost < r.cost;
    }
};

const int MAXM = 10000;
const int MAXN = 110;
edge es[MAXM];

int par[MAXN];
int rankrank[MAXN];

void init(int n) {
    for (int i = 0; i < n; i++) {
        par[i] = i;
        rankrank[i] = 0;
    }
}

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

void unite(int x, int y) {
    x = find(x); y = find(y);
    if (x == y) return;
    if (rankrank[x] < rankrank[y]) {
        par[x] = y;
    } else {
        par[y] = x;
        if (rankrank[x] == rankrank[y]) rankrank[x]++;
    }
}

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

int kruskal(int m) {
    sort(es, es+m);
    int ret = 0;
    for (int i = 0; i < m; i++) {
        edge e = es[i];
        if (!same(e.u, e.v)) {
            unite(e.u, e.v);
            ret += e.cost;
        }
    }
    return ret;
}

int main(void) {
    int n, m;
    while (cin >> n >> m) {
        if (n == 0 && m == 0) break;
        for (int i = 0; i < m; i++) {
            int a, b, cost;
            cin >> a >> b >> cost;
            edge e;
            e.u = a; e.v = b; e.cost = cost;
            es[i] = e;
        }
        init(n);
        cout << kruskal(m) << endl;
    }
    return 0;
}