#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define inf 0x7fffffff
#define N 100010
#define ll long long
#define lson (p<<1)
#define rson (p<<1|1)
#define mid (l+r>>1)
int n,a[N],uu[N],vv[N],tree[N<<2],addlaz[N<<2],maxlaz[N<<2],ord[N<<1],v[N],cnt,siz[N],top[N],f[N],son[N],dep[N];
struct edge{
int to,w;
};
vector<edge> e[N<<1];
void build(int p,int l,int r){
maxlaz[p]=-1;
if(l==r){
tree[p]=v[l];
return;
}
build(lson,l,mid);
build(rson,mid+1,r);
tree[p]=max(tree[lson],tree[rson]);
}
void pushdown(int p,int l,int r){
if(maxlaz[p]!=-1){
tree[lson]=maxlaz[p];
tree[rson]=maxlaz[p];
maxlaz[lson]=maxlaz[p];
maxlaz[rson]=maxlaz[p];
addlaz[lson]=0;
addlaz[rson]=0;
maxlaz[p]=-1;
}
if(addlaz[p]){
tree[lson]+=addlaz[p];
tree[rson]+=addlaz[p];
addlaz[lson]+=addlaz[p];
addlaz[rson]+=addlaz[p];
addlaz[p]=0;
}
}
void cover(int p,int l,int r,int ql,int qr,int val){
if(l>=ql&&r<=qr){
tree[p]=val;
maxlaz[p]=val;
addlaz[p]=0;
return;
}
pushdown(p,l,r);
if(ql<=mid) cover(lson,l,mid,ql,qr,val);
if(qr>mid) cover(rson,mid+1,r,ql,qr,val);
tree[p]=max(tree[lson],tree[rson]);
}
void add(int p,int l,int r,int ql,int qr,int val){
if(l>=ql&&r<=qr){
tree[p]+=val;
addlaz[p]+=val;
return;
}
pushdown(p,l,r);
if(ql<=mid) add(lson,l,mid,ql,qr,val);
if(qr>mid) add(rson,mid+1,r,ql,qr,val);
tree[p]=max(tree[lson],tree[rson]);
}
int query(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr){
return tree[p];
}
pushdown(p,l,r);
int ans=-inf;
if(ql<=mid) ans=max(ans,query(lson,l,mid,ql,qr));
if(qr>mid) ans=max(ans,query(rson,mid+1,r,ql,qr));
return ans;
}
void coverRange(int x,int y,int val){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
cover(1,1,n,ord[top[x]],ord[x],val);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
cover(1,1,n,ord[x]+1,ord[y],val);
}
void addRange(int x,int y,int val){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
add(1,1,n,ord[top[x]],ord[x],val);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
add(1,1,n,ord[x]+1,ord[y],val);
}
int queryRange(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,query(1,1,n,ord[top[x]],ord[x]));
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=max(ans,query(1,1,n,ord[x]+1,ord[y]));
return ans;
}
void dfs1(int x,int fx){
dep[x]=dep[fx]+1;
siz[x]=1;
f[x]=fx;
for(auto [to,w]:e[x]){
if(to==fx) continue;
a[to]=w;
dfs1(to,x);
siz[x]+=siz[to];
if(siz[to]>siz[son[x]]){
son[x]=to;
}
}
}
void dfs2(int x,int topf){
top[x]=topf;
ord[x]=++cnt;
v[cnt]=a[x];
if(!son[x]) return;
dfs2(son[x],x);
for(auto [to,w]:e[x]){
if(to==f[x]||to==son[x]) continue;
dfs2(to,to);
}
}
void solve(){
cin>>n;
for(int i=1;i<=n-1;i++){
int u,v,w;cin>>u>>v>>w;
uu[i]=u,vv[i]=v;
e[u].push_back({v,w});
e[v].push_back({u,w});
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
string op;
while(cin>>op){
if(op=="Stop") break;
if(op=="Cover"){
int l,r,k;cin>>l>>r>>k;
coverRange(l,r,k);
}else if(op=="Add"){
int u,v,k;cin>>u>>v>>k;
addRange(u,v,k);
}else if(op=="Change"){
int pos,k;cin>>pos>>k;
int u=uu[pos],v=vv[pos];
if(f[u]==v) swap(u,v);
cover(1,1,n,ord[u]+1,ord[u]+1,k);
}else if(op=="Max"){
int l,r;cin>>l>>r;
cout<<queryRange(l,r)<<'\n';
}
}
}
int main(){
IOS;
//freopen("D:\\Code\\in","r",stdin);
//freopen("D:\\Code\\out","w",stdout);
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}