#include<bits/stdc++.h>
using namespace std;
int n,ttt,siz[100005],son[100005],fa[100005],top[100005],num[100005],id[100005],father[100005][17],idx,qlog[100005],deep[100005],g[100005],head[100005],tot;
struct node
{
int v,w,nxt;
}edge[200005];
inline void add(int u,int v,int w)
{
edge[++tot]={v,w,head[u]};
head[u]=tot;
}
inline void read(int &a)
{
a=0;register char c;
while((c=getchar())<48);
do a=(a<<3)+(a<<1)+(c^48);
while((c=getchar())>47);
}
inline void write(int x)
{
if(x<=0)return;
write(x/10);
putchar(x%10+'0');
}
inline void read_string(register string &a)
{
a="";register char c;
while((c=getchar())<'A'||c>'Z');
do a+=c;
while((c=getchar())>='A'&&c<='Z');
}
struct tree
{
int sum[500005];
inline void pushup(int num)
{
sum[num]=max(sum[num<<1],sum[num<<1|1]);
}
inline void build(int l,int r,int num)
{
if(l==r)
{
sum[num]=0;
return;
}
int mid=(l+r)>>1;
build(l,mid,num<<1),build(mid+1,r,num<<1|1);
pushup(num);
}
inline void update(int pos,int x,int l,int r,int num)
{
if(l==r&&l==pos)
{
sum[num]=x;
return;
}
int mid=(l+r)>>1;
if(pos<=mid)update(pos,x,l,mid,num<<1);
if(pos>mid)update(pos,x,mid+1,r,num<<1|1);
pushup(num);
}
inline int query(int L,int R,int l,int r,int num)
{
if(L<=l&&r<=R)return sum[num];
int mid=(l+r)>>1;
int res=0;
if(L<=mid)res=max(res,query(L,R,l,mid,num<<1));
if(R>mid)res=max(res,query(L,R,mid+1,r,num<<1|1));
return res;
}
}tr;
inline void dfs(int x,int fat)
{
int maxn=0;
siz[x]=1;
father[x][0]=fat;
deep[x]=deep[fat]+1;
for(int i=1;i<=qlog[deep[x]];i++)father[x][i]=father[father[x][i-1]][i-1];
for(int i=head[x];i;i=edge[i].nxt)
{
if(edge[i].v==fat)continue;
dfs(edge[i].v,x);
siz[x]+=siz[edge[i].v];
if(siz[edge[i].v]>maxn)
{
maxn=siz[edge[i].v];
son[x]=i;
}
}
}
inline int lca(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
while(deep[x]>deep[y])x=father[x][qlog[deep[x]-deep[y]]-1];
if(x==y)return x;
for(int i=qlog[deep[x]]-1;i>=0;i--)
if(father[x][i]!=father[y][i])
{
x=father[x][i];
y=father[y][i];
}
return father[x][0];
}
inline void dfs2(int x,int fat,int topx,int w)
{
id[x]=++idx;
top[idx]=id[topx];
num[idx]=x;
fa[idx]=id[fat];
g[w/2+1]=idx;
tr.update(idx,edge[w].w,1,n,1);
if(son[x])dfs2(edge[son[x]].v,x,topx,son[x]);
for(int i=head[x];i;i=edge[i].nxt)
{
if(edge[i].v==fat||i==son[x])continue;
dfs2(edge[i].v,x,edge[i].v,i);
}
}
inline int query(int x,int y)
{
int f=id[lca(x,y)];
int res=0;
x=id[x];
while(x>0)
{
bool flag=0;
int end=top[x];
if(top[x]<=f&&f<=x)
{
end=f+1;
flag=1;
}
res=max(res,tr.query(end,x,1,n,1));
if(flag)break;
x=fa[top[x]];
}
y=id[y];
while(y>0)
{
bool flag=0;
int end=top[y];
if(top[y]<=f&&f<=y)
{
end=f+1;
flag=1;
}
res=max(res,tr.query(end,y,1,n,1));
if(flag)break;
y=fa[top[y]];
}
return res;
}
signed main()
{
read(ttt);
for(int i=1;i<=100000;i++)qlog[i]=qlog[i-1]+(1<<qlog[i-1]==i);
while(ttt--)
{
idx=0;
read(n);
tr.build(1,n,1);
memset(son,0,sizeof son);
memset(head,0,sizeof head);
tot=0;
for(int i=1;i<n;i++)
{
int u,v,w;
read(u),read(v),read(w);
add(u,v,w);
add(v,u,w);
}
dfs(1,0);
dfs2(1,0,1,0);
string op;
while(1)
{
read_string(op);
if(op=="DONE")break;
if(op=="CHANGE")
{
int x,v;
read(x),read(v);
tr.update(g[x],v,1,n,1);
}
if(op=="QUERY")
{
int x,y;
read(x),read(y);
int res=query(x,y);
if(res==0)putchar('0');
else write(res);
putchar('\n');
}
}
}
}