const int N=2e5+5;
int n,m,t;
int i,j,k;
int fa[N];
struct node
{
int u,v,w;
bool operator<(node b){
if(w!=b.w) return w<b.w;
if(u!=b.u) return u<b.u;
return v<b.v;
}
}G[N];
int Find(int x)
{
if(fa[x]==x) return x;
return fa[x]=Find(fa[x]);
}
int Kruskal()
{
int ans=0;
sort(G+1,G+1+n);
for(i=1;i<=m;i++) fa[i]=i;
int cnt=0;
for(i=1;i<=n;i++){
int x=Find(G[i].u);
int y=Find(G[i].v);
if(x==y) continue;
cnt++;
fa[x]=y;
ans+=G[i].w;
if(cnt==m-1) break;
}
if(cnt==m-1) return ans;
else return inf;
}
int main()
{
//IOS;
while(sdd(n,m)==2){
if(n==0) break;
for(i=1;i<=n;i++){
sdd(G[i].u,G[i].v);
sd(G[i].w);
}
int ans=Kruskal();
if(ans==inf) puts("?");
else pd(ans);
}
return 0;
//PAUSE;
}