#include <iostream>
#include<algorithm>
using namespace std;

const int maxnum=101;
int points[maxnum];
int height[maxnum];
struct path{
    int from;
    int to;
    int weight;
} paths[maxnum*(maxnum-1)/2];

bool compare(path p1,path p2){
    return p1.weight<p2.weight;
}

void init(int m){
    for(int i=0;i<m+1;++i){
        points[i]=i;
        height[i]=0;
    }
}

int find(int x){
    if(x!=points[x]){
        points[x]=find(points[x]);
    }
    return points[x];
}

void Union(int x,int y){
    x=find(x);
    y=find(y);
    if(x==y) return;
    if(height[x]>height[y]) points[y]=x;
    else if(height[y]>height[x]) points[x]=y;
    else{
        points[x]=y;
        height[y]++;
    }
}

int kruskal(int n,int m){
    init(m);
    sort(paths,paths+n,compare);
    int weight=0;
    int x=0;
    for(int i=0;i<n;++i){
        path cur=paths[i];
        if(find(cur.to)==find(cur.from)) continue;
        else{
            x++;
            Union(cur.to, cur.from);
            weight+=cur.weight;
        }
    }
    if(x==m-1)
    return weight;
    return -1;
}

int main() {
    int n,m;
    while(cin>>n>>m){
        if(n==0) break;
        for(int i=0;i<n;++i){
            cin>>paths[i].from>>paths[i].to>>paths[i].weight;
        }
        int res=kruskal(n,m);
        if(res!=-1)
        cout<<res<<endl;
        else cout<<"?"<<endl;
    }
}