#include<stdio.h>
#include<math.h>
#include<stdlib.h>
struct Point{
int x;
int y;
};
struct Edge{
int from;
int to;
int cost;
};
int father[101];
struct Edge edge[101];
int height[101];
void inital(int n){
for(int i = 1; i <= n; i++){
father[i] = i;
height[i] = 1;
}
}
int cmp(const void*a, const void*b ){
struct Edge* edgea = (struct Edge *) a;
struct Edge* edgeb = (struct Edge *) b;
if(edgea->cost < edgeb->cost) return -1;
else if(edgea->cost > edgeb->cost) return 1;
return 0;
}
int Find(int x) {
if (x != father[x])
father[x] = Find(father[x]);
return father[x];
}
void Union(int x, int y) {
x = Find(x);
y = Find(y);
if (x != y) {
if (height[x] > height[y])
father[y] = x;
else if (height[y] > height[x])
father[x] = y;
else {
father[y] = x;
height[x]++;
}
}
}
int kruskal(struct Edge edge[], int edgenum){
int ans = 0;
qsort(edge, edgenum, sizeof(struct Edge), cmp);
for(int i = 0; i < edgenum; i++){
if(Find(edge[i].from) != Find(edge[i].to)){
Union(edge[i].from, edge[i].to);
ans += edge[i].cost;
}
}
return ans;
}
int main(){
int n, m, a, b, c, res, x, y;
while(scanf("%d %d", &n, &m)!=EOF){
if (n == 0) break;
inital(m);
for(int i = 0; i < n; i++){
scanf("%d %d %d", &edge[i].from, &edge[i].to, &edge[i].cost);
}
res = kruskal(edge, n);
x = father[1];
int tag = 0;
for(int i = 2; i <= m; i++){
y = Find(i);
if (x != y) {
tag = 1;
break;
}
}
if(tag == 0)
printf("%d\n",res);
else
printf("%s\n", "?");
}
return 0;
}