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