#include<bits/stdc++.h>
using namespace std;
int n,m,root=1,P;
int a[1000100];
string opt;
int head[1000100],tot,x,y,k;
struct node{
int to,nxt,w;
}e[1001000<<1];
void add1(int x,int y,int k)
{
e[++tot]=(node){y,head[x],k};head[x]=tot;
}
int fa[1000100],dep[1000100],siz[1001000],son[1000100],top[1000100],dfn[1001000],b[1000100];
int cnt;
void dfs1(int p,int f)
{
fa[p]=f;dep[p]=dep[f]+1;
siz[p]=1;
for(int i=head[p];i;i=e[i].nxt)
{
int k=e[i].to;
if(k!=f)
{
a[k]=e[i].w;
dfs1(k,p);
siz[p]+=siz[k];
if(siz[k]>siz[son[p]]) son[p]=k;
}
}
}
void dfs2(int p,int t)
{
top[p]=t;
dfn[p]=++cnt,b[cnt]=a[p];
if(!son[p]) return ;
dfs2(son[p],t);
for(int i=head[p];i;i=e[i].nxt)
{
int k=e[i].to;
if(k!=son[p]&&k!=fa[p]) dfs2(k,k);
}
}
int t[1000100],add[1000100],tag[1000100];
void push_up(int p)
{
t[p]=max(t[p<<1],t[p<<1|1]);
}
void build(int p,int l,int r)
{
tag[p]=-1;
if(l==r){
t[p]=b[l];return ;
}
int mid=l+r>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r);
push_up(p);
}
void make(int p,int k)
{
t[p]+=k,add[p]+=k;
}
void make1(int p,int k)
{
t[p]=k,tag[p]=k,add[p]=0;
}
void push_down(int p)
{
if(tag[p]!=-1)
{
make1(p<<1,tag[p]),make1(p<<1|1,tag[p]);tag[p]=-1;
}
if(!add[p]){
make(p<<1,add[p]),make(p<<1|1,add[p]);add[p]=0;
}
}
void update1(int p,int x,int y,int l,int r,int k)
{
if(x<=l&&r<=y){
make1(p,k);return ;
}
push_down(p);
int mid=l+r>>1;
if(x<=mid) update1(p<<1,x,y,l,mid,k);
if(y>mid) update1(p<<1|1,x,y,mid+1,r,k);
push_up(p);
}
void update2(int p,int x,int y,int l,int r,int k)
{
if(x<=l&&r<=y){
make(p,k);return ;
}
push_down(p);
int mid=l+r>>1;
if(x<=mid) update2(p<<1,x,y,l,mid,k);
if(y>mid) update2(p<<1|1,x,y,mid+1,r,k);
push_up(p);
}
int query(int p,int x,int y,int l,int r)
{
if(x<=l&&r<=y){
return t[p];
}
push_down(p);
int mid=l+r>>1,sum=0;
if(x<=mid) sum=max(sum,query(p<<1,x,y,l,mid));
if(y>mid) sum=max(sum,query(p<<1|1,x,y,mid+1,r));
return sum;
}
void update1_t(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update1(1,dfn[top[x]],dfn[x],1,n,k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update1(1,dfn[x]+1,dfn[y],1,n,k);
}
void update2_t(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update2(1,dfn[top[x]],dfn[x],1,n,k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update2(1,dfn[x]+1,dfn[y],1,n,k);
}
int query_t(int x,int y)
{
int sum=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
sum=max(sum,query(1,dfn[top[x]],dfn[x],1,n));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
sum=max(sum,query(1,dfn[x]+1,dfn[y],1,n));
return sum;
}
int main()
{
cin>>n;
for(int i=1;i<n;i++)
{
cin>>x>>y>>k;
add1(x,y,k),add1(y,x,k);
}
dfs1(root,0),dfs2(root,root);
build(1,1,n);
cin>>opt;
while(opt!="Stop")
{
if(opt=="Change"){
cin>>x>>y;
int k1=e[x*2].to,v=e[x*2-1].to;
k1=dep[k1]<dep[v]?v:k1;
update1(1,dfn[k1],dfn[k1],1,n,y);
}
else if(opt=="Cover")
{
cin>>x>>y>>k;
update1_t(x,y,k);
}
else if(opt=="Add")
{
cin>>x>>y>>k;
update2_t(x,y,k);
}
else if(opt=="Max"){
cin>>x>>y;
cout<<query_t(x,y)<<endl;
}
cin>>opt;
}
return 0;
}