#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,tot,cnt,h[100005],len[100005],w[100005],m[100005],top[100005],son[100005],L[100005],DFS[100005],f[100005],U[100005];
struct edge{
int v,nxt,w,id;
}e[200005];
struct ST{
struct node{
int l,r,p,val;
bool f;
}c[400005];
void down(int q){
if((c[q].p||c[q].f)&&c[q].l!=c[q].r){
if(c[q].f){
c[q<<1].f=c[q<<1|1].f=1;
c[q<<1].p=c[q<<1|1].p=c[q].p;
c[q<<1].val=c[q].p;
c[q<<1|1].val=c[q].p;
c[q].p=c[q].f=0;
}
else{
c[q<<1].p+=c[q].p;
c[q<<1].val+=c[q].p;
c[q<<1|1].p+=c[q].p;
c[q<<1|1].val+=c[q].p;
c[q].p=0;
}
}
}
void Build(int q,int l,int r){
c[q].l=l,c[q].r=r;c[q].f=c[q].p=0;
if(l==r){c[q].val=w[DFS[l]];return;}
int mid=l+r>>1;
Build(q<<1,l,mid);
Build(q<<1|1,mid+1,r);
c[q].val=max(c[q<<1].val,c[q<<1|1].val);
}
void Cover(int q,int l,int r,int x){
if(l<=c[q].l&&c[q].r<=r){
c[q].f=1;
c[q].p=x;
c[q].val=x;
return;
}
down(q);
int mid=c[q].l+c[q].r>>1;
if(l<=mid)Cover(q<<1,l,r,x);
if(mid<r)Cover(q<<1|1,l,r,x);
c[q].val=max(c[q<<1].val,c[q<<1|1].val);
}
void Cover(int u,int v,int x){
int fu=top[u],fv=top[v];
while(fu!=fv){
if(len[fu]<len[fv])swap(fu,fv),swap(u,v);
Cover(1,L[fu],L[u],x);
u=f[fu];
fu=top[u];
}
if(len[u]>len[v])swap(u,v);
Cover(1,L[u],L[v],x);
}
void Change(int q,int x,int y){
if(c[q].l==c[q].r){c[q].val=y;return;}
down(q);
int mid=c[q].l+c[q].r>>1;
if(x<=mid)Change(q<<1,x,y);
else Change(q<<1|1,x,y);
c[q].val=max(c[q<<1].val,c[q<<1|1].val);
}
void Add(int q,int l,int r,int x){
if(l<=c[q].l&&c[q].r<=r){
c[q].p+=x;
c[q].val+=x;
return;
}
down(q);
int mid=c[q].l+c[q].r>>1;
if(l<=mid)Add(q<<1,l,r,x);
if(mid<r)Add(q<<1|1,l,r,x);
c[q].val=max(c[q<<1].val,c[q<<1|1].val);
}
void Add(int u,int v,int k){
int fu=top[u],fv=top[v];
while(fu!=fv){
if(len[fu]<len[fv])swap(fu,fv),swap(u,v);
Add(1,L[fu],L[u],k);
u=f[fu];
fu=top[u];
}
if(len[u]>len[v])swap(u,v);
Add(1,L[u],L[v],k);
}
int Getmax(int q,int l,int r){
if(l<=c[q].l&&c[q].r<=r)return c[q].val;
down(q);
int mid=c[q].l+c[q].r>>1,res=0;
if(l<=mid)res=max(res,Getmax(q<<1,l,r));
if(mid<r)res=max(res,Getmax(q<<1|1,l,r));
return res;
}
int Getmax(int u,int v){
int fu=top[u],fv=top[v],res=0;
while(fu!=fv){
if(len[fu]<len[fv])swap(fu,fv),swap(u,v);
res=max(res,Getmax(1,L[fu],L[u]));
u=f[fu];
fu=top[u];
}
if(len[u]>len[v])swap(u,v);
res=max(res,Getmax(1,L[u],L[v]));
return res;
}
}T;
inline void adde(int u,int v,int w,int id){
e[++cnt].nxt=h[u];
h[u]=cnt;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].id=id;
}
void dfs(int x){
m[x]=1;
for(int i=h[x];i;i=e[i].nxt){
if(e[i].v==f[x])continue;
len[e[i].v]=len[x]+1;
f[e[i].v]=x;
w[e[i].v]=e[i].w;
U[e[i].id]=e[i].v;
dfs(e[i].v);
m[x]+=m[e[i].v];
if(m[e[i].v]>m[son[x]])son[x]=e[i].v;
}
}
void dfs1(int x,int tp){
top[x]=tp;
L[x]=++tot;
DFS[tot]=x;
if(son[x])dfs1(son[x],tp);
for(int i=h[x];i;i=e[i].nxt){
if(e[i].v==f[x]||e[i].v==son[x])continue;
dfs1(e[i].v,e[i].v);
}
}
signed main()
{
scanf("%lld",&n);
for(int i=2,x,y,z;i<=n;i++){
scanf("%lld%lld%lld",&x,&y,&z);
adde(x,y,z,i-1);
adde(y,x,z,i-1);
}
dfs(1);
dfs1(1,1);
T.Build(1,1,tot);
string s;
int k,u,v,w;
while(cin>>s){
if(s=="Change"){
scanf("%lld%lld",&k,&w);
T.Change(1,L[U[k]],w);
}
else if(s=="Cover"){
scanf("%lld%lld%lld",&u,&v,&w);
T.Cover(u,v,w);
T.Change(1,1,0);
}
else if(s=="Add"){
scanf("%lld%lld%lld",&u,&v,&w);
T.Add(u,v,w);
T.Change(1,1,0);
}
else if(s=="Max"){
scanf("%lld%lld",&u,&v);
printf("%lld\n",T.Getmax(u,v));
}
else break;
}
return 0;
}