#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<3)+(x<<1)+(c^48);
return x*f;
}
#define mid (l+r>>1)
struct tree{
int top,heavy_son,size,depth,fa,id,v;
}a[100005];
struct segment{
int l,r,v,lazy,c;
bool co;
}tr[400005];
struct PII{
int fir,se;
};
vector<PII>f[100001];
map<int,PII>dot;
int b[100005],tot;
int n;
void dfs1(int x){
a[x].size=1;
a[x].depth=a[a[x].fa].depth+1;
for(int i=0;i<f[x].size();i++){
int y=f[x][i].fir;
if(y!=a[x].fa){
a[y].fa=x;
a[y].v=f[x][i].se;
dfs1(y);
a[x].size+=a[y].size;
if(a[a[x].heavy_son].size<a[y].size){
a[x].heavy_son=y;
}
}
}
return;
}
void dfs2(int x,int t){
a[x].top=t;
a[x].id=++tot;
b[tot]=a[x].v;
if(a[x].heavy_son)dfs2(a[x].heavy_son,t);
for(int i=0;i<f[x].size();i++){
int y=f[x][i].fir;
if(y!=a[x].fa&&y!=a[x].heavy_son){
dfs2(y,y);
}
}
return;
}
void pushup(int root){
tr[root].v=max(tr[root<<1].v,tr[root<<1|1].v);
return;
}
void pushdown(int root){
if(tr[root].co){
tr[root<<1].c=tr[root].c;
tr[root<<1|1].c=tr[root].c;
tr[root<<1].co=1;
tr[root<<1|1].co=1;
tr[root<<1].lazy=0;
tr[root<<1|1].lazy=0;
tr[root<<1].v=tr[root].c;
tr[root<<1|1].v=tr[root].c;
tr[root].co=0;
}
if(tr[root].lazy){
tr[root<<1].v+=tr[root].lazy;
tr[root<<1|1].v+=tr[root].lazy;
tr[root<<1].lazy+=tr[root].lazy;
tr[root<<1|1].lazy+=tr[root].lazy;
tr[root].lazy=0;
}
return;
}
void build(int root,int l,int r){
tr[root].l=l,tr[root].r=r;
if(l==r){
tr[root].v=b[l];
return;
}
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
pushup(root);
return;
}
void cover(int root,int x,int y,int v){
int l=tr[root].l,r=tr[root].r;
if(l>=x&&r<=y){
tr[root].c=tr[root].v=v;
tr[root].co=1;
tr[root].lazy=0;
return;
}
pushdown(root);
if(mid>=x)cover(root<<1,x,y,v);
if(mid<y)cover(root<<1|1,x,y,v);
pushup(root);
return;
}
void add(int root,int x,int y,int v){
int l=tr[root].l,r=tr[root].r;
if(l>=x&&r<=y){
tr[root].lazy+=v;
tr[root].v+=v;
return;
}
pushdown(root);
if(mid>=x)add(root<<1,x,y,v);
if(mid<y)add(root<<1|1,x,y,v);
pushup(root);
return;
}
void change(int root,int x,int v){
int l=tr[root].l,r=tr[root].r;
if(l==r){
tr[root].v=tr[root].c=v;
tr[root].co=1;
tr[root].lazy=0;
return;
}
pushdown(root);
if(mid>=x)change(root<<1,x,v);
else if(mid<x)change(root<<1|1,x,v);
pushup(root);
return;
}
int query(int root,int x,int y){
int l=tr[root].l,r=tr[root].r;
if(l>=x&&r<=y){
return tr[root].v;
}
int ans=0;
pushdown(root);
if(mid>=x)ans=max(query(root<<1,x,y),ans);
if(mid<y)ans=max(ans,query(root<<1|1,x,y));
return ans;
}
int x,y,v;
string opt;
int main(){
freopen("P4315_1.in","r",stdin);
n=read();
for(int i=1;i<n;i++){
x=read(),y=read(),v=read();
f[x].push_back((PII){y,v});
f[y].push_back((PII){x,v});
dot[i]=((PII){x,y});
}
dfs1(1);
dfs2(1,1);
build(1,1,n);
while(cin>>opt){
if(opt=="Stop")break;
x=read(),y=read();
if(opt=="Max"){
int ans=0;
while(a[x].top!=a[y].top){
if(a[x].depth<a[y].depth)swap(x,y);
ans=max(ans,query(1,a[a[x].top].id,a[x].id));
x=a[a[x].top].fa;
}
if(a[x].depth>a[y].depth)swap(x,y);
ans=max(ans,query(1,a[x].id+1,a[y].id));
printf("%d\n",ans);
}else if(opt=="Add"){
v=read();
while(a[x].top!=a[y].top){
if(a[x].depth<a[y].depth)swap(x,y);
add(1,a[a[x].top].id,a[x].id,v);
x=a[a[x].top].fa;
}
if(a[x].depth>a[y].depth)swap(x,y);
add(1,a[x].id+1,a[y].id,v);
}else if(opt=="Cover"){
v=read();
while(a[x].top!=a[y].top){
if(a[x].depth<a[y].depth)swap(x,y);
cover(1,a[a[x].top].id,a[x].id,v);
x=a[a[x].top].fa;
}
if(a[x].depth>a[y].depth)swap(x,y);
cover(1,a[x].id+1,a[y].id,v);
}else{
v=a[dot[x].fir].depth<a[dot[x].se].depth?dot[x].se:dot[x].fir;
cover(1,a[v].id,a[v].id,y);
}
}
return 0;
}