#include<bits/stdc++.h>
using namespace std;
const int N = 10010;
struct node{
int l,r,val;
} tri[N * 4];
struct edge{
int u,v,w;
};
int Q,n,m,dep[N],fa[N],top[N],pos[N],sz[N],cnt,son[N],pre[N],w[N];
vector<int> g[N];
vector<edge> e;
void build(int u,int f){
dep[u] = dep[f] + 1;
fa[u] = f;
sz[u] = 1;
for(auto v : g[u]){
if(v == f){
continue;
}
build(v,u);
if(sz[v] > sz[son[u]]){
son[u] = v;
}
sz[u] += sz[v];
}
}
void func(int u,int tot){
top[u] = tot;
pos[u] = ++cnt;
pre[cnt] = u;
if(son[u] != 0){
func(son[u],tot);
}
for(int v : g[u]){
if(v == fa[u] or v == son[u]){
continue;
}
func(v,v);
}
}
void build_tri(int p,int l,int r){
tri[p].l = l;
tri[p].r = r;
if(l == r){
tri[p].val = w[pre[l]];
return;
}
int mid = (l + r) >> 1;
build_tri(p << 1,l,mid);
build_tri(p << 1 | 1,mid + 1,r);
tri[p].val = max(tri[p << 1].val,tri[p << 1 | 1].val);
}
void update(int p,int l,int r,int k){
if(tri[p].l >= l and tri[p].r <= r){
tri[p].val = k * (tri[p].r - tri[p].l + 1);
return;
}
int mid = (tri[p].l + tri[p].r) >> 1;
if(l <= mid){
update(p << 1,l,r,k);
}
if(r > mid){
update(p << 1 | 1,l,r,k);
}
tri[p].val = max(tri[p << 1].val,tri[p << 1 | 1].val);
}
int query(int p,int l,int r){
if(tri[p].l >= l and tri[p].r <= r){
return tri[p].val;
}
int mid = (tri[p].l + tri[p].r) >> 1,res = INT_MIN;
if(l <= mid){
res = max(res,query(p << 1,l,r));
}
if(r > mid){
res = max(res,query(p << 1 | 1,l,r));
}
return res;
}
void update_path(int x,int y,int k){
update(1,pos[x] + 1,pos[y],k);
}
int query_path(int x,int y){
int res = INT_MIN;
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]]){
swap(x,y);
}
res = max(res,query(1,pos[top[x]],pos[x]));
x = fa[top[x]];
}
if(dep[x] > dep[y]){
swap(x,y);
}
if(x == y){
return res;
}
res = max(res,query(1,pos[x] + 1,pos[y]));
return res;
}
void init(){
e.clear();
for(int i = 1;i <= n;i ++){
g[i].clear();
}
cnt = 0;
memset(son,0,sizeof(son));
memset(w,0,sizeof(w));
}
int input(){
int ret = 0,s = 1;
char ch = getchar();
while((ch < '0' or ch > '9') and ch != '-'){
ch = getchar();
}
if(ch == '-'){
s = -1;
ch = getchar();
}
while(ch >= '0' and ch <= '9'){
ret = ret * 10 + ch - '0';
ch = getchar();
}
return ret * s;
}
void pr(int x){
if(x == 0){
return;
}
pr(x / 10);
putchar((char)(x % 10 + '0'));
}
void print(int x){
if(x == 0){
putchar('0');
return;
}
if(x < 0){
putchar('-');
x = -x;
}
pr(x);
}
string read_str(){
string ret;
char ch = getchar();
while(ch == ' ' or ch == '\n'){
ch = getchar();
}
while(ch != ' ' and ch != '\n'){
ret += ch;
ch = getchar();
}
return ret;
}
int main(){
m = input();
while(m --){
init();
n = input();
for(int i = 1;i < n;i ++){
int u,v,w;
u = input(),v = input(),w = input();
e.push_back({u,v,w});
g[u].push_back(v);
g[v].push_back(u);
}
build(1,0);
func(1,1);
for(int i = 0;i < n - 1;i ++){
if(dep[e[i].u] < dep[e[i].v]){
w[pos[e[i].v]] = e[i].w;
}else{
w[pos[e[i].u]] = e[i].w;
}
}
build_tri(1,1,n);
while(true){
string opt;
int x,y;
opt = read_str();
if(opt == "DONE"){
break;
}
x = input(),y = input();
if(opt == "CHANGE"){
update_path(e[x - 1].u,e[x - 1].v,y);
}else{
print(query_path(e[x - 1].u,e[x - 1].v));
putchar('\n');
}
}
}
return 0;
}