#include<bits/stdc++.h>
using namespace std;
inline void read(int &x){
char c=getchar();
x=0;
bool f=0;
while(c<'0' || c>'9'){
if(c=='-') f=1;
c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
if(f) x=-x;
}
inline void read(long long &x){
char c=getchar();
x=0ll;
bool f=0;
while(c<'0' || c>'9'){
if(c=='-') f=1;
c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<1ll)+(x<<3ll)+(c^48ll);
c=getchar();
}
if(f) x=-x;
return ;
}
inline void read(unsigned long long &x){
char c=getchar();
x=0ull;
while(c<'0' || c>'9'){
c=getchar();
}
while(c>='0' && c<='9'){
x=(x<<1ull)+(x<<3ull)+(c^48ull);
c=getchar();
}
return ;
}
inline void write(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+48);
return ;
}
inline void write(long long x){
if(x<0ll){
putchar('-');
x=-x;
}
if(x>9ll) write(x/10ll);
putchar(x%10ll+48ll);
return ;
}
inline void write(unsigned long long x){
if(x>9ull) write(x/10ull);
putchar(x%10ull+48ull);
return ;
}
const int maxn=2e5+5;
int n;
int head[maxn];
struct edge{
int nex,to,w;
}e[maxn<<1];
int tot=-1;
inline void add(int x,int y,int w){
e[++tot].to=y,e[tot].nex=head[x],e[tot].w=w,head[x]=tot;
e[++tot].to=x,e[tot].nex=head[y],e[tot].w=w,head[y]=tot;
}
int val[maxn];
int fa[maxn],dep[maxn],siz[maxn],son[maxn];
inline void dfs1(int u){
son[u]=-1;
siz[u]=1;
for(int i=head[u];~i;i=e[i].nex){
int v=e[i].to;
if(dep[v]) continue ;
fa[v]=u;
dep[v]=dep[u]+1;
val[v]=e[i].w;
dfs1(v);
siz[u]+=siz[v];
if(son[u]==-1 || siz[v]>siz[son[u]])
son[u]=v;
}
return ;
}
int top[maxn],dfn[maxn],rnk[maxn],t2;
inline void dfs2(int u,int t){
top[u]=t;
dfn[u]=++t2;
rnk[t2]=u;
if(son[u]==-1) return ;
dfs2(son[u],t);
for(int i=head[u];~i;i=e[i].nex){
int v=e[i].to;
if(v!=son[u] && v!=fa[u]) dfs2(v,v);
}
return ;
}
struct Tree{
int l,r;
int sum,mx,mn;
int tag;
}T[maxn<<2];
inline void build(int rt,int l,int r){
T[rt].l=l,T[rt].r=r;
T[rt].tag=0;
if(l==r){
T[rt].sum=T[rt].mn=T[rt].mx=val[rnk[l]];
return ;
}
int mid=(l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
T[rt].sum=T[rt<<1].sum+T[rt<<1|1].sum;
T[rt].mn=min(T[rt<<1].mn,T[rt<<1|1].mn);
T[rt].mx=max(T[rt<<1].mx,T[rt<<1|1].mx);
}
inline void push_down(int rt){
if(T[rt].tag){
T[rt<<1].tag=T[rt<<1|1].tag=1;
T[rt<<1].sum=-T[rt<<1].sum;
T[rt<<1|1].sum=-T[rt<<1|1].sum;
int mx=T[rt<<1].mx,mn=T[rt<<1].mn;
T[rt<<1].mn=-mx,T[rt<<1].mx=-mn;
mx=T[rt<<1|1].mx,mn=T[rt<<1|1].mn;
T[rt<<1|1].mn=-mx,T[rt<<1|1].mx=-mn;
T[rt].tag=0;
}
}
inline void up_data1(int rt,int l,int r){
if(l<=T[rt].l && T[rt].r<=r){
T[rt].tag^=1;
T[rt].sum=-T[rt].sum;
int mx=T[rt].mx,mn=T[rt].mn;
T[rt].mx=-mn,T[rt].mn=-mx;
return ;
}
push_down(rt);
int mid=(T[rt].l+T[rt].r)>>1;
if(l<=mid) up_data1(rt<<1,l,r);
if(r>mid) up_data1(rt<<1|1,l,r);
T[rt].sum=T[rt<<1].sum+T[rt<<1|1].sum;
T[rt].mn=min(T[rt<<1].mn,T[rt<<1|1].mn);
T[rt].mx=max(T[rt<<1].mx,T[rt<<1|1].mx);
}
inline void up_data2(int rt,int pos,int val){
if(T[rt].l==T[rt].r){
T[rt].sum=T[rt].mn=T[rt].mx=val;
return ;
}
push_down(rt);
int mid=(T[rt].l+T[rt].r)>>1;
if(pos<=mid) up_data2(rt<<1,pos,val);
else up_data2(rt<<1|1,pos,val);
T[rt].sum=T[rt<<1].sum+T[rt<<1|1].sum;
T[rt].mn=min(T[rt<<1].mn,T[rt<<1|1].mn);
T[rt].mx=max(T[rt<<1].mx,T[rt<<1|1].mx);
}
const int INF=1e9;
inline int query_sum(int rt,int l,int r){
if(l<=T[rt].l && T[rt].r<=r){
return T[rt].sum;
}
push_down(rt);
int mid=(T[rt].l+T[rt].r)>>1;
int ans=0;
if(l<=mid) ans+=query_sum(rt<<1,l,r);
if(r>mid) ans+=query_sum(rt<<1|1,l,r);
return ans;
}
inline int query_min(int rt,int l,int r){
if(l<=T[rt].l && T[rt].r<=r){
return T[rt].mn;
}
push_down(rt);
int mid=(T[rt].l+T[rt].r)>>1;
int ans=INF;
if(l<=mid) ans=min(query_min(rt<<1,l,r),ans);
if(r>mid) ans=min(query_min(rt<<1|1,l,r),ans);
return ans;
}
inline int query_max(int rt,int l,int r){
if(l<=T[rt].l && T[rt].r<=r){
return T[rt].mx;
}
push_down(rt);
int mid=(T[rt].l+T[rt].r)>>1;
int ans=-INF;
if(l<=mid) ans=max(query_max(rt<<1,l,r),ans);
if(r>mid) ans=max(query_max(rt<<1|1,l,r),ans);
return ans;
}
struct Node{
int x,y;
}a[maxn];
inline void solve_N(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
up_data1(1,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
if(u!=v) up_data1(1,dfn[v],dfn[u]);
return ;
}
inline int solve_SUM(int u,int v){
int ans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans+=query_sum(1,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
if(u!=v) ans+=query_sum(1,dfn[v],dfn[u]);
return ans;
}
inline int solve_MAX(int u,int v){
int ans=-INF;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans=max(query_max(1,dfn[top[u]],dfn[u]),ans);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
if(u!=v) ans=max(query_max(1,dfn[v],dfn[u]),ans);
return ans;
}
inline int solve_MIN(int u,int v){
int ans=INF;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
ans=min(query_min(1,dfn[top[u]],dfn[u]),ans);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
if(u!=v) ans=min(query_min(1,dfn[v],dfn[u]),ans);
return ans;
}
int main(){
read(n);
memset(head,-1,sizeof head);
for(int i=1,u,v,w;i<n;i++){
read(u),read(v),read(w);
u++,v++;
a[i].x=u,a[i].y=v;
add(u,v,w);
}
dep[1]=1;
dfs1(1);
dfs2(1,1);
build(1,1,n);
int q;
read(q);
while(q--){
char op[5];
scanf("%s",op);
if(op[0]=='C'){
int i,w;
read(i),read(w);
if(dep[a[i].x]>dep[a[i].y]){
up_data2(1,dfn[a[i].x],w);
}
else{
up_data2(1,dfn[a[i].y],w);
}
}
else if(op[0]=='N'){
int u,v;
read(u),read(v);
u++,v++;
solve_N(u,v);
}
else if(op[0]=='S'){
int u,v;
read(u),read(v);
u++,v++;
write(solve_SUM(u,v));
putchar('\n');
}
else if(op[0]=='M' && op[1]=='A'){
int u,v;
read(u),read(v);
u++,v++;
write(solve_MAX(u,v));
putchar('\n');
}
else{
int u,v;
read(u),read(v);
u++,v++;
write(solve_MIN(u,v));
putchar('\n');
}
}
return 0;
}