#include<cstdio>
#include<cstring>
#define INF 0x7fffffff
using namespace std;
const int N=2e5+;
inline int min(int a,int b){
return (a<b?a:b);
}
int first[N],next[N*],to[N*],c[N*],n;
int edge_count=;
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][];
long long ans=;
//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][]=INF;
return;
}
for(int i=first[root];i;i=next[i]){
if(to[i]==fa)continue;
search(to[i],root);
f[root][]+=min(f[ to[i] ][],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][]=min(c[i],f[fa][]+f[fa][]-min(c[i],f[root][]));
}
}
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][]!=(INF>>) )t+=f[root][];
if(f[root][]!=INF)t+=f[root][];
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=;k<=aa;k++){
memset(first,,sizeof(first));
memset(next,,sizeof(next));
memset(to,,sizeof(to));
memset(c,,sizeof(c));
memset(f,,sizeof(f));
ans=0ll;
edge_count=;
scanf("%d",&n);
for(int i=,a,b,w;i<n;++i){
scanf("%d%d%d",&a,&b,&w);
add(a,b,w);
add(b,a,w);
}
search(,);
if(!next[ first[] ])f[][]=INF>>;
dfs(,);
printf("%lld\n",ans);
}
return ;
}