#include<bits/stdc++.h>
using namespace std;
const int N=2*1e5+10,INF=2147483647;
struct Edge{
int to,w;
};
vector<Edge>G[N];
int n,m;
int U[N],V[N];
int size[N],depth[N],fa[N],son[N],ans[N];
int top[N],id[N],rev[N],cnt;
int s[N<<2],mx[N<<2],mn[N<<2];
bool Opposite[N<<2];
char opt[10];
int u,v;
void DFS_Find_Son(int u){
size[u]=1;
depth[u]=depth[fa[u]]+1;
for(int i=0;i<G[u].size();i++){
Edge e=G[u][i];
if(fa[u]==e.to)continue;
fa[e.to]=u;
ans[e.to]=e.w;
DFS_Find_Son(e.to);
size[u]+=size[e.to];
if(size[son[u]]<size[e.to])
son[u]=e.to;
}
}
void DFS_Change(int u,int tp){
top[u]=tp;
id[u]=++cnt;
rev[cnt]=u;
if(son[u])
DFS_Change(son[u],tp);
for(int i=0;i<G[u].size();i++){
Edge e=G[u][i];
if(fa[u]==e.to||son[u]==e.to)continue;
DFS_Change(e.to,e.to);
}
}
void Up(int p){
s[p]=s[p<<1]+s[p<<1|1];
mx[p]=max(mx[p<<1],mx[p<<1|1]);
mn[p]=min(mn[p<<1],mn[p<<1|1]);
}
void Down(int p){
Opposite[p<<1]=!Opposite[p<<1];
Opposite[p<<1|1]=!Opposite[p<<1|1];
s[p<<1]=-s[p<<1];
s[p<<1|1]=-s[p<<1|1];
mx[p<<1]=-mx[p<<1];
mn[p<<1]=-mn[p<<1];
swap(mx[p<<1],mn[p<<1]);
mx[p<<1|1]=-mx[p<<1|1];
mn[p<<1|1]=-mn[p<<1|1];
swap(mx[p<<1|1],mn[p<<1|1]);
Opposite[p]=false;
}
void Build(int p,int l,int r){
if(l==r){
s[p]=mx[p]=mn[p]=ans[rev[l]];
return;
}
int mid=(l+r)>>1;
Build(p<<1,l,mid),Build(p<<1|1,mid+1,r);
Up(p);
}
void Update_Change(int p,int l,int r,int x,int v){
if(x<l||x>r)return;
if(l==r){
s[p]=mx[p]=mn[p]=v;
return;
}
if(Opposite[p])Down(p);
int mid=(l+r)>>1;
Update_Change(p<<1,l,mid,x,v);
Update_Change(p<<1|1,mid+1,r,x,v);
Up(p);
}
void Update_Opposite(int p,int l,int r,int x,int y){
if(l>y||x>r)return;
if(x<=l&&r<=y){
Opposite[p]=!Opposite[p];
s[p]=-s[p];
mx[p]=-mx[p];
mn[p]=-mn[p];
swap(mx[p],mn[p]);
return;
}
if(Opposite[p])Down(p);
int mid=(l+r)>>1;
Update_Opposite(p<<1,l,mid,x,y);
Update_Opposite(p<<1|1,mid+1,r,x,y);
Up(p);
}
int Query_Sum(int p,int l,int r,int x,int y){
if(l>y||x>r)return 0;
if(x<=l&&r<=y)return s[p];
if(Opposite[p])Down(p);
int mid=(l+r)>>1;
int sum=0;
sum+=Query_Sum(p<<1,l,mid,x,y);
sum+=Query_Sum(p<<1|1,mid+1,r,x,y);
Up(p);
return sum;
}
int Query_Max(int p,int l,int r,int x,int y){
if(l>y||x>r)return -INF;
if(x<=l&&r<=y)return mx[p];
if(Opposite[p])Down(p);
int mid=(l+r)>>1;
int ans=-INF;
ans=max(ans,Query_Max(p<<1,l,mid,x,y));
ans=max(ans,Query_Max(p<<1|1,mid+1,r,x,y));
Up(p);
return ans;
}
int Query_Min(int p,int l,int r,int x,int y){
if(l>y||x>r)return INF;
if(x<=l&&r<=y)return mn[p];
if(Opposite[p])Down(p);
int mid=(l+r)>>1;
int ans=INF;
ans=min(ans,Query_Min(p<<1,l,mid,x,y));
ans=min(ans,Query_Min(p<<1|1,mid+1,r,x,y));
Up(p);
return ans;
}
void Update_Change(int u,int v,int w){
if(fa[u]==v)Update_Change(1,1,n,id[u],w);
else Update_Change(1,1,n,id[v],w);
}
void Update_Opposite(int u,int v){
if(top[u]!=top[v]){
if(depth[top[u]]<depth[top[v]])swap(u,v);
Update_Opposite(1,1,n,id[top[u]],id[u]);
u=fa[top[u]];
}
if(id[u]>id[v])swap(u,v);
if(u!=v)Update_Opposite(1,1,n,id[u]+1,id[v]);
}
int Query_Sum(int u,int v){
int sum=0;
while(top[u]!=top[v]){
if(depth[top[u]]<depth[top[v]])swap(u,v);
sum+=Query_Sum(1,1,n,id[top[u]],id[u]);
u=fa[top[u]];
}
if(id[u]>id[v])swap(u,v);
if(u!=v)sum+=Query_Sum(1,1,n,id[u]+1,id[v]);
return sum;
}
int Query_Max(int u,int v){
int ans=-INF;
while(top[u]!=top[v]){
if(depth[top[u]]<depth[top[v]])swap(u,v);
ans=max(ans,Query_Max(1,1,n,id[top[u]],id[u]));
u=fa[top[u]];
}
if(id[u]>id[v])swap(u,v);
if(u!=v)ans=max(ans,Query_Max(1,1,n,id[u]+1,id[v]));
return ans;
}
int Query_Min(int u,int v){
int ans=INF;
while(top[u]!=top[v]){
if(depth[top[u]]<depth[top[v]])swap(u,v);
ans=min(ans,Query_Min(1,1,n,id[top[u]],id[u]));
u=fa[top[u]];
}
if(id[u]>id[v])swap(u,v);
if(u!=v)ans=min(ans,Query_Min(1,1,n,id[u]+1,id[v]));
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1,w;i<=n-1;i++){
scanf("%d%d%d",&U[i],&V[i],&w);
U[i]++,V[i]++;
G[U[i]].push_back(Edge{V[i],w});
G[V[i]].push_back(Edge{U[i],w});
}
DFS_Find_Son(1);
DFS_Change(1,1);
Build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%s%d%d",opt+1,&u,&v);
if(opt[1]=='C'){
Update_Change(U[u],V[u],v);
continue;
}
u++,v++;
if(opt[1]=='N')
Update_Opposite(u,v);
else if(opt[1]=='S')
printf("%d\n",Query_Sum(u,v));
else if(opt[2]=='A')
printf("%d\n",Query_Max(u,v));
else
printf("%d\n",Query_Min(u,v));
}
return 0;
}