#include <bits/stdc++.h>
using namespace std;
const int MAXN=10005;
struct Edge
{
int to, next;
}edge[MAXN<<1];
int head[MAXN], tot;
int top[MAXN]; //子重链起点
int fa[MAXN]; //父节点
int deep[MAXN]; //深度
int num[MAXN]; //以节点x为根节点的子树包含的节点数量,包括x本身
int p[MAXN]; //重新建链之后节点的新的编号,也是加入到线段树中的位置
int fp[MAXN]; //根据编号得到实际的点编号
int son[MAXN]; //重链所在的节点
int pos;
void init()
{
tot=0;
memset(head, -1, sizeof(head));
pos=0;
memset(son, -1, sizeof(son));
}
void addedge(int u, int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs1(int u, int pre, int d) //得到dep, fa, num, son数组,为建链预处理
{
deep[u]=d;
fa[u]=pre;
num[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v!=pre)
{
dfs1(v, u, d+1);
num[u]+=num[v];
if(son[u]==-1 || num[v]>num[son[u]])
son[u]=v;
}
}
}
void getpos(int u, int sp) //sp->ancestor
{
top[u]=sp;
p[u]=pos++;
fp[p[u]]=u;
if(son[u]==-1)
return ;
getpos(son[u], sp); //以根节点为起点,沿重边向下拓展,拉成重链。
for(int i=head[u];i!=-1;i=edge[i].next) //不在当前重链上的节点,都以该节点为起点向下重新拉一条重链。
{
int v=edge[i].to;
if(v!=son[u] && v!=fa[u])
getpos(v, v);
}
}
struct node
{
int l, r;
int Max;
}seg[MAXN*3];
void build(int i, int l, int r)
{
seg[i].l=l;
seg[i].r=r;
seg[i].Max=0;
if(l==r)
return ;
int mid=(l+r)>>1;
build(i<<1, l, mid);
build((i<<1)|1, mid+1, r);
}
void pushup(int i)
{
seg[i].Max=max(seg[i<<1].Max, seg[(i<<1)|1].Max);
}
void update(int i, int k, int val)
{
if(seg[i].l==k && seg[i].r==k)
{
seg[i].Max=val;
return ;
}
int mid=(seg[i].l+seg[i].r)>>1;
if(k<=mid)
update(i<<1, k, val);
else
update(i<<1|1, k, val);
pushup(i);
}
int query(int i, int l, int r)
{
if(seg[i].l==l && seg[i].r==r)
return seg[i].Max;
int mid=(seg[i].l+seg[i].r)>>1;
if(r<=mid)
return query(i<<1, l, r);
else if(l>mid)
return query((i<<1)|1, l, r);
else
return max(query(i<<1, l, mid), query((i<<1)|1, mid+1, r));
}
/*
记f1 = top[u],f2 = top[v]。
当f1 <> f2时:不妨设dep[f1] >= dep[f2],那么就更新u到f1的父边的权值(logn),并使u = fa[f1]。
当f1 = f2时:u与v在同一条重链上,若u与v不是同一点,就更新u到v路径上的边的权值(logn),否则修改完成;
重复上述过程,直到修改完成。
*/
int find(int u, int v)
{
int f1=top[u], f2=top[v];
int tmp=0;
while(f1!=f2)
{
if(deep[f1]<deep[f2])
{
swap(f1, f2);
swap(u, v);
}
tmp=max(tmp, query(1, p[f1], p[u]));
u=fa[f1];
f1=top[u];
}
if(u==v)
return tmp;
if(deep[u]>deep[v])
swap(u, v);
return max(tmp, query(1, p[son[u]], p[v]));
}
int e[MAXN][3];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
init();
int n;
scanf("%d", &n);
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d", &e[i][0], &e[i][1], &e[i][2]);
addedge(e[i][0], e[i][1]);
addedge(e[i][1], e[i][0]);
}
dfs1(1, 0, 0);
getpos(1,1);
build(1, 0, pos-1);
for(int i=0;i<n-1;i++)
{
if(deep[e[i][0]]>deep[e[i][1]])
swap(e[i][0], e[i][1]);
update(1, p[e[i][1]], e[i][2]);
}
char op[10];
while(~scanf("%s", op))
{
if(op[0]=='D')
break;
int u, v;
scanf("%d%d", &u, &v);
if(op[0]=='Q')
printf("%d\n", find(u, v));
else
update(1, p[e[u-1][1]], v);
}
}
return 0;
}
//SPOJ 375