import java. io. * ;
import java. util. Arrays ;
public class Solution {
public static void main ( String [ ] args) throws IOException {
in = new StreamTokenizer ( new BufferedReader ( new InputStreamReader ( System . in) ) ) ;
int T = nextInt ( ) ;
for ( int tc = 1 ; tc <= T ; tc++ ) {
readCase ( ) ;
work ( ) ;
System . out. println ( "#" + tc + " " + ans1 + " " + ans2) ;
}
}
static void work ( ) {
for ( int k = 1 ; k <= N ; k++ ) {
for ( int i = 1 ; i <= N ; i++ ) {
for ( int j = 1 ; j <= N ; j++ ) {
dp[ i] [ j] = Math . min ( dp[ i] [ j] , dp[ i] [ k] + dp[ k] [ j] ) ;
}
}
}
ans1 = ans2 = 0 ;
for ( int i = 0 ; i < M ; i++ ) {
if ( dp[ edge[ 0 ] [ i] ] [ edge[ 1 ] [ i] ] < edge[ 2 ] [ i] ) {
ans1++ ;
ans2 += edge[ 2 ] [ i] ;
}
}
}
static void readCase ( ) throws IOException {
N = nextInt ( ) ;
M = nextInt ( ) ;
for ( int i = 1 ; i <= N ; i++ ) {
Arrays . fill ( dp[ i] , 1 , N + 1 , INF) ;
dp[ i] [ i] = 0 ;
}
int a, b, c;
for ( int i = 0 ; i < M ; i++ ) {
edge[ 0 ] [ i] = a = nextInt ( ) ;
edge[ 1 ] [ i] = b = nextInt ( ) ;
edge[ 2 ] [ i] = c = nextInt ( ) ;
if ( dp[ a] [ b] > c) {
dp[ a] [ b] = c;
dp[ b] [ a] = c;
}
}
}
static int nextInt ( ) throws IOException {
in. nextToken ( ) ;
return ( int ) in. nval;
}
static final long INF = Long . MAX_VALUE >> 1 ;
static final long [ ] [ ] dp = new long [ 303 ] [ 303 ] ;
static final int [ ] [ ] edge = new int [ 3 ] [ 40000 ] ;
static StreamTokenizer in;
static int N , M ;
static long ans1, ans2;
}