#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
int dep[N],fa[N],son[N],w[N];
int top[N],id[N],sz[N],nw[N],cnt;
struct E{
int l,r;
ll mx;
}tr[N<<2];
vector<pair<int,int>>g[N];
int n,m;
void dfs1(int u,int father){
dep[u]=dep[father]+1;
fa[u]=father,sz[u]=1;
for(auto [v,val]:g[u]){
if(v==father)continue;
w[v]=val;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[son[u]]<sz[v])son[u]=v;
}
}
void dfs2(int u,int t){
top[u]=t,id[u]=++cnt,nw[cnt]=w[u];
if(son[u])dfs2(son[u],t);
for(auto p:g[u]){
int v=p.first;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
#define lc u<<1
#define rc u<<1|1
#define mid ((l+r)>>1)
void pushup(int u){
tr[u].mx=max(tr[lc].mx,tr[rc].mx);
}
void build(int u,int l,int r){
tr[u]={l,r,nw[l]};
if(l==r)return;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(u);
}
void update(int u,int l,int r,int x,int v){
if(l==r){
tr[u].mx=v;
return;
}
if(x<=mid)update(lc,l,mid,x,v);
else update(rc,mid+1,r,x,v);
pushup(u);
}
ll query(int u,int l,int r,int x,int y){
if(r<x||l>y)return 0;
if(x<=l&&r<=y)return tr[u].mx;
ll res=0;
if(x<=mid)res=max(res,query(lc,l,mid,x,y));
if(y>mid)res=max(res,query(rc,mid+1,r,x,y));
return res;
}
ll query_path(int u,int v){
if(u==v)return 0;
ll res=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
res=max(res,query(1,1,n,id[top[u]],id[u]));
u=fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
res=max(res,query(1,1,n,id[v]+1,id[u]));
return res;
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;++i){
int u,v,d;scanf("%d%d%d",&u,&v,&d);
g[u].push_back({v,d});
g[v].push_back({u,d});
}
while(1+1==2){
char op[10];int a,b;
scanf("%s",op);
if(*op=='Q'){
scanf("%d%d",&a,&b);
printf("%lld\n",query_path(a,b));
}else if(*op=='C')update(1,1,n,id[a],b);
else if(*op=='D')break;
}
return 0;
}