#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 2e4+100;
int son[maxn], deep[maxn], father[maxn], num[maxn], top[maxn], p[maxn], fp[maxn], pos;
int Treevalue[maxn];
int first[maxn], ntot;
struct Node
{
int to, next, val;
} edge[maxn];
struct NODE
{
int a, b, c;
} input[maxn];
void init()
{
memset(first, -1, sizeof(first));
memset(son, -1, sizeof(son));
pos = ntot = 0;
}
void addedge(int s,int t,int val)
{
edge[ntot].to=t,edge[ntot].val=val;
edge[ntot].next=first[s],first[s]=ntot++;
}
///树链剖分
void dfs(int x, int pre, int de)
{
deep[x] = de;
father[x] = pre;
num[x] = 1;
for(int i = first[x]; i != -1; i = edge[i].next)
{
int to = edge[i].to;
if(to != pre)
{
Treevalue[to] = edge[i].val;
dfs(to, x, de + 1);
num[x] += num[to];
if(son[x] == -1 || num[to] > num[son[x]])
son[x] = to;
}
}
return ;
}
void getlist(int x, int tp)
{
top[x] = tp;
p[x] = pos++;
fp[p[x]] = x;
if(son[x] != -1)
getlist(son[x], tp);
else
return ;
for(int i = first[x]; i != -1; i = edge[i].next)
{
int to = edge[i].to;
if(to != father[x] && to != son[x])
getlist(to, to);
}
}
struct TreeNode
{
int l, r, max;
} tree[maxn * 3];
void push_up(int i)
{
tree[i].max = max(tree[i << 1].max, tree[i << 1 | 1].max);
}
void build(int i,int l,int r)
{
tree[i].l=l,tree[i].r=r,tree[i].max=0;
if(l==r)
{
tree[i].max=Treevalue[fp[l]];
return ;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
push_up(i);
}
int Query(int rt, int L, int R)
{
if(tree[rt].l >= L && tree[rt].r <= R)
return tree[rt].max;
int m = (tree[rt].l + tree[rt].r) >> 1;
int ans = 0;
if(L <= m)
ans = max(ans, Query(rt << 1, L, R));
if(m < R)
ans = max(ans, Query(rt << 1 | 1, L, R));
return ans;
}
void update(int i,int k,int val)//插点
{
if(tree[i].l == k && tree[i].r == k)
{
tree[i].max=val;
return ;
}
int mid=(tree[i].l+tree[i].r)>>1;
if(k>mid)
update(i<<1|1,k,val);
else
update(i<<1,k,val);
push_up(i);
}
int getmax(int a, int b)
{
int res = 0;
int f1 = top[a], f2 = top[b];
while(f1 != f2)
{
if(deep[f1] < deep[f2])
{
swap(f1, f2);
swap(a, b);
}
res = max(res, Query(1, p[f1], p[a]));
a = father[f1];
f1 = top[a];
}
if(a == b)
return res;
if(deep[a] > deep[b])
swap(a, b);
return max(res, Query(1, p[son[a]], p[b]));
}
int main()
{
//freopen("in.txt", "r", stdin);
int ncase, n;
cin >> ncase;
while(ncase--)
{
init();
cin >> n;
for(int i = 1; i <= n - 1; i++)
{
scanf("%d%d%d",&input[i].a,&input[i].b,&input[i].c);
addedge(input[i].a,input[i].b,input[i].c);
addedge(input[i].b,input[i].a,input[i].c);
}
dfs(1, 0, 0);
getlist(1,1);
build(1, 1, n -1 );
while(1)
{
char op[10];
scanf("%s", op);
if(op[0] == 'D')
break;
if(op[0] == 'C')
{
int a, b;
scanf("%d%d", &a, &b);
int aa = input[a].a, bb = input[a].b;
if(deep[aa] < deep[bb])
swap(aa, bb);
update(1, p[aa], b);
}
else
{
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", getmax(a, b));
}
}
}
return 0;
}