#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n;
int u[N],v[N],w[N];
int d[N],z[N],s[N],FA[N];
int L[N],R[N],tp[N],deep;
int adtag[16*N],chtag[16*N];
int tree[16*N];
vector<int>edge[N];
void pushdown(int x)
{
if(chtag[x]!=-1)
{
adtag[x]=0;
tree[x]=chtag[x];
chtag[x*2]=chtag[x];
chtag[x*2+1]=chtag[x];
chtag[x]=-1;
return;
}
tree[x]+=adtag[x];
adtag[x*2]+=adtag[x];
adtag[x*2+1]+=adtag[x];
adtag[x]=0;
return;
}
void update(int x)
{
tree[x]=max(tree[x*2],tree[x*2+1]);
return;
}
void change(int l,int r,int l1,int r1,int x,int to)
{
pushdown(x);
pushdown(x*2);
pushdown(x*2+1);
update(x);
if(l1>=l&&r1<=r)
{
chtag[x]=to;
pushdown(x);
return;
}
if((l1+r1)/2>=l)
change(l,r,l1,(l1+r1)/2,x*2,to);
if((l1+r1)/2+1<=r)
change(l,r,(l1+r1)/2+1,r1,x*2+1,to);
update(x);
return;
}
void add(int l,int r,int l1,int r1,int x,int to)
{
pushdown(x);
pushdown(x*2);
pushdown(x*2+1);
update(x);
if(l1>=l&&r1<=r)
{
adtag[x]=to;
pushdown(x);
return;
}
if((l1+r1)/2>=l)
add(l,r,l1,(l1+r1)/2,x*2,to);
if((l1+r1)/2+1<=r)
add(l,r,(l1+r1)/2+1,r1,x*2+1,to);
update(x);
return;
}
int get(int l,int r,int l1,int r1,int x)
{
pushdown(x);
pushdown(x*2);
pushdown(x*2+1);
update(x);
if(l1>=l&&r1<=r)
return tree[x];
int maxs=0;
if((l1+r1)/2>=l)
maxs=max(maxs,get(l,r,l1,(l1+r1)/2,x*2));
if((l1+r1)/2+1<=r)
maxs=max(maxs,get(l,r,(l1+r1)/2+1,r1,x*2+1));
return maxs;
}
void solve1(int x,int y,int to)
{
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]])
swap(x,y);
change(L[tp[x]],L[x],1,n,1,to);
x=FA[tp[x]];
}
if(d[x]<d[y])
swap(x,y);
change(L[y]+1,L[x],1,n,1,to);
return;
}
void solve2(int x,int y,int to)
{
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]])
swap(x,y);
add(L[tp[x]],L[x],1,n,1,to);
x=FA[tp[x]];
}
if(d[x]<d[y])
swap(x,y);
add(L[y]+1,L[x],1,n,1,to);
return;
}
int solve3(int x,int y)
{
int ans=0;
while(tp[x]!=tp[y])
{
if(d[tp[x]]<d[tp[y]])
swap(x,y);
ans=max(ans,get(L[tp[x]],L[x],1,n,1));
x=FA[tp[x]];
}
if(d[x]<d[y])
swap(x,y);
ans=max(ans,get(L[y]+1,L[x],1,n,1));
return ans;
}
void dfs1(int x,int fa)
{
FA[x]=fa;
d[x]=d[fa]+1;
s[x]=1;
int maxs=0;
for(int i=0;i<edge[x].size();i++)
{
int id=edge[x][i];
if(v[id]==x)
swap(u[id],v[id]);
if(v[id]==fa)
continue;
dfs1(v[id],x);
swap(u[id],v[id]);
s[x]+=s[v[id]];
if(s[v[id]]>maxs)
{
maxs=s[v[id]];
z[x]=v[id];
}
}
return;
}
void dfs2(int x,int fa,int old)
{
L[x]=++deep;
tp[x]=old;
if(z[x]!=0)
dfs2(z[x],x,old);
for(int i=0;i<edge[x].size();i++)
{
int id=edge[x][i];
if(v[id]==x)
swap(u[id],v[id]);
if(v[id]==fa)
continue;
if(v[id]==z[x])
{
change(L[z[x]],L[z[x]],1,n,1,w[id]);
continue;
}
dfs2(v[id],x,v[id]);
swap(u[id],v[id]);
change(L[v[id]],L[v[id]],1,n,1,w[id]);
}
R[x]=deep;
return;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n*8;i++)
{
chtag[i]=-1;
}
for(int i=1;i<n;i++)
{
cin>>u[i]>>v[i]>>w[i];
edge[u[i]].push_back(i);
edge[v[i]].push_back(i);
}
dfs1(1,0);
dfs2(1,0,1);
while(1)
{
string op;
cin>>op;
if(op=="Stop")
return 0;
if(op=="Change")
{
int id,to;
cin>>id>>to;
if(d[u[id]]>d[v[id]])
swap(u[id],v[id]);
change(L[v[id]],L[v[id]],1,n,1,to);
}
if(op=="Cover")
{
int u,v,w;
cin>>u>>v>>w;
solve1(u,v,w);
}
if(op=="Add")
{
int u,v,w;
cin>>u>>v>>w;
solve2(u,v,w);
}
if(op=="Max")
{
int u,v;
cin>>u>>v;
cout<<solve3(u,v)<<endl;
}
}
return 0;
}
rt,目前已知问题在线段树