#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n;
struct edge{
int x,y,c,pre;
}a[2*N];
int last[N],alen;
void ins(int x,int y,int c){
a[++alen]=edge{x,y,c,last[x]};
last[x]=alen;
}
struct tnode{
int fa,dep,val,son,siz,top,dfn;
}t[N];
void dfs1(int x,int fa,int val){
t[x]=tnode{fa,t[fa].dep+1,val,0,1,0,0};
for(int k=last[x];k;k=a[k].pre){
int y=a[k].y;
if(y==fa)continue;
dfs1(y,x,a[k].c);
t[x].siz+=t[y].siz;
if(t[t[x].son].siz<t[y].siz){
t[x].son=y;
}
}
}
int dfn,pos[N];
void dfs2(int x,int top){
t[x].top=top;
t[x].dfn=++dfn;
pos[dfn]=x;
if(t[x].son)dfs2(t[x].son,top);
for(int k=last[x];k;k=a[k].pre){
int y=a[k].y;
if(y==t[x].fa||y==t[x].son)
continue;
dfs2(y,y);
}
}
struct trnode{
int l,r,lc,rc;
int mx,nmx,lazy,add;
}tr[2*N];
trnode I={0,0,0,0,0,0,0,0};
int trlen;
void pushup(trnode &now,trnode lc,trnode rc){
int lmx=lc.mx,rmx=rc.mx;
int lnmx=lc.nmx,rnmx=rc.nmx;
if(lmx<rmx)swap(lmx,rmx);
now.mx=lmx;
now.nmx=max({rmx,lnmx,rnmx});
}
void modify(int now,int c){
tr[now].mx=c;
tr[now].lazy=c;
}
void update(int now,int c){
tr[now].mx+=c;
tr[now].lazy+=c;
tr[now].add+=c;
}
void pushdown(int now,int lc,int rc){
if(tr[now].lazy){
modify(lc,tr[now].lazy);
modify(rc,tr[now].lazy);
tr[now].lazy=0;
tr[now].add=0;
}
if(tr[now].add){
update(lc,tr[now].add);
update(rc,tr[now].add);
tr[now].add=0;
}
}
void build(int nl,int nr){
trlen++;int now=trlen;
tr[now]=trnode{nl,nr,-1,-1,0,0,0,0};
if(nl==nr)tr[now].mx=t[pos[nl]].val;
else{
int mid=(nl+nr)>>1;
tr[now].lc=trlen+1;build(nl,mid);
tr[now].rc=trlen+1;build(mid+1,nr);
pushup(tr[now],tr[tr[now].lc],tr[tr[now].rc]);
}
}
void change(int now,int nl,int nr,int x,int c){
if(nl==nr){
tr[now].mx=c;
tr[now].lazy=0;
tr[now].add=0;
return;
}
int mid=(nl+nr)>>1;
int lc=tr[now].lc,rc=tr[now].rc;
pushdown(now,lc,rc);
if(x<=mid)change(lc,nl,mid,x,c);
else change(rc,mid+1,nr,x,c);
pushup(tr[now],tr[lc],tr[rc]);
}
void cover(int now,int nl,int nr,int l,int r,int c){
if(l<=nl&&nr<=r){
modify(now,c);
tr[now].add=0;
return;
}
int mid=(nl+nr)>>1;
int lc=tr[now].lc,rc=tr[now].rc;
pushdown(now,lc,rc);
if(l<=mid)cover(lc,nl,mid,l,r,c);
if(mid<r)cover(rc,mid+1,nr,l,r,c);
pushup(tr[now],tr[lc],tr[rc]);
}
void add(int now,int nl,int nr,int l,int r,int c){
if(l<=nl&&nr<=r){
tr[now].mx+=c;
if(tr[now].lazy){
tr[now].lazy+=c;
}
tr[now].add+=c;
return;
}
int mid=(nl+nr)>>1;
int lc=tr[now].lc,rc=tr[now].rc;
pushdown(now,lc,rc);
if(l<=mid)add(lc,nl,mid,l,r,c);
if(mid<r)add(rc,mid+1,nr,l,r,c);
pushup(tr[now],tr[lc],tr[rc]);
}
trnode query(int now,int nl,int nr,int l,int r){
if(l<=nl&&nr<=r){
return tr[now];
}
int mid=(nl+nr)>>1;
int lc=tr[now].lc,rc=tr[now].rc;
pushdown(now,lc,rc);
trnode res=I,ls=I,rs=I;
if(l<=mid)ls=query(lc,nl,mid,l,r);
if(mid<r)rs=query(rc,mid+1,nr,l,r);
pushup(res,ls,rs);
return res;
}
int calc(int now,int nl,int nr,int x){
if(nl==nr)return tr[now].mx;
int mid=(nl+nr)>>1;
int lc=tr[now].lc,rc=tr[now].rc;
pushdown(now,lc,rc);
if(x<=mid)return calc(lc,nl,mid,x);
else return calc(rc,mid+1,nr,x);
}
void Cover(int x,int y,int c){
while(t[x].top!=t[y].top){
if(t[t[x].top].dep<t[t[y].top].dep)
swap(x,y);
cover(1,1,n,t[t[x].top].dfn,t[x].dfn,c);
x=t[t[x].top].fa;
}
if(t[x].dep>t[y].dep)swap(x,y);
if(x==y)return;
cover(1,1,n,t[x].dfn,t[y].dfn,c);
}
void Add(int x,int y,int c){
while(t[x].top!=t[y].top){
if(t[t[x].top].dep<t[t[y].top].dep)
swap(x,y);
add(1,1,n,t[t[x].top].dfn,t[x].dfn,c);
x=t[t[x].top].fa;
}
if(t[x].dep>t[y].dep)swap(x,y);
if(x==y)return;
add(1,1,n,t[x].dfn,t[y].dfn,c);
}
int LCA(int x,int y){
while(t[x].top!=t[y].top){
if(t[t[x].top].dep<t[t[y].top].dep)
swap(x,y);
x=t[t[x].top].fa;
}
if(t[x].dep<t[y].dep)return x;
return y;
}
int solve(int x,int y){
trnode ans=I;
while(t[x].top!=t[y].top){
if(t[t[x].top].dep<t[t[y].top].dep)
swap(x,y);
pushup(ans,ans,query(1,1,n,t[t[x].top].dfn,t[x].dfn));
x=t[t[x].top].fa;
}
if(t[x].dep>t[y].dep)swap(x,y);
pushup(ans,ans,query(1,1,n,t[x].dfn,t[y].dfn));
int lca=LCA(x,y);
int val=calc(1,1,n,t[lca].dfn);
if(ans.mx==val)return ans.nmx;
else return ans.mx;
}
int main(){
scanf("%d",&n);
alen=1;memset(last,0,sizeof(last));
for(int i=1;i<n;i++){
int x,y,c;scanf("%d%d%d",&x,&y,&c);
ins(x,y,c),ins(y,x,c);
}
dfn=0;
dfs1(1,0,0),dfs2(1,1);
trlen=0;build(1,n);
char op[10];
while(scanf("%s",op+1)!=EOF&&op[1]!='S'){
int x,y,c;
if(op[2]=='h'){
scanf("%d%d",&x,&c);
change(1,1,n,t[a[x*2].y].dfn,c);
}
if(op[2]=='o'){
scanf("%d%d%d",&x,&y,&c);
Cover(x,y,c);
}
if(op[2]=='d'){
scanf("%d%d%d",&x,&y,&c);
Add(x,y,c);
}
if(op[2]=='a'){
scanf("%d%d",&x,&y);
printf("%d\n",solve(x,y));
}
}
return 0;
}