#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define v e[i].to
#define mid ((ls[x]+rs[x])>>1)
#define x1 x<<1
#define x2 x<<1|1
char *p1,*p2,buf[100000];
#define gc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
inline int read(){
int x=0;int f=1;char c=gc();
for(;c<'0'||c>'9';c=gc())if(c=='-')f=-1;
for(;c>='0'&&c<='9';c=gc())x=(x<<1)+(x<<3)+c-'0';
return x*f;
}
const int N=1e6+5;
int n,q,root=1;
map <pair<int,int>,int> mp,mp2;
struct node{
int to,nex;
}e[N*2];
int h[N],tot=0,cnt=0;
int w[N],wt[N],sum[N*4],tag[N*4],laz[N*4],ma[N*4];
int fa[N],dep[N],hs[N],sz[N],top[N],id[N],ls[N*4],rs[N*4];
int a[N];
inline void add(int x,int y){
e[++tot].to=y;e[tot].nex=h[x];h[x]=tot;
}
inline void pushup(int x){
ma[x]=max(ma[x1],ma[x2]);
}
inline void pushdown(int x){
if(tag[x]!=-1){
tag[x1]=tag[x],tag[x2]=tag[x];
ma[x1]=tag[x];ma[x2]=tag[x];
tag[x]=-1;laz[x]=0;
}
if(laz[x]){
laz[x1]+=laz[x],laz[x2]+=laz[x];
ma[x1]+=laz[x],ma[x2]+=laz[x];
laz[x]=0;
}
}
void build(int l,int r,int x){
tag[x]=-1,laz[x]=0;
ls[x]=l,rs[x]=r;
if(l==r){
ma[x]=wt[l];
return ;
}
build(l,mid,x1);build(mid+1,r,x2);
pushup(x);
}
void update1(int x,int l,int r,ll val){//加
if(l<=ls[x]&&rs[x]<=r){
laz[x]+=val;
ma[x]+=val;
return ;
}
pushdown(x);
if(l<=mid) update1(x1,l,r,val);
if(r>mid) update1(x2,l,r,val);
pushup(x);
}
void update2(int x,int l,int r,ll val){//改
if(l<=ls[x]&&rs[x]<=r){
laz[x]=0;
tag[x]=ma[x]=val;
return ;
}
pushdown(x);
if(l<=mid) update2(x1,l,r,val);
if(r>mid) update2(x2,l,r,val);
pushup(x);
}
int query(int x,int l,int r){
if(l>r) return -1e9;
if(l<=ls[x]&&rs[x]<=r) return ma[x];
int res=-1e9;
pushdown(x);
if(l<=mid) res=max(res,query(x1,l,r));
if(r>mid) res=max(res,query(x2,l,r));
//cout<<'@'<<res<<'\n';
return res;
}
void dfs1(int x,int f){
//cout<<x<<' '<<f<<'\n';
fa[x]=f,sz[x]=1,dep[x]=dep[f]+1,hs[x]=n+1;
for(int i=h[x];i;i=e[i].nex){
if(v==f) continue;
dfs1(v,x);
sz[x]+=sz[v];
if(sz[hs[x]]<sz[v]) hs[x]=v;
}
}
void dfs2(int x,int y){
top[x]=y,id[x]=++cnt;wt[cnt]=mp[{fa[x],x}];a[mp2[{fa[x],x}]]=x;
if(hs[x]==n+1) return ;
dfs2(hs[x],y);
for(int i=h[x];i;i=e[i].nex){
if(v==fa[x]||v==hs[x]) continue;
dfs2(v,v);
}
}
inline void add1(int x,int y,ll val){//路径加
if(x==y) return ;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update1(1,id[top[x]],id[x],val);
x=fa[top[x]];
if(x==y) return ;
}
if(dep[x]>dep[y]) swap(x,y);
update1(1,id[x]+1,id[y],val);
}
inline void add2(int x,int y,ll val){//路径改
if(x==y) return ;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update2(1,id[top[x]],id[x],val);
x=fa[top[x]];
if(x==y) return ;
}
if(dep[x]>dep[y]) swap(x,y);
update2(1,id[x]+1,id[y],val);
}
inline int ask1(int x,int y){
if(x==y) return 0;
int res=-1e9;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res=max(res,query(1,id[top[x]],id[x]));
x=fa[top[x]];
}
//cout<<'#'<<res<<'\n';
if(dep[x]>dep[y]) swap(x,y);
res=max(res,query(1,id[x]+1,id[y]));
//cout<<"$"<<res<<'\n';
return res;
}
inline void pre_work(){
int x,y;
for(int i=1;i<n;i++){
x=read(),y=read();mp[{x,y}]=mp[{y,x}]=read();
mp2[{x,y}]=mp2[{y,x}]=i;
add(x,y);add(y,x);
}
/*for(int i=0;i<n;i++){
for(int j=h[i];j;j=e[j].nex) cout<<e[j].to<<' ';
cout<<"\n";
}*/
dfs1(root,0);dfs2(root,root);build(1,n,1);
//for(int i=1;i<=n*4;i++) cout<<ma[i]<<' ';cout<<'\n';
}
int main(){
//freopen("data.out","r",stdin);
//freopen("1.out","w",stdout);
int x,y,z;
char opt='@';
n=read();
pre_work();
int tmp=0,pop=0;
while(1){
while(opt!='M'&&opt!='A'&&opt!='C'&&opt!='S') opt=gc();
if(opt=='S') break;
if(opt=='M'){
x=read(),y=read();
cout<<ask1(x,y)<<'\n';
}
else if(opt=='A'){
x=read(),y=read(),z=read();
add1(x,y,z);
}
else{
opt=gc();
if(opt=='h'){
x=read(),z=read();
//add2(a[x],fa[a[x]],z);
update2(1,id[a[x]],id[a[x]],z);
}
else{
x=read(),y=read(),z=read();
add2(x,y,z);
}
}
opt='@';
}
return 0;
}