#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <set>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)

const int INF = 1 << 24;
const int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};

typedef unsigned long long ull;

const int MAX_N = 1000000;

class UnionFind{
public:
    UnionFind(int n){
        REP(i, n){
            par[i] = i;
            rank[i] = 0;
        }
    }
    int find(int x){
        if(x == par[x])return x;
        return par[x] = find(par[x]);
    }
    bool same(int x, int y){
        return find(x) == find(y);
    }
    void unite(int x, int y){
        x = find(x);
        y = find(y);
        if(x == y){return;}

        if(rank[x] > rank[y]){
            par[y] = x;
        }else{
            par[x] = y;
            if(rank[x] == rank[y]){rank[y]++;}
        }
    }
private:
    int rank[MAX_N], par[MAX_N];
};

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

bool comp(const Edge& le, const Edge& re){
    return le.cost < re.cost;
}

int N, M;
std::vector<Edge> E;

int kruskal(){
    std::sort(E.begin(), E.end(), comp);

    int res = 0;
    UnionFind uf(N);

    REP(i, M){
        Edge e = E[i];

        if(!uf.same(e.to, e.from)){
            uf.unite(e.to, e.from);
            res += e.cost;
        }
    }

    return res;
}

int main(){
    while(std::cin >> N >> M, N){
        E.clear();
        
        REP(i, M){
            int to, from, cost;
            std::cin >> to >> from >> cost;
            E.push_back({to, from, cost});
        }

        std::cout << kruskal() << std::endl;
    }
}