1 #include<cstdio>
2 #include<string.h>
3 #include<algorithm>
4 using namespace std;
5 #define inf 0x3f3f3f3f
6 int map[105][105];
7 void prim(int m)
8 {
9 int vis[105], dis[105];
10 int ans = 0;
11 memset(vis, 0, sizeof(vis));//记录该点是否被访问过
12 memset(dis, inf, sizeof(dis));
13 dis[1] = 0;//从第一个点开始至第n个点
14 for(int i = 1; i <= m; i++)
15 {
16 int k = -1, tp = inf;
17 for(int j = 1; j <= m; j++)
18 //寻找权最小的路
19 if(!vis[j] && dis[j] < tp)
20 {
21 k = j;//最小权连通的点(还未标记的)
22 tp = dis[j];//最小的权的大小(记为x)
23 }
24 vis[k] = 1;//标记新的点
25 ans += tp;//加入新的权值
26 //printf("%d\n", ans);
27 for(int j = 1; j <= m; j++)
28 { //寻找新的最小权值 (仅次于x小的权值)
29 if(!vis[j] && map[k][j] < dis[j])
30 dis[j] = map[k][j];
31 }
32 }
33 for(int j = 1; j <= m; j++)
34 if(vis[j] == 0){
35 printf("?\n");
36 return ;
37 }
38 printf("%d\n", ans);
39 }
40 int main()
41 {
42 int n, m, a, b, c;
43 //道路n条 村庄m个
44 while( scanf("%d %d", &n, &m), n)
45 { //初始化地图上的权,设为最大值
46 memset(map, inf, sizeof(map));
47 for(int i = 0; i < n; i++){
48 scanf("%d %d %d", &a, &b, &c);
49 map[a][b] = map[b][a] = c;//无向图
50 }
51 if(n<m-1){
52 printf("?\n");
53 continue;
54 }
55 prim(m);
56 }
57 return 0;
58 }