#include<cstdio>
#include<iostream>
#define int long long
const int maxn=2e5+1;
using namespace std;
struct node{
int to,next,w,from;
}edge[maxn*2];
struct node1{
int l,r,num,sum,maxn,minn,flag2;
}t[maxn*2];
char s[1001];
int u[maxn],v[maxn],w[maxn],va[maxn];
int cntt,fa1[maxn],tot,head[maxn],cnt1,ans,m,n,R,res,wt[maxn];
int mod,id[maxn],size[maxn],depth[maxn],heavyson[maxn],top[maxn];
void addedge(int u,int v,int w)
{
edge[++cnt1].to=v;
edge[cnt1].from=u;
edge[cnt1].next=head[u];
edge[cnt1].w=w;
head[u]=cnt1;
}
void maketree(int tot,int l,int r)
{
t[tot].l=l;
t[tot].r=r;
if(l==r)
{
t[tot].sum=wt[l];
t[tot].maxn=wt[l];
t[tot].minn=wt[l];
return ;
}
int mid=(l+r)>>1;
maketree(tot*2,l,mid);
maketree(tot*2+1,mid+1,r);
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum);
t[tot].maxn=max(t[tot*2].maxn,t[tot*2+1].maxn);
t[tot].minn=min(t[tot*2].minn,t[tot*2+1].minn);
}
void down(int tot,int l,int r) // 标记下移
{
t[tot*2].flag2^=t[tot].flag2;
t[tot*2+1].flag2^=t[tot].flag2;
int mid=(l+r)/2;
t[tot*2].sum=-t[tot*2].sum; int q=t[tot*2].minn;t[tot*2].minn=-t[tot*2].maxn,t[tot*2].maxn=-q;
t[tot*2+1].sum=-t[tot*2+1].sum; q=t[tot*2+1].minn;t[tot*2+1].minn=-t[tot*2+1].maxn,t[tot*2+1].maxn=-q;
t[tot].flag2=0;
}
void ask1(int tot,int l1,int r1,int l,int r)
{
if(l1>=l && r1<=r)
{
ans+=t[tot].sum;
return ;
}
if(t[tot].flag2) down(tot,l1,r1);
int mid=(l1+r1)/2;
if(l<=mid) ask1(tot*2,l1,mid,l,r);
if(r>mid) ask1(tot*2+1,mid+1,r1,l,r);
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum);
t[tot].maxn=max(t[tot*2].maxn,t[tot*2+1].maxn);
t[tot].minn=min(t[tot*2].minn,t[tot*2+1].minn);
}
void ask2(int tot,int l1,int r1,int l,int r)
{
if(l1>=l && r1<=r)
{
ans=max(ans,t[tot].maxn);
return ;
}
if(t[tot].flag2) down(tot,l1,r1);
int mid=(l1+r1)/2;
if(l<=mid) ask2(tot*2,l1,mid,l,r);
if(r>mid) ask2(tot*2+1,mid+1,r1,l,r);
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum);
t[tot].maxn=max(t[tot*2].maxn,t[tot*2+1].maxn);
t[tot].minn=min(t[tot*2].minn,t[tot*2+1].minn);
}
void ask3(int tot,int l1,int r1,int l,int r)
{
if(l1>=l && r1<=r)
{
ans=min(ans,t[tot].minn);
return ;
}
if(t[tot].flag2) down(tot,l1,r1);
int mid=(l1+r1)/2;
if(l<=mid) ask3(tot*2,l1,mid,l,r);
if(r>mid) ask3(tot*2+1,mid+1,r1,l,r);
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum);
t[tot].maxn=max(t[tot*2].maxn,t[tot*2+1].maxn);
t[tot].minn=min(t[tot*2].minn,t[tot*2+1].minn);
}
void change1(int tot,int l,int r,int x,int y,int z) //单点
{
if(l>=x && r<=y)
{
t[tot].sum=z;
t[tot].maxn=t[tot].sum;
t[tot].minn=t[tot].sum;
return ;
}
if(t[tot].flag2) down(tot,l,r);
int mid=(l+r)/2;
if(x<=mid) //在左区间
change1(tot*2,l,mid,x,y,z);
if(y>mid) // 在右区间
change1(tot*2+1,mid+1,r,x,y,z);
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum);
t[tot].maxn=max(t[tot*2].maxn,t[tot*2+1].maxn);
t[tot].minn=max(t[tot*2].minn,t[tot*2+1].minn);
}
void change2(int tot,int l,int r,int x,int y) // 区间取反
{
if(l>=x && r<=y)
{
int q=t[tot].minn;
t[tot].sum=-t[tot].sum;
t[tot].minn=-t[tot].maxn;
t[tot].maxn=-q;
t[tot].flag2^=1;
return ;
}
if(t[tot].flag2) down(tot,l,r);
int mid=(l+r)/2;
if(x<=mid) //在左区间
change2(tot*2,l,mid,x,y);
if(y>mid) // 在右区间
change2(tot*2+1,mid+1,r,x,y);
t[tot].sum=(t[tot*2].sum+t[tot*2+1].sum);
t[tot].maxn=max(t[tot*2].maxn,t[tot*2+1].maxn);
t[tot].minn=max(t[tot*2].minn,t[tot*2+1].minn);
}
///////////////////////// 以上为线段树部分
void dfs1(int u,int fa) // 找重儿子
{
fa1[u]=fa; // 父亲节点
depth[u]=depth[fa]+1;
int heavy=0;
size[u]=1;
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(v!=fa)
{
int w=edge[i].w;
va[v]=w;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>heavy)
{
heavyson[u]=v;
heavy=size[v];
}
}
}
}
void dfs2(int u,int k)
{
top[u]=k; // 找到链头顶端
id[u]=++cntt; // 每个节点新编号
wt[cntt]=va[u];
if(heavyson[u]) dfs2(heavyson[u],k); // 优先遍历重儿子
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(v==fa1[u] || v==heavyson[u]) continue;
dfs2(v,v);
}
}
void get2(int x,int y) // 区间和
{
ans=0;
while(top[x]!=top[y])
{
if(depth[top[x]]<depth[top[y]]) swap(x,y);
ask1(1,1,n,id[top[x]],id[x]);
x=fa1[top[x]];
}
if(depth[x]>depth[y]) swap(x,y);
ask1(1,1,n,id[x]+1,id[y]);
printf("%lld\n",ans);
}
void get3(int x,int y) //最大值
{
ans=-0x7fffffff;
while(top[x]!=top[y])
{
if(depth[top[x]]<depth[top[y]]) swap(x,y);
ask2(1,1,n,id[top[x]],id[x]);
x=fa1[top[x]];
}
if(depth[x]>depth[y]) swap(x,y);
ask2(1,1,n,id[x]+1,id[y]);
printf("%lld\n",ans);
}
void get4(int x,int y) // 最小值
{
ans=0x7fffffff;
while(top[x]!=top[y])
{
if(depth[top[x]]<depth[top[y]]) swap(x,y);
ask3(1,1,n,id[top[x]],id[x]);
x=fa1[top[x]];
}
if(depth[x]>depth[y]) swap(x,y);
ask3(1,1,n,id[x]+1,id[y]);
printf("%lld\n",ans);
}
void get5(int x,int y) // 区间
{
while(top[x]!=top[y])
{
if(depth[top[x]]<depth[top[y]]) swap(x,y);
change2(1,1,n,id[top[x]],id[x]);
x=fa1[top[x]];
}
if(depth[x]>depth[y]) swap(x,y);
change2(1,1,n,id[x]+1,id[y]);
}
signed main()
{
scanf("%lld",&n);
for(int i=1;i<n;i++)
{
scanf("%lld%lld%lld",&u[i],&v[i],&w[i]);
addedge(u[i]+1,v[i]+1,w[i]);addedge(v[i]+1,u[i]+1,w[i]);
}
dfs1(1,0);
dfs2(1,1);
maketree(1,1,n);
scanf("%lld",&m);
for(int i=1;i<=m;i++)
{
int k,x,y,z;
cin>>s;
scanf("%lld%lld",&x,&y);
if(s[0]=='C')
{
int U=u[x]+1,V=v[x]+1;
if(fa1[U]==V) swap(V, U);
change1(1,1,n,id[V],id[V],y);
}
if(s[0]=='S'){get2(x+1,y+1);}
if(s[0]=='M' && s[1]=='A') {get3(x+1,y+1);}
if(s[0]=='M' && s[1]=='I') {get4(x+1,y+1);}
if(s[0]=='N') {get5(x+1,y+1);}
}
return 0;
}