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