#include <bits/stdc++.h>
using namespace std;
using namespace std;
class My_tree {
 private:
  int n;
  vector<int> ch, vst;
  vector<pair<pair<int, int>, int>> edge;
  vector<vector<pair<int, int>>> graph;

 public:
  My_tree(int n) {
    this->n = n;
    ch.resize(n + 5, 0);
    vst.resize(n + 5, 0);
    graph.resize(n + 5);
    edge.resize(n + 5);
  }
  void read() {
    for (int i = 1; i < n; i++) {
      int a, b, c;
      cin >> a >> b >> c;
      graph[a].push_back({b, c});
      graph[b].push_back({a, c});
      edge[i] = {{a, b}, c};
    }
  }
  int dfs(int x) {
    vst[x] = 1;
    int res = 1;
    for (pair<int, int> nxt : graph[x]) {
      if (vst[nxt.first]) continue;
      res += dfs(nxt.first);
    }
    return ch[x] = res;
  }
  long long max_tot() {
    long long res = 0;
    for (int i = 1; i < n; i++) {
      int p = edge[i].first.first;
      int c = edge[i].first.second;
      if (ch[c] > ch[p]) swap(c, p);
      long long xx = (long long)min(ch[c], n - ch[c]);
      res += xx * (long long)edge[i].second;
    }
    return res;
  }
  long long min_tot() {
    long long res = 0;
    for (int i = 1; i < n; i++) {
      int p = edge[i].first.first;
      int c = edge[i].first.second;
      if (ch[c] > ch[p]) swap(c, p);
      long long xx = ((ch[c]) % 2 == 1 ? 1 : 0);
      res += xx * (long long)edge[i].second;
    }
    return res;
  }
};
int main(void) {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int t;
  cin >> t;
  while (t--) {
    int n;
    cin >> n;
    n = 2 * n;
    My_tree mt = My_tree(n);
    mt.read();
    mt.dfs(1);
    cout << mt.min_tot() << " " << mt.max_tot() << '\n';
  }
  return 0;
}
