#include<cstdio>
#include<cstring>
#define INF 0x7fffffff
using namespace std;
const int N=2e5+5;
inline int min(int a,int b){
return (a<b?a:b);
}
int first[N],next[N*2],to[N*2],c[N*2],n;
int edge_count=0;
inline void add(int x,int y,int w){
edge_count++;
to[edge_count]=y;
c[edge_count]=w;
next[edge_count]=first[x];
first[x]=edge_count;
}
int f[N][2];
long long ans=0;
//f[i][1]->以i结点为根的子树 向下流动 的最大流量
//f[i][2]->以i节点为根的子树 向上流动 的最大流量
void search(int root,int fa){
if(to[ first[root] ]==fa){
//错因分析:本想判断root结点是否为叶节点,但是存在那样一个结点NODE s.t. first【root】->father
//so, it should be 【 if(to[ first[root] ]==fa && !next[ first[root] ]) 】
f[root][0]=INF;
return;
}
for(int i=first[root];i;i=next[i]){
if(to[i]==fa)continue;
search(to[i],root);
f[root][0]+=min(f[ to[i] ][0],c[i]);
//printf("root:%d",root);printf(" %d\n",f[root][0]);
}
}
void dfs(int root,int fa){
for(int i=first[root];i;i=next[i]){
if(to[i]==fa){
f[root][1]=min(c[i],f[fa][1]+f[fa][0]-min(c[i],f[root][0]));
}
}
for(int i=first[root];i;i=next[i]){
if(to[i]==fa)continue;
dfs(to[i],root);
}
long long t=0ll;
if(f[root][1]!=(INF>>1) )t+=f[root][1];
if(f[root][0]!=INF)t+=f[root][0];
if(ans<t)ans=t;
}
int aa;
int main()
{
//freopen("degree.in","r",stdin);
//freopen("degree.out","w",stdout);
scanf("%d",&aa);
for(int k=1;k<=aa;k++){
memset(first,0,sizeof(first));
memset(next,0,sizeof(next));
memset(to,0,sizeof(to));
memset(c,0,sizeof(c));
memset(f,0,sizeof(f));
ans=0ll;
edge_count=0;
scanf("%d",&n);
for(int i=1,a,b,w;i<n;++i){
scanf("%d%d%d",&a,&b,&w);
add(a,b,w);
add(b,a,w);
}
search(1,0);
if(!next[ first[1] ])f[1][1]=INF>>1;
dfs(1,0);
printf("%lld\n",ans);
}
return 0;
}