#include<bits/stdc++.h>
typedef long long int ll;
using namespace std;
const int maxn=2e5+10,INF=-1;
int n,root;
int a[maxn],u[maxn],v[maxn],w,kx,ky,kz;
string op;
int cnt,num,fir[maxn];
int deep[maxn],fa[maxn],siz[maxn],son[maxn],wt[maxn],id[maxn],top[maxn];
struct node{
int to,nxt,w;
}e[maxn];
void add_edge(int a,int b,int c){
cnt++;
e[cnt].to=b;
e[cnt].w=c;
e[cnt].nxt=fir[a];
fir[a]=cnt;
}
struct SegmentTree{
int l,r;
int mx,tag1,tag2;
int len(){return r-l+1;}
SegmentTree(){l=r=mx=tag1=0;tag2=INF;}
}t[maxn<<2];
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){t[p].mx=wt[l];return;}
int mid=l+r>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
}
void pushdown(int p){
if(t[p].tag2!=INF){
t[p*2].mx=t[p*2].tag2=t[p].tag2;
t[p*2+1].mx=t[p*2+1].tag2=t[p].tag2;
t[p*2].tag1=t[p*2+1].tag1=0;
t[p].tag2=INF;
}
if(t[p].tag1){
t[p*2].mx+=t[p].tag1;
t[p*2].tag1+=t[p].tag1;
t[p*2+1].mx+=t[p].tag1;
t[p*2+1].tag1+=t[p].tag1;
t[p].tag1=0;
}
}
void change_add(int p,int l,int r,int d){
if(l<=t[p].l&&t[p].r<=r){
pushdown(p);
t[p].mx+=d;
t[p].tag1+=d;
return;
}
pushdown(p);
int mid=t[p].l+t[p].r>>1;
if(l<=mid)change_add(p*2,l,r,d);
if(r>mid)change_add(p*2+1,l,r,d);
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
}
void change_cover(int p,int l,int r,int d){
if(l<=t[p].l&&t[p].r<=r){
t[p].mx=t[p].tag2=d;
t[p].tag1=0;
return;
}
pushdown(p);
int mid=t[p].l+t[p].r>>1;
if(l<=mid)change_cover(p*2,l,r,d);
if(r>mid)change_cover(p*2+1,l,r,d);
t[p].mx=max(t[p*2].mx,t[p*2+1].mx);
}
int query(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r)return t[p].mx;
pushdown(p);
int mid=t[p].l+t[p].r>>1;
int val=0;
if(l<=mid)val=max(val,query(p*2,l,r));
if(r>mid)val=max(val,query(p*2+1,l,r));
return val;
}
void dfs1(int x,int f,int dep){
deep[x]=dep;
fa[x]=f;
siz[x]=1;
int maxson=-1;
for(int i=fir[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==f)continue;
a[y]=e[i].w;
dfs1(y,x,dep+1);
siz[x]+=siz[y];
if(siz[y]>maxson)maxson=siz[y],son[x]=y;
}
}
void dfs2(int x,int topf){
id[x]=++num;
wt[num]=a[x];
top[x]=topf;
if(!son[x])return;
dfs2(son[x],topf);
for(int i=fir[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa[x]||y==son[x])continue;
dfs2(y,y);
}
}
void change_sgt_add(int x,int y,int k){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
change_add(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
if(x!=y)change_add(1,id[x]+1,id[y],k);
else change_add(1,id[x],id[x],k);
}
void change_sgt_cover(int x,int y,int k){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
change_cover(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
if(x!=y)change_cover(1,id[x]+1,id[y],k);
else change_cover(1,id[x],id[x],k);
}
int query_sgt(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
ans=max(ans,query(1,id[top[x]],id[x]));
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
if(x!=y)ans=max(ans,query(1,id[x]+1,id[y]));
return ans;
}
int main(){
cin>>n;
root=1;
for(int i=1;i<n;i++){
cin>>u[i]>>v[i]>>w;
add_edge(u[i],v[i],w);
add_edge(v[i],u[i],w);
}
dfs1(root,0,1);
dfs2(root,root);
build(1,1,n);
while(cin>>op){
if(op=="Stop")return 0;
if(op=="Max"){
cin>>kx>>ky;
cout<<query_sgt(kx,ky)<<"\n";
}
if(op=="Add"){
cin>>kx>>ky>>kz;
change_sgt_add(kx,ky,kz);
}
if(op=="Change"){
cin>>kx>>kz;
if(u[kx]==fa[v[kx]])change_sgt_cover(v[kx],v[kx],kz);
else change_sgt_cover(u[kx],u[kx],kz);
}
if(op=="Cover"){
cin>>kz>>ky>>kz;
change_sgt_cover(kx,ky,kz);
}
}
return 0;
}