#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 ", 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 ", seg, tmp); } return 0; }