#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct Edge{
int to,value;
};
#define ll long long
#define ls(x) x<<1
#define rs(x) x<<1|1
#define inf 2147483647
int n;
vector<Edge>G[N];
int u,v,w;
int s[N],t[N];
int dep[N],fa[N],son[N],sz[N],dfn[N],a[N],rnk[N],cnt,top[N];
int siz[N<<2],maxx[N<<2];
ll cover[N<<2],lzy[N<<2];
string str;
void dfs1(int u,int father){
fa[u]=father;
sz[u]=1;
dep[u]=dep[father]+1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i].to,w=G[u][i].value;
if(v==father){
continue;
}
a[v]=w;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]]){
son[u]=v;
}
}
}
void dfs2(int u,int tp){
dfn[u]=++cnt,top[u]=tp;
rnk[dfn[u]]=u;
if(!son[u]){
return;
}
dfs2(son[u],tp);
for(int i=0;i<G[u].size();i++){
int v=G[u][i].to;
if(v!=fa[u]&&v!=son[u]){
dfs2(v,v);
}
}
}
void pushup(int u){
maxx[u]=max(maxx[ls(u)],maxx[rs(u)]);
}
void build(int u,int l,int r){
cover[u]=-1;
siz[u]=r-l+1;
if(l==r){
maxx[u]=a[rnk[l]];
return;
}
int mid=l+r>>1;
build(ls(u),l,mid);
build(rs(u),mid+1,r);
pushup(u);
}
void pushdown(int u){
if(cover[u]>=0){
lzy[ls(u)]=lzy[rs(u)]=0;
maxx[ls(u)]=maxx[rs(u)]=cover[ls(u)]=cover[rs(u)]=lzy[u];
cover[u]=-1;
}
if(lzy[u]){
maxx[ls(u)]+=lzy[u];
maxx[rs(u)]+=lzy[u];
lzy[ls(u)]+=lzy[u];
lzy[rs(u)]+=lzy[u];
lzy[u]=0;
}
}
void modify(int u,int l,int r,int L,int R,int p){
if(L<=l&&r<=R){
lzy[u]+=p,maxx[u]+=p;
}
else if(!(R<l||r<L)){
pushdown(u);
int mid=l+r>>1;
modify(ls(u),l,mid,L,R,p);
modify(rs(u),mid+1,r,L,R,p);
pushup(u);
}
}
void add(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
swap(x,y);
}
modify(1,1,n,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if(dfn[x]>dfn[y]){
swap(x,y);
}
modify(1,1,n,dfn[x]+1,dfn[y],z);
}
void fill(int u,int l,int r,int L,int R,int p){
if(L<=l&&r<=R){
maxx[u]=cover[u]=p;
lzy[u]=0;
}
else if(!(R<l||r<L)){
pushdown(u);
int mid=l+r>>1;
fill(ls(u),l,mid,L,R,p);
fill(rs(u),mid+1,r,L,R,p);
pushup(u);
}
}
void cov(int x,int y,int z){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
swap(x,y);
}
fill(1,1,n,dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if(dfn[x]>dfn[y]){
swap(x,y);
}
fill(1,1,n,dfn[x]+1,dfn[y],z);
}
int qry(int u,int l,int r,int L,int R){
if(L<=l&&r<=R){
return maxx[u];
}
else if(!(R<l||r<L)){
pushdown(u);
int mid=l+r>>1;
return max(qry(ls(u),l,mid,L,R),qry(rs(u),mid+1,r,L,R));
}
return -inf;
}
int ask(int x,int y){
int ans=-inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
swap(x,y);
}
ans=max(ans,qry(1,1,n,dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dfn[x]>dfn[y]){
swap(x,y);
}
return max(ans,qry(1,1,n,dfn[x]+1,dfn[y]));
}
int main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n;
for(int i=1;i<n;i++){
cin>>u>>v>>w;
G[u].push_back({v,w});
G[v].push_back({u,w});
s[i]=u,t[i]=v;
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<n;i++){
if(dep[s[i]]<dep[t[i]]){
swap(s[i],t[i]);
}
}
while(1){
cin>>str;
if(str[0]=='S'){
return 0;
}
if(str[0]=='A'){
cin>>u>>v>>w;
add(u,v,w);
}
else if(str[1]=='o'){
cin>>u>>v>>w;
cov(u,v,w);
}
else if(str[1]=='h'){
cin>>u>>w;
fill(1,1,n,dfn[s[u]],dfn[s[u]],w);
}
else{
cin>>u>>v;
cout<<ask(u,v)<<"\n";
}
}
return 0;
}