rt
#include<bits/stdc++.h>
#define int long long
using namespace std;
struct Edge
{
int v,w,nxt;
};
struct Tree
{
#define lc (p<<1)
#define rc ((p<<1)|1)
int l,r;
int mx;
int add,cov;
int length()
{
return (r-l+1);
}
};
const int N=1000005;
int head[N],cntEdge;
int cntDfs;
int fa[N],ch[N],siz[N];
int dep[N],top[N],dfn[N];
int val[N],var[N],idv[N];
Edge e[N<<1];
Tree t[N<<2];
void addEdge(int u,int v,int w=0)
{
cntEdge++;
e[cntEdge].v=v;
e[cntEdge].w=w;
e[cntEdge].nxt=head[u];
head[u]=cntEdge;
}
void dfs1(int u,int f)
{
fa[u]=f;
siz[u]=1;
dep[u]=dep[f]+1;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
int w=e[i].w;
if(v==f)
continue;
dfs1(v,u);
idv[(i+1)>>1]=v;
var[v]=w;
siz[u]+=siz[v];
if(siz[v]>siz[ch[u]])
ch[u]=v;
}
}
void dfs2(int u,int f)
{
top[u]=f;
dfn[u]=++cntDfs;
val[cntDfs]=var[u];
if(ch[u])
dfs2(ch[u],f);
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].v;
if(v!=fa[u]&&v!=ch[u])
dfs2(v,v);
}
}
void pushUp(int p)
{
t[p].mx=max(t[lc].mx,t[rc].mx);
}
void update(int p,int k)
{
t[p].mx=k;
t[p].cov=k;
t[p].add=0;
}
void pushDown(int p)
{
if(t[p].cov!=-1)
{
update(lc,t[p].cov);
update(rc,t[p].cov);
t[p].cov=-1;
}
t[lc].mx+=t[p].add;
t[lc].add+=t[p].add;
t[rc].mx+=t[p].add;
t[rc].add+=t[p].add;
t[p].add=0;
}
void build(int p,int x,int y)
{
t[p].l=x,t[p].r=y;
t[p].cov=-1;
if(x==y)
{
t[p].mx=val[x];
return;
}
int mid=(x+y)>>1;
build(lc,x,mid);
build(rc,mid+1,y);
pushUp(p);
}
void change(int p,int pos,int k)
{
if(pos<t[p].l||t[p].r<pos)
return;
if(t[p].l==t[p].r)
{
t[p].mx=k;
t[p].cov=-1;
t[p].add=0;
return;
}
pushDown(p);
change(lc,pos,k);
change(rc,pos,k);
pushUp(p);
}
void cover(int p,int x,int y,int k)
{
if(y<t[p].l||t[p].r<x)
return;
if(x<=t[p].l&&t[p].r<=y)
{
update(p,k);
return;
}
pushDown(p);
cover(lc,x,y,k);
cover(rc,x,y,k);
pushUp(p);
}
void increase(int p,int x,int y,int k)
{
if(y<t[p].l||t[p].r<x)
return;
if(x<=t[p].l&&t[p].r<=y)
{
t[p].mx+=k;
t[p].add+=k;
return;
}
pushDown(p);
increase(lc,x,y,k);
increase(rc,x,y,k);
pushUp(p);
}
int getMax(int p,int x,int y)
{
if(y<t[p].l||t[p].r<x)
return LONG_LONG_MIN;
if(x<=t[p].l&&t[p].r<=y)
return t[p].mx;
pushDown(p);
return max(getMax(lc,x,y),getMax(rc,x,y));
}
void increaseRange(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(dep[top[x]<dep[top[y]]])
swap(x,y);
increase(1,dfn[top[x]],dfn[x],k);
x=fa[top[x]];
}
if(dep[x]<dep[y])
swap(x,y);
increase(1,dfn[y]+1,dfn[x],k);
}
void coverRange(int x,int y,int k)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
cover(1,dfn[top[x]],dfn[x],k);
x=fa[top[x]];
}
if(dep[x]<dep[y])
swap(x,y);
cover(1,dfn[y]+1,dfn[x],k);
}
int getRangeMax(int x,int y)
{
int res=LONG_LONG_MIN;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
res=max(res,getMax(1,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dep[x]<dep[y])
swap(x,y);
res=max(res,getMax(1,dfn[y]+1,dfn[x]));
return res;
}
signed main()
{
// freopen("cao.in","r",stdin);
// freopen("madan.out","w",stdout);
int n;
cin>>n;
for(int i=2;i<=n;++i)
{
int iu,iv,iw;
cin>>iu>>iv>>iw;
addEdge(iu,iv,iw);
addEdge(iv,iu,iw);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
string io;
do
{
cin>>io;
if(io=="Change")
{
int ik,iw;
cin>>ik>>iw;
change(1,dfn[idv[(ik+1)>>1]],iw);
}
if(io=="Cover")
{
int iu,iv,iw;
cin>>iu>>iv>>iw;
coverRange(iu,iv,iw);
}
if(io=="Add")
{
int iu,iv,iw;
cin>>iu>>iv>>iw;
increaseRange(iu,iv,iw);
}
if(io=="Max")
{
int iu,iv;
cin>>iu>>iv;
cout<<getRangeMax(iu,iv)<<endl;
}
}while(io!="Stop");
return 0;
}