#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; }