#include<bits/stdc++.h>
long long inf=LLONG_MIN;
using namespace std;
long long n,root=1;
string op;
long long u,v,w;
struct edge {
long long v,idx,w;
};
vector<edge> adj[100010],son[100010];
vector<long long> a;
long long b[100010];
bool vis[100010];
long long des[100010],deep[100010],dss[100010];
long long hld[100010],hfa[100010],hff[100010];
long long pr[100010];
long long k;
bool cmpdes(edge a,edge b) {
return des[a.v]>des[b.v];
}
long long dfs(long long p) {
long long res=1;
for(auto i:adj[p]) {
if(vis[i.v]) {
continue;
}
vis[i.v]=1;
son[p].push_back(i);
b[i.v]=i.w;
pr[i.idx]=i.v;
res+=dfs(i.v);
}
return des[p]=res;
}
void HLD(long long p,long long fa,long long d) {
if(p==root) {
hff[1]=1;
}
hld[p]=++k;
deep[hld[p]]=d;
hfa[k]=hld[fa];
a.push_back(b[p]);
long long res=hld[p];
sort(son[p].begin(),son[p].end(),cmpdes);
for(long long i=0; i<son[p].size(); i++) {
if(i==0) {
HLD(son[p][i].v,fa,d+1);
} else {
hff[k+1]=hld[p];
HLD(son[p][i].v,son[p][i].v,d+1);
}
res=max(res,dss[hld[son[p][i].v]]);
}
dss[hld[p]]=res;
return ;
}
struct Segtree {
long long n;
vector<long long> tree,lazya,lazym;
void init(long long size,vector<long long> &a) {
n=size;
tree.resize(4*n+10);
lazya.resize(4*n+10);
lazym.resize(4*n+10);
for(long long i=0; i<=4*n+10; i++) {
lazym[i]=inf;
lazya[i]=0;
}
build(1,1,n,a);
}
void build(long long p,long long l,long long r,vector<long long> &a) {
if(l==r) {
tree[p]=a[l];
return;
}
long long mid=(l+r)/2;
build(p*2,l,mid,a);
build(p*2+1,mid+1,r,a);
tree[p]=max(tree[p*2],tree[p*2+1]);
}
void pushdowna(long long p) {
if(lazya[p]) {
tree[p*2]+=lazya[p];
tree[p*2+1]+=lazya[p];
lazya[p*2]+=lazya[p];
lazya[p*2+1]+=lazya[p];
lazya[p]=0;
}
}
void pushdownm(long long p) {
if(lazym[p]!=inf) {
tree[p*2]=lazym[p*2]=lazym[p];
tree[p*2+1]=lazym[p*2+1]=lazym[p];
lazym[p]=inf;
lazya[p*2]=lazya[p*2+1]=0;
}
}
void add(long long p,long long l,long long r,long long ql,long long qr,long long val) {
if(ql<=l && r<=qr) {
tree[p]+=val;
lazya[p]+=val;
return;
}
pushdownm(p);
pushdowna(p);
long long mid=(l+r)/2;
if(ql<=mid) {
add(p*2,l,mid,ql,qr,val);
}
if(qr>mid) {
add(p*2+1,mid+1,r,ql,qr,val);
}
tree[p]=max(tree[p*2],tree[p*2+1]);
}
void modify(long long p,long long l,long long r,long long ql,long long qr,long long val) {
if(ql<=l && r<=qr) {
tree[p]=val;
lazym[p]=val;
lazya[p]=0;
return;
}
pushdownm(p);
pushdowna(p);
long long mid=(l+r)/2;
if(ql<=mid) {
modify(p*2,l,mid,ql,qr,val);
}
if(qr>mid) {
modify(p*2+1,mid+1,r,ql,qr,val);
}
tree[p]=max(tree[p*2],tree[p*2+1]);
}
long long query(long long p,long long l,long long r,long long ql,long long qr) {
if(ql<=l && r<=qr) {
return tree[p];
}
pushdownm(p);
pushdowna(p);
long long mid=(l+r)/2;
long long res=inf;
if(mid>=ql) {
res=max(res,query(p*2,l,mid,ql,qr));
}
if(mid+1<=qr) {
res=max(res,query(p*2+1,mid+1,r,ql,qr));
}
return res;
}
} tree;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(long long i=1; i<n; i++) {
cin>>u>>v>>w;
adj[u].push_back({v,i,w});
adj[v].push_back({u,i,w});
}
vis[root]=1;
dfs(root);
HLD(root,root,1);
tree.init(n,a);
while(1) {
cin>>op;
if(op=="Stop") {
break;
}
cin>>u>>v;
if(op=="Change") {
u=hld[pr[u]];
tree.modify(1,1,n,u,u,v);
}
if(op=="Add") {
cin>>w;
if(u==v){
continue;
}
u=hld[u];
v=hld[v];
while(hfa[u]!=hfa[v]) {
if(deep[hfa[u]]<deep[hfa[v]]) {
swap(u,v);
}
tree.add(1,1,n,hfa[u],u,w);
u=hff[hfa[u]];
}
tree.add(1,1,n,min(u,v)+1,max(u,v),w);
}
if(op=="Cover") {
cin>>w;
if(u==v){
continue;
}
u=hld[u];
v=hld[v];
while(hfa[u]!=hfa[v]) {
if(deep[hfa[u]]<deep[hfa[v]]) {
swap(u,v);
}
tree.modify(1,1,n,hfa[u],u,w);
u=hff[hfa[u]];
}
tree.modify(1,1,n,min(u,v)+1,max(u,v),w);
}
if(op=="Max") {
u=hld[u];
v=hld[v];
long long res=LLONG_MIN;
while(hfa[u]!=hfa[v]) {
if(deep[hfa[u]]<deep[hfa[v]]) {
swap(u,v);
}
res=max(res,tree.query(1,1,n,hfa[u],u));
u=hff[hfa[u]];
}
res=max(res,tree.query(1,1,n,min(u,v)+1,max(u,v)));
cout<<res<<'\n';
}
}
return 0;
}