#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int inf = 0x7fffffff;
int st[110], rank[110], N, M, x, y, val, maxN, map[110][110];
struct Edge {
int x, y, val;
}e[10000];
int cmp ( const void *a, const void *b ) {
return (( Edge * )a)->val - ( ( Edge * )b )->val;
}
int find ( int i ) {
return i == st[i] ? i : st[i] = find ( st[i] );
}
void merge ( int x, int y ) {
int a = find ( x ), b = find ( y );
if ( a != b ) {
st[a] = b;
rank[b] += rank[a];
//maxN >?= rank[b];
if ( maxN < rank[b] ) maxN = rank[b];
}
}
int Kruskal () {
int sum = 0;
for ( int i = 0 ; i < N; ++ i ) {
int x = e[i].x, y = e[i].y, val = e[i].val;
if ( find ( x ) != find ( y ) ) {
sum += val;
merge ( x, y );
}
}
return sum;
}
int main()
{
while ( scanf ( "%d%d", &N, &M ) != EOF && N ) {
maxN = 0;
for ( int i = 0; i <= M; ++ i ) {
st[i] = i;
rank[i] = 1;
for ( int j = 0; j <= M ; ++ j ) {
map[i][j] = inf;
}
}
for ( int i = 0; i < N; ++ i ) {
scanf ( "%d%d%d", &x, &y, &val );
//map[x][y] = map[y][x] = val;
e[i].x = x, e[i].y = y, e[i].val = val;
}
qsort ( e, N, sizeof ( e[0] ), cmp ); puts(" --------------------->");
int res = Kruskal ();
if ( maxN < M ) puts ( "?" );
else printf ( "%d\n", res );
}
// system("pause");
return 0;