#include <bits/stdc++.h>
using namespace std;
int ri() {
  int x;
  if (scanf(" %d", &x) == EOF) return -1;
  return x;
}
long long int rl() {
  long long int x;
  if (cin >> x) return x;
  return -1;
}
string rs() {
  string s;
  if (cin >> s) return s;
  return "";
}
struct Graph {
  int n;
  vector<vector<pair<int, int>>> edges;
  Graph(int n) : n(n) { edges = vector<vector<pair<int, int>>>(n); }
  pair<int, long long int> getMax(int u, int p) {
    int count = 1;
    long long int total = 0;
    for (auto [v, cost] : edges[u])
      if (v != p) {
        pair<int, long long int> cur = getMax(v, u);
        count += cur.first;
        total += cur.second;
        total += min(cur.first, n - cur.first) * (long long int)cost;
      }
    return {count, total};
  }
  long long int getMaxDistance() {
    pair<int, long long int> ret = getMax(0, -1);
    return ret.second;
  }
  pair<int, long long int> getMin(int u, int p) {
    int count = 1;
    long long int sum = 0;
    for (auto& [v, cost] : edges[u])
      if (v != p) {
        pair<int, long long int> cur = getMin(v, u);
        count += cur.first;
        sum += cur.second;
        if (cur.first & 1) sum += cost;
      }
    return {count, sum};
  }
  long long int getLeastDistance() {
    pair<int, long long int> ret = getMin(0, -1);
    return ret.second;
  }
  void readInput() {
    for (int i = 0; i < (n - 1); ++i) {
      int u = ri() - 1;
      int v = ri() - 1;
      int c = ri();
      edges[u].push_back({v, c});
      edges[v].push_back({u, c});
    }
  }
};
struct SingleCase {
  int n;
  bool solveCase() {
    n = ri();
    if (n < 0) return false;
    n *= 2;
    Graph g(n);
    g.readInput();
    long long int lo = g.getLeastDistance();
    long long int hi = g.getMaxDistance();
    cout << lo << " " << hi << endl;
    return true;
  }
};
int main() {
  ri();
  while (SingleCase().solveCase()) {
  };
  return 0;
}
