//============================================================================
// Name : POJ_1511.cpp
// Author : tiger
// Version :
// Copyright : Your copyright notice
// Description : 求两遍单源最短路径之和即可,第二遍要把图反转
// zhangzhenhu 1511 Accepted 36880K 1938MS G++
//============================================================================
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXN = 1000005;
struct NODE
{
int to;
int value;
NODE *next;
void intial()
{
to = 0;
value = 0;
next = 0;
}
};
NODE *mat1[MAXN], *mat2[MAXN];
queue<int> q;
NODE pool[MAXN *2 + 2];
int counts;
long long spfa(int n, int s, NODE *mat[])
{
int i, k;
long long sum;
NODE *p;
int min[MAXN];
bool v[MAXN];
for (i = 0; i < n; i++)
{
min[i] = 1000000000;
v[i] = false;
}
min[s] = 0;
v[s] = true;
q.push(s);
while (!q.empty())
{
k = q.front();
q.pop();
v[k] = false;
p = mat[k];
while (p)
{
if (min[k] + p->value < min[p->to])
{
min[p->to] = min[k] + p->value;
if (!v[p->to])
{
q.push(p->to);
v[p->to] = true;
}
}
p = p->next;
}
}
sum = 0;
for (i = 0; i < n; i++)
sum += min[i];
return sum;
}
int main()
{
freopen("in", "r", stdin);
int t, P, Q;
int i, a, b, c;
long long sum;
NODE *p;
scanf("%d", &t);
while (t--)
{
scanf("%d %d", &P, &Q);
for (i = 0; i < P; i++)
{
mat1[i] = NULL;
mat2[i] = NULL;
}
counts = 0;
for (i = 0; i < Q; i++)
{
scanf("%d %d %d", &a, &b, &c);
a--;
b--;
p = mat1[a];
mat1[a] = pool + counts;
mat1[a]->intial();
mat1[a]->to = b;
mat1[a]->value = c;
mat1[a]->next = p;
p = mat2[b];
mat2[b] = pool + Q + 1 + counts;
mat2[b]->intial();
mat2[b]->to = a;
mat2[b]->value = c;
mat2[b]->next = p;
counts++;
}
sum = spfa(P, 0, mat1) + spfa(P, 0, mat2);
printf("%lld/n", sum);
}
return 0;
}