#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
using namespace std;

#define rep(i,n) for(int (i)=0; (i)<(int)(n); ++(i))
#define foreach(c,i) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)

// uf
namespace uf
{
  const int Size = 1002;
  int par[Size];
  int rank[Size];
  
  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;
    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);
  }
}; /* uf */ 

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

bool comp(const edge& a, const edge& b) {
  return a.cost < b.cost;
}

const int MAX_E = 10002;
edge es[MAX_E];
int V, E;

int kruskal() {
  sort(es, es + E, comp);
  uf::init(V);
  int res = 0;
  for (int i = 0; i < V; ++i) {
    edge e = es[i];
    if (!uf::same(e.u, e.v)) {
      uf::unite(e.u, e.v);
      res += e.cost;
    }
  }
  return res;
}

int solve() {
  int a, b, cost;
  rep (i,E) {
    cin >> a >> b >> cost;
    es[i] = (edge){ a, b, cost };
  }
  return kruskal();
}

int main() {
  while (cin >> V >> E, V|E) {
    cout << solve() << endl;
  }
  return 0;
}