/*
给定一颗2n结点的树,求两个值:
1.给每两个点配对,并且两点之间距离和最小
从叶子结点往上统计,如果子树大小是偶数,那么其到父亲的边权就不用统计,反之要统计
2.给每两个点配对,并且两点之间距离和最大
每条边都被尽可能的访问,一条边将树分成两部分,取小的那部分的size*边权就是这条边的贡献
*/
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define N 300005
#define ll long long
ll n;
struct Edge{ll to,nxt,w;}e[N<<1];
ll head[N],tot;
void add(ll u,ll v,ll w){
e[tot].to=v;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot++;
}
ll size[N],val[N];
void getsize(int u,int fa){
size[u]=1;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
val[v]=e[i].w;
getsize(v,u);
size[u]+=size[v];
}
}
ll ans1,ans2;
void dfs1(int u,int fa){
if(size[u]%2)ans1+=val[u];
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
dfs1(v,u);
}
}
void dfs2(int u,int fa){
ll tmp=min(size[u],n-size[u]);
ans2+=tmp*val[u];
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==fa)continue;
dfs2(v,u);
}
}
void init(){
memset(head,-1,sizeof head);
tot=0;
ans1=ans2=0;
}
int main(){
int t;cin>>t;
while(t--){
init();
scanf("%d",&n);n<<=1;
for(int i=1;i<=n-1;i++){
ll u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
add(u,v,w);add(v,u,w);
}
getsize(1,1);
dfs1(1,1);
dfs2(1,1);
cout<<ans1<<" "<<ans2<<'\n';
}
}