# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring>
# include <vector>
using namespace std;
const int maxn= 150 , maxm= 100005 ;
const int inf = 1e9 ;
int t, n, m, cnt, mst, logg[ maxn] , mx[ maxn] [ 15 ] , pre[ maxn] [ 15 ] , dep[ maxn] , f[ maxn] ;
bool used[ maxm] ;
struct edge {
int u, v, w, fla;
} e[ maxm] ;
struct node {
int u, w;
} ;
vector< node> q[ maxn] ;
bool cmp ( const edge & a, const edge & b)
{
return a. w< b. w;
}
inline void add ( int u, int v, int w)
{
e[ ++ cnt] . v= v;
e[ cnt] . w= w;
e[ cnt] . u= u;
e[ cnt] . fla= 0 ;
}
int find ( int x)
{
return f[ x] == x? x: f[ x] = find ( f[ x] ) ;
}
void kruskal ( )
{
int k = 0 ;
sort ( e+ 1 , e+ 1 + m, cmp) ;
for ( int i= 1 ; i<= m; i++ )
{
int u= e[ i] . u, v= e[ i] . v, w= e[ i] . w;
if ( find ( u) != find ( v) )
{
k++ ;
mst+= w;
f[ find ( u) ] = f[ find ( v) ] ;
used[ i] = 1 ;
q[ u] . push_back ( { v, w} ) ;
q[ v] . push_back ( { u, w} ) ;
if ( k== n- 1 ) return ;
}
}
}
void dfs ( int u, int fa)
{
for ( int i= 1 ; i<= 9 ; i++ )
{
pre[ u] [ i] = pre[ pre[ u] [ i- 1 ] ] [ i- 1 ] ;
mx[ u] [ i] = max ( mx[ u] [ i- 1 ] , mx[ pre[ u] [ i- 1 ] ] [ i- 1 ] ) ;
}
for ( int i= 0 ; i< q[ u] . size ( ) ; i++ )
{
int v= q[ u] [ i] . u, w= q[ u] [ i] . w;
if ( v!= fa)
{
mx[ v] [ 0 ] = w;
pre[ v] [ 0 ] = u;
dep[ v] = dep[ u] + 1 ;
dfs ( v, u) ;
}
}
}
int lcaw ( int x, int y)
{
int maxw = 0 ;
if ( dep[ x] < dep[ y] )
swap ( x, y) ;
while ( dep[ x] != dep[ y] )
{
maxw= max ( maxw, mx[ x] [ logg[ dep[ x] - dep[ y] ] ] ) ;
x= pre[ x] [ logg[ dep[ x] - dep[ y] ] ] ;
}
if ( x== y)
return maxw;
for ( int k= logg[ dep[ x] ] ; k>= 0 ; k-- )
if ( pre[ x] [ k] != pre[ y] [ k] )
{
maxw= max ( maxw, mx[ x] [ k] ) ;
maxw= max ( maxw, mx[ y] [ k] ) ;
x= pre[ x] [ k] , y= pre[ y] [ k] ;
}
return max ( max ( mx[ x] [ 0 ] , mx[ y] [ 0 ] ) , maxw) ;
}
int SMST ( )
{
int smst = inf;
for ( int i= 1 ; i<= m; i++ )
{
int u= e[ i] . u, v= e[ i] . v, w= e[ i] . w;
if ( ! used[ i] )
smst= min ( smst, mst+ w- lcaw ( u, v) ) ;
}
return smst;
}
void init ( )
{
cnt = 0 ;
mst = 0 ;
for ( int i= 1 ; i<= n; i++ )
q[ i] . clear ( ) ;
memset ( used, 0 , sizeof ( used) ) ;
memset ( pre, 0 , sizeof ( pre) ) ;
memset ( mx, 0 , sizeof ( mx) ) ;
memset ( dep, 0 , sizeof ( dep) ) ;
}
int main ( )
{
cin>> t;
for ( int i= 2 ; i<= 105 ; i++ )
logg[ i] = logg[ i- 1 ] + ( ( 1 << ( logg[ i- 1 ] + 1 ) ) == i) ;
while ( t-- )
{
init ( ) ;
scanf ( "%d%d" , & n, & m) ;
for ( int i= 1 ; i<= n; i++ )
f[ i] = i;
for ( int i= 1 , u, v, w; i<= m; i++ )
{
scanf ( "%d%d%d" , & u, & v, & w) ;
add ( u, v, w) ;
}
kruskal ( ) ;
dfs ( 1 , 0 ) ;
SMST ( ) ;
cout<< mst<< ' ' << SMST ( ) << endl;
}
return 0 ;
}