#include<bits/stdc++.h>
#define PII pair<int,int>
#define lson pos<<1
#define rson pos<<1|1
using namespace std;
const int MAXN=2e5+5;
int N,Q;
int dep[MAXN],f[MAXN],son[MAXN],siz[MAXN],tp[MAXN],dfn[MAXN];
int ori[MAXN],val[MAXN];
PII e[MAXN];
int tim=0;
vector<PII>gra[MAXN];
struct SegTree
{
int mn,mx,sum,tag;
}tre[MAXN<<2];
void PushUp(int pos)
{
tre[pos].mn=min(tre[lson].mn,tre[rson].mn);
tre[pos].mx=max(tre[lson].mx,tre[rson].mx);
tre[pos].sum=tre[lson].sum+tre[rson].sum;
}
void Build(int pos,int l,int r)
{
if(l==r)
{
tre[pos]={val[l],val[l],val[l],1};
return;
}
int mid=(l+r)>>1;
Build(lson,l,mid);
Build(rson,mid+1,r);
PushUp(pos);
return;
}
void PushDown(int pos,int l,int r)
{
if(l==r) return;
if(tre[pos].tag==-1)
{
tre[lson].tag=-tre[lson].tag;
tre[lson].sum=-tre[lson].sum;
tre[lson].mx=-tre[lson].mx;
tre[lson].mn=-tre[lson].mn;
swap(tre[lson].mx,tre[lson].mn);
tre[rson].tag=-tre[rson].tag;
tre[rson].sum=-tre[rson].sum;
tre[rson].mx=-tre[rson].mx;
tre[rson].mn=-tre[rson].mn;
swap(tre[rson].mx,tre[rson].mn);
}
tre[pos].tag=1;
return;
}
void Update(int pos,int l,int r,int q,int x)
{
PushDown(pos,l,r);
if(l==r)
{
tre[pos].mn=tre[pos].mx=tre[pos].sum=x;
return;
}
int mid=(l+r)>>1;
if(q<=mid) Update(lson,l,mid,q,x);
else Update(rson,mid+1,r,q,x);
PushUp(pos);
return;
}
void Reverse(int pos,int l,int r,int ql,int qr)
{
PushDown(pos,l,r);
if(ql<=l&&r<=qr)
{
tre[pos].tag=-tre[pos].tag;
tre[pos].sum=-tre[pos].sum;
tre[pos].mx=-tre[pos].mx;
tre[pos].mn=-tre[pos].mn;
swap(tre[pos].mx,tre[pos].mn);
return;
}
int mid=(l+r)>>1;
if(ql<=mid) Reverse(lson,l,mid,ql,qr);
if(mid<qr) Reverse(rson,mid+1,r,ql,qr);
PushUp(pos);
return;
}
int QueryMin(int pos,int l,int r,int ql,int qr)
{
PushDown(pos,l,r);
if(ql<=l&&r<=qr)
{
return tre[pos].mn;
}
int res=2e9;
int mid=(l+r)>>1;
if(ql<=mid) res=min(res,QueryMin(lson,l,mid,ql,qr));
if(mid<qr) res=min(res,QueryMin(rson,mid+1,r,ql,qr));
return res;
}
int QueryPathMin(int u,int v)
{
int res=2e9;
while(tp[u]!=tp[v])
{
if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
res=min(res,QueryMin(1,1,N,dfn[tp[v]],dfn[v]));
v=f[tp[v]];
}
if(dep[u]>dep[v]) swap(u,v);
if(dfn[u]+1<=dfn[v]) res=min(res,QueryMin(1,1,N,dfn[u]+1,dfn[v]));
return res;
}
int QueryMax(int pos,int l,int r,int ql,int qr)
{
PushDown(pos,l,r);
if(ql<=l&&r<=qr)
{
return tre[pos].mx;
}
int res=-2e9;
int mid=(l+r)>>1;
if(ql<=mid) res=max(res,QueryMax(lson,l,mid,ql,qr));
if(mid<qr) res=max(res,QueryMax(rson,mid+1,r,ql,qr));
return res;
}
int QueryPathMax(int u,int v)
{
int res=-2e9;
while(tp[u]!=tp[v])
{
if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
res=max(res,QueryMax(1,1,N,dfn[tp[v]],dfn[v]));
v=f[tp[v]];
}
if(dep[u]>dep[v]) swap(u,v);
if(dfn[u]+1<=dfn[v]) res=max(res,QueryMax(1,1,N,dfn[u]+1,dfn[v]));
return res;
}
int QuerySum(int pos,int l,int r,int ql,int qr)
{
PushDown(pos,l,r);
if(ql<=l&&r<=qr)
{
return tre[pos].sum;
}
int res=0;
int mid=(l+r)>>1;
if(ql<=mid) res+=QuerySum(lson,l,mid,ql,qr);
if(mid<qr) res+=QuerySum(rson,mid+1,r,ql,qr);
return res;
}
int QueryPathSum(int u,int v)
{
int res=0;
while(tp[u]!=tp[v])
{
if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
res+=QuerySum(1,1,N,dfn[tp[v]],dfn[v]);
v=f[tp[v]];
}
if(dep[u]>dep[v]) swap(u,v);
if(dfn[u]+1<=dfn[v]) res+=QuerySum(1,1,N,dfn[u]+1,dfn[v]);
return res;
}
void PathReverse(int u,int v)
{
while(tp[u]!=tp[v])
{
if(dep[tp[u]]>dep[tp[v]]) swap(u,v);
Reverse(1,1,N,dfn[tp[v]],dfn[v]);
v=f[tp[v]];
}
if(dep[u]>dep[v]) swap(u,v);
if(dfn[u]+1<=dfn[v]) Reverse(1,1,N,dfn[u]+1,dfn[v]);
return;
}
void dfs1(int u,int fa)
{
dep[u]=dep[fa]+1;
siz[u]=1;
f[u]=fa;
for(auto [v,w]:gra[u])
{
if(v==fa) continue;
dfs1(v,u);
siz[u]+=siz[v];
ori[v]=w;
if(siz[v]>siz[son[u]]) son[u]=v;
}
return;
}
void dfs2(int u,int rt)
{
tp[u]=rt;
dfn[u]=++tim;
val[tim]=ori[u];
if(son[u]) dfs2(son[u],rt);
for(auto [v,w]:gra[u])
{
if(v!=f[u]&&v!=son[u]) dfs2(v,v);
}
return;
}
int main()
{
scanf("%d",&N);
for(int i=1;i<N;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
u++,v++;
gra[u].push_back({v,w});
gra[v].push_back({u,w});
e[i]={u,v};
}
dfs1(1,0);
dfs2(1,1);
Build(1,1,N);
int ind=0;
scanf("%d",&Q);
while(Q--)
{
char s[10];
scanf("%s",s+1);
int u,v;
scanf("%d %d",&u,&v);
if(s[1]=='C')
{
int x=e[u].first,y=e[u].second;
if(dep[x]>dep[y]) swap(x,y);
Update(1,1,N,dfn[y],v);
}
if(s[1]=='N')
{
u++,v++;
PathReverse(u,v);
}
if(s[1]=='S')
{
u++,v++;
printf("%d\n",QueryPathSum(u,v));
}
if(s[1]=='M'&&s[2]=='A')
{
u++,v++;
printf("%d\n",QueryPathMax(u,v));
}
if(s[1]=='M'&&s[2]=='I')
{
u++,v++;
printf("%d\n",QueryPathMin(u,v));
}
}
return 0;
}