#include <bits/stdc++.h>
using namespace std;
struct node {
  int parent = -1;
  int numOfChilds = 0;
  vector<pair<int, int>> neighs;
};
vector<node> tree;
vector<pair<pair<int, int>, int>> edges;
vector<int> visited;
int dfs(int currNode) {
  if (visited[currNode]) {
    return 0;
  }
  visited[currNode] = true;
  int cant = 0;
  for (auto p : tree[currNode].neighs) {
    if (!visited[p.first]) {
      tree[p.first].parent = currNode;
      cant += dfs(p.first);
    }
  }
  tree[currNode].numOfChilds = cant;
  return cant + 1;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int t;
  cin >> t;
  while (t--) {
    tree.clear();
    edges.clear();
    visited.clear();
    int k;
    cin >> k;
    tree.resize(2 * k + 1);
    visited.resize(2 * k + 1);
    for (int i = 0; i < 2 * k - 1; i++) {
      int a, b, t;
      cin >> a >> b >> t;
      tree[a].neighs.push_back({b, t});
      tree[b].neighs.push_back({a, t});
      edges.push_back({{a, b}, t});
    }
    dfs(1);
    long long int maxim = 0;
    long long int minim = 0;
    for (auto p : edges) {
      int ca = tree[p.first.first].numOfChilds + 1;
      int cb = tree[p.first.second].numOfChilds + 1;
      int pa = tree[p.first.first].parent;
      int push_back = tree[p.first.second].parent;
      if (ca < cb) {
        swap(ca, cb);
        swap(pa, push_back);
      }
      if (pa >= 0) {
        ca = tree[1].numOfChilds + 1;
      }
      ca -= cb;
      maxim += ((long long int)p.second) * ((long long int)min(ca, cb));
      minim += (long long int)(ca % 2) * ((long long int)p.second);
    }
    cout << minim << " " << maxim << '\n';
  }
  return 0;
}
