#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define int long long
#define ls t<<1
#define rs t<<1|1
using namespace std;
const int N=100009;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,T[N*4],laz[N*4],lazcover[N*4];
int tot,head[N],gz[N],ngz[N];
int cnt,id[N],siz[N],son[N],dep[N],st[N],f[N];
char s[10];
struct node{int to,nxt,w,zx;}a[N*2];
void dfs1(int t,int fa){
dep[t]=dep[fa]+1;f[t]=fa;siz[t]=1;
for(int i=head[t];i;i=a[i].nxt){
int v=a[i].to;
if(v==fa) continue;
gz[v]=a[i].w;a[i].zx=v;
dfs1(v,t);
siz[t]+=siz[v];
if(siz[v]>siz[son[t]]) son[t]=v;
}
}
void dfs2(int u,int fa,int tou){
id[u]=++cnt;ngz[cnt]=gz[u];st[u]=tou;
if(son[u]) dfs2(son[u],u,tou);
for(int i=head[u];i;i=a[i].nxt){
int v=a[i].to;
if(v==fa||v==son[u]) continue;
dfs2(v,u,v);
}
}
void pushup(int t){T[t]=max(T[ls],T[rs]);}
void build(int t,int tl,int tr){
if(tl==tr) {T[t]=ngz[tl];return ;}
int mid=(tl+tr)>>1;
build(ls,tl,mid);build(rs,mid+1,tr);
pushup(t);
}
void pushdown(int t,int tl,int tr){
if(!laz[t]&&!lazcover[t]) return ;
if(lazcover[t]){
T[ls]=lazcover[t],T[rs]=lazcover[t];
lazcover[ls]=lazcover[t],lazcover[rs]=lazcover[t];
laz[ls]=laz[rs]=lazcover[t]=0;
}
if(laz[t]){
T[ls]+=laz[t];T[rs]+=laz[t];
laz[ls]+=laz[t];laz[rs]+=laz[t];laz[t]=0;
}
}
void cover(int t,int tl,int tr,int l,int r,int k){
if(l<=tl&&tr<=r){T[t]=k;if(laz[t]) laz[t]=0;lazcover[t]=k;return ;}
pushdown(t,tl,tr);
int mid=(tl+tr)>>1;
if(l<=mid) cover(ls,tl,mid,l,r,k);
if(r>mid) cover(rs,mid+1,tr,l,r,k);
pushup(t);
}
void add(int t,int tl,int tr,int l,int r,int k){
if(l<=tl&&tr<=r){
T[t]+=k;if(lazcover[t]) pushdown(t,tl,tr);laz[t]+=k;return ;}
pushdown(t,tl,tr);
int mid=(tl+tr)>>1;
if(l<=mid) add(ls,tl,mid,l,r,k);
if(r>mid) add(rs,mid+1,tr,l,r,k);
pushup(t);
}
int query(int t,int tl,int tr,int l,int r){
if(l<=tl&&tr<=r){return T[t];}
pushdown(t,tl,tr);
int mid=(tl+tr)>>1,ans=0;
if(l<=mid) ans=query(ls,tl,mid,l,r);
if(r>mid) ans=max(ans,query(rs,mid+1,tr,l,r));
return ans;
}
void change(int t,int tl,int tr,int l,int k){
if(tl==tr&&tl==l){T[t]=k;return ;}
pushdown(t,tl,tr);
int mid=(tl+tr)>>1;
if(l<=mid) change(ls,tl,mid,l,k);
else change(rs,mid+1,tr,l,k);
pushup(t);
}
void addd(int x,int y,int z){
a[++tot].nxt=head[x];head[x]=tot;a[tot].to=y;a[tot].w=z;
}
signed main()
{
n=read();
for(int A,B,C,i=1;i<n;i++){
A=read();B=read();C=read();
addd(A,B,C);addd(B,A,C);
}
dfs1(1,0);
dfs2(1,0,1);build(1,1,n);
while(1){
scanf("%s",s);
if(s[0]=='S') break;
if(s[0]=='C'&&s[1]=='o'){
int u=read(),v=read(),w=read();
while(st[u]!=st[v]){
if(dep[st[u]]<dep[st[v]]) swap(u,v);
cover(1,1,n,id[st[u]],id[u],w);
u=f[st[u]];
}
if(dep[u]<dep[v]) swap(u,v);
if(id[u]!=id[v]) cover(1,1,n,id[v]+1,id[u],w);continue;
}
if(s[0]=='C'){
int k=read(),w=read();
change(1,1,n,a[2*k].zx?a[2*k].zx:a[2*k-1].zx,w);
}
if(s[0]=='A'){
int u=read(),v=read(),w=read();
while(st[u]!=st[v]){
if(dep[st[u]]<dep[st[v]]) swap(u,v);
add(1,1,n,id[st[u]],id[u],w);
u=f[st[u]];
}
if(dep[u]<dep[v]) swap(u,v);
if(id[u]!=id[v]) add(1,1,n,id[v]+1,id[u],w);continue;
}
if(s[0]=='M'){
int u=read(),v=read(),maxn=0;
while(st[u]!=st[v]){
if(dep[st[u]]<dep[st[v]]) swap(u,v);
maxn=max(maxn,query(1,1,n,id[st[u]],id[u]));
u=f[st[u]];
}
if(dep[u]<dep[v]) swap(u,v);
if(id[u]!=id[v]) maxn=max(maxn,query(1,1,n,id[v]+1,id[u]));
printf("%lld\n",maxn);
}
}
return 0;
}