#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=5e5+5,M=3e4+5;
int t,R[M],L[M],pos[M],a[N],n,MAX[M],add[M],cover[M];
int siz[N],top[N],dep[N],fa[N],son[N],rnk[N],dfn[N];
struct node{
int l,r;
}stick[N];
struct edge{
int v,w;
}; vector<edge> g[N];
inline int read(){
int w = 0;
char ch = getchar();
while(ch<'0'||ch>'9') ch = getchar();
while('0'<=ch&&ch<='9'){
w = w*10+(ch-'0');
ch = getchar();
}
return w;
}
void write(int x){
if(x<0) putchar('\n'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
void solve1(int p,int l,int r,int k){
MAX[p]=0;
if(cover[p]){
for(int i=L[p];i<=R[p];i++) a[i]=cover[p];
cover[p]=0,add[p]=0;
for(int i=l;i<=r;i++) a[i]=k;
for(int i=L[p];i<=R[p];i++) MAX[p]=max(MAX[p],a[i]);
}
else{
for(int i=L[p];i<=R[p];i++) a[i]+=add[p];
cover[p]=add[p]=0;
for(int i=l;i<=r;i++) a[i]=k;
for(int i=L[p];i<=R[p];i++) MAX[p]=max(MAX[p],a[i]);
}
}
void Cover_change(int l,int r,int k){
int p=pos[l],q=pos[r];
if(p==q) solve1(p,l,r,k);
else {
solve1(p,l,R[p],k);
solve1(q,L[q],r,k);
for(int i=p+1;i<=q-1;i++){
add[i]=0;
MAX[i]=k;
cover[i]=k;
}
}
}
void solve2(int p,int l,int r,int k){
MAX[p]=0;
if(cover[p]){
for(int i=L[p];i<=R[p];i++) a[i]=cover[p];
cover[p]=0,add[p]=0;
for(int i=l;i<=r;i++) a[i]+=k;
for(int i=L[p];i<=R[p];i++) MAX[p]=max(MAX[p],a[i]);
}
else{
for(int i=L[p];i<=R[p];i++) a[i]+=add[p];
cover[p]=add[p]=0;
for(int i=l;i<=r;i++) a[i]+=k;
for(int i=L[p];i<=R[p];i++) MAX[p]=max(MAX[p],a[i]);
}
}
void Add_change(int l,int r,int k){
int p=pos[l],q=pos[r];
if(p==q) solve2(p,l,r,k);
else{
solve2(p,l,R[p],k);
solve2(q,L[q],r,k);
for(int i=p+1;i<=q-1;i++){
if(cover[i] ){
cover[i]+=k;
//add[i]=0;
}
else add[i]+=k;
MAX[i]+=k;
}
}
}
int solve3(int p,int l,int r){
int maxn=0;
if(cover[p]){
for(int i=L[p];i<=R[p];i++) a[i]=cover[p];
add[p]=0,cover[p]=0;
}
else{
for(int i=L[p];i<=R[p];i++) a[i]+=add[p];
add[p]=0,cover[p]=0;
}
for(int i=l;i<=r;i++) maxn=max(maxn,a[i]);
return maxn;
}
int ask(int l,int r){
int p=pos[l],q=pos[r];
if(p==q) return solve3(p,l,r);
else{
int max1=solve3(p,l,R[p]);
int max2=solve3(q,L[q],r);
int max3=0;
for(int i=p+1;i<=q-1;i++) max3=max(max3,MAX[i]);
return max(max1,max(max2,max3));
}
}
void dfs1(int x,int fat){
son[x]=-1;
siz[x]=1;
for(int i=0;i<g[x].size();i++){
if(g[x][i].v!=fat){
a[g[x][i].v]=g[x][i].w;
fa[g[x][i].v]=x;
dep[g[x][i].v]=dep[x]+1;
dfs1(g[x][i].v,x);
siz[x]+=siz[g[x][i].v];
if(son[x]==-1||siz[son[x]]<siz[g[x][i].v]) son[x]=g[x][i].v; //重儿子
}
}
}
int idx=0;
void dfs2(int x,int t){
dfn[x]=++idx;
rnk[idx]=x;
top[x]=t;
if(son[x]==-1) return ;
dfs2(son[x],t);
for(int i=0;i<g[x].size();i++){
int y=g[x][i].v;
if(y!=son[x] && y!=fa[x]){
dfs2(y,y);
}
}
return;
}
void mRange_add(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Add_change(dfn[top[x]],dfn[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
Add_change(dfn[x],dfn[y],k);
return ;
}
void mRange_cover(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Cover_change(dfn[top[x]],dfn[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
Cover_change(dfn[x],dfn[y],k);
return ;
}
int qRange(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,ask(dfn[top[x]],dfn[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=max(ans,ask(dfn[x],dfn[y]));
return ans;
}
signed main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
memset(add,0,sizeof(add));
memset(cover,0,sizeof(cover));
memset(MAX,0,sizeof(MAX));
cin>>n;
for(int i=1;i<n;i++){
int x,y,z;
x=read(),y=read(),z=read();
g[x].push_back({y,z});
g[y].push_back({x,z});
stick[i].l=x,stick[i].r=y;
}
dep[1]=1;
dfs1(1,1);
dfs2(1,1);
int t=sqrt(n);
for(int i=1;i<=t;i++){
L[i]=(i-1) *sqrt(n)+1;
R[i]=sqrt(n)*i;
}
if(R[t]<n){
t++;
L[t]=R[t-1]+1;
R[t]=n;
}
for(int i=1;i<=t;i++){
for(int j=L[i];j<=R[i];j++){
pos[j]=i;
MAX[i]=max(MAX[i],a[rnk[j]]);
}
}
while(1){
string op;
int u,v,w,k;
cin>>op;
if(op=="Change"){
k=read(),w=read();
mRange_cover(stick[k].l,stick[k].r,w);
}
if(op=="Cover"){
u=read(),v=read(),w=read();
mRange_cover(u,v,w);
}
if(op=="Add"){
u=read(),v=read(),w=read();
mRange_add(u,v,w);
}
if(op=="Max"){
u=read(),v=read();
cout<<qRange(u,v)<<endl;
}
if(op=="Stop") break;
}
}