/* Sub-tree generation problem. Method: find the Minimum Spanning Tree and mark the path F [I] [j] to represent the largest edge in the I-> j in the Minimum Spanning Tree if map (I, j)> F [I] [j]
Replace this edge to enumerate each edge that is not in the smallest spanning tree to find the smallest.
*/
# Include <cstdio>
# Include <cstring>
# Define INF 1 <30
Int map [110] [110], n, m;
Int vis [110], use [110] [110], low [110];
Int pre [110], F [110] [110];
Int max (int x, int y)
{
Return x> y? X: y;
}
Int prim (int s, int t)
{
Int ans = 0;
Memset (pre,-1, sizeof (pre ));
Pre [s] =-1;
Memset (F, 0, sizeof (F ));
For (int I = 1; I <= n; I ++)
{
Vis [I] = 0;
Low [I] = INF;
}
Low [1] = 0;
// Vis [s] = 1;
For (int I = 1; I <= n; I ++)
{
Int temp = INF, tp =-1;
For (int j = 1; j <= n; j ++)
If (! Vis [j] & temp> low [j])
{
Tp = j;
Temp = low [j];
}
If (tp =-1) continue;
Int k = tp;
Int v = pre [k];
If (v! =-1)
{
Use [k] [v] = use [v] [k] = 2;
For (int j = 1; j <= n; j ++)
If (vis [j])
F [j] [k] = max (F [j] [v], map [v] [k]);
}
Vis [k] = 1;
Ans + = low [k];
For (int j = 1; j <= n; j ++)
If (! Vis [j] & low [j]> map [k] [j])
{
Low [j] = map [k] [j];
Pre [j] = k;
}
}
Return ans;
}
Int second_mst (int x)
{
Int res = x, ans = INF;
For (int I = 1; I <= n; I ++)
For (int j = 1; j <= n; j ++)
If (use [I] [j] = 1 & map [I] [j]! = INF & F [I] [j]! = INF)
{
If (res + map [I] [j]-F [I] [j] <ans)
Ans = res + map [I] [j]-F [I] [j];
// Printf ("% d. % d. \ n", F [I] [j], map [I] [j]);
}
Return ans;
}
Int main ()
{
Int t;
Scanf ("% d", & t );
While (t --)
{
Scanf ("% d", & n, & m );
For (int I = 0; I <= n; I ++)
For (int j = 0; j <= n; j ++)
Map [I] [j] = INF;
Memset (use, 0, sizeof (use ));
Int x, y, z;
For (int I = 0; I <m; I ++)
{
Scanf ("% d", & x, & y, & z );
Map [x] [y] = map [y] [x] = z;
Use [x] [y] = use [y] [x] = 1;
}
Int ans = prim (1, n );
Int ans1 = second_mst (ans );
Printf ("% d \ n", ans, ans1 );
}
Return 0;
}