#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxe = 1e4+50;
struct Edge {
int lst;
int to;
int w;
}edge[maxe * 2];
int head[128];
int qsz;
inline void add(int u, int v, int w) {
edge[qsz].lst = head[u];
edge[qsz].to = v;
edge[qsz].w = w;
head[u] = qsz++;
}
struct Edge1 {
int to;
int st;
int w;
bool operator < (const Edge1 &a) const {
return w < a.w;
}
}edge1[maxe * 2];
int fa[128];
inline int find(int idx) { return fa[idx]==idx ? idx : fa[idx]=find(fa[idx]); }
bool sel[maxe*2];
int pa[128];
int deep[128];
int up[128][9];
int maxi[128][9];
void dfs(int u, int fa) {
// printf("%d %d \n", u, fa);
int i, v;
pa[u] = fa;
up[u][0] = fa;
deep[u] = deep[fa] + 1;
for (i=head[u]; i; i=edge[i].lst) {
v = edge[i].to;
if (v == fa) continue;
maxi[v][0] = edge[i].w;
dfs(v, u);
}
}
void update(int n) {
int i, j;
for (i=1; i<9; ++i) {
for (j=1; j<=n; ++j) {
up[j][i] = up[up[j][i-1]][i-1];
maxi[j][i] = max(maxi[j][i-1], maxi[up[j][i-1]][i-1]);
}
}
}
inline int lca(int u, int v) {
int i;
if (deep[u] < deep[v]) swap(u, v);
for (i=8; i>=0; --i)
if (deep[up[u][i]] >= deep[v]) u = up[u][i];
if (v == u) return u;
for (i=8; i>=0; --i)
if (up[u][i] != up[v][i]) {
u = up[u][i];
v = up[v][i];
}
return up[u][0];
}
inline int qmax(int u, int lc) {
int i, res = 0;
for (i=8; i>=0; --i) {
if (deep[up[u][i]] >= deep[lc]) {
res = max(res, maxi[u][i]);
u = up[u][i];
}
}
return res;
}
int main()
{
// freopen("E:\\input.txt", "r", stdin);
int t, i, j, n, m, u, v, size, tx, ty, seg;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
qsz = 1;
memset(head, 0, sizeof(head));
memset(sel , 0, sizeof(sel ));
memset(maxi, 0, sizeof(maxi));
for (i=1; i<=n; ++i) fa[i] = i;
for (i=1; i<=m; ++i) scanf("%d%d%d", &edge1[i].st, &edge1[i].to, &edge1[i].w);
sort(edge1+1, edge1+m+1);
size = 0;
seg = 0;
for (i=1; i<=m; ++i) {
u = edge1[i].st; v = edge1[i].to;
tx = find(u); ty = find(v);
if (tx == ty) continue;
if (u == tx) size++;
if (v == ty) size++;
fa[tx] = ty;
sel[i] = true;
add(u, v, edge1[i].w); add(v, u, edge1[i].w);
seg += edge1[i].w;
}
deep[0] = 0;
dfs(1, 0);
update(n);
bool flag = true;
int res = 0;
int tmp = seg;
for (i=1; i<=m; ++i) {
if (!sel[i]) {
if (flag) {
tmp = tmp + edge1[i].w;
flag = false;
}
u = edge1[i].st; v = edge1[i].to;
int lc = lca(u, v);
int t1 = max(qmax(u, lc), qmax(v, lc));
tmp = min(tmp, seg-t1+edge1[i].w);
}
}
printf("%d %d\n", seg, tmp);
}
return 0;
}