/*
简单最小生成树问题
*/
#include <cstdio>
#include <cstring>
#include <cstdlib>
const int mMax = 107;
const int nMax = 10007;
int N, M;
int u[nMax], v[nMax], w[nMax], r[nMax];
int p[mMax];
int cmp(const void *a, const void *b)
{
int *pa = (int *)a;
int *pb = (int *)b;
return w[r[*pa]] - w[r[*pb]];
}
int find(int x)
{
return p[x] == x ? x : p[x] = find(p[x]);
}
int main()
{
//freopen("f://data.in", "r", stdin);
while(scanf("%d %d", &N, &M) != EOF)
{
if(!N) break;
int ans = 0;
int i;
for(i = 0; i < N; ++ i)
scanf("%d %d %d", &u[i], &v[i], &w[i]);
for(i = 0; i < N; ++ i) r[i] = i;
for(i = 0; i <= M; ++ i) p[i] = i;
qsort(r, N, sizeof(r[0]), cmp);
for(i = 0; i < N; ++ i)
{
int x = find(u[r[i]]),
y = find(v[r[i]]);
if(x != y)
{
p[x] = y;
ans += w[r[i]];
}
}
//判断图是否全连通
bool ok = 1;
for(i = 2; i <= M; ++ i)
if(find(1) != find(i))
{
ok = 0;
break;
}
if(ok)
printf("%d\n", ans);
else
printf("?\n");
}
return 0;
}