#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf (1LL<<60)
#define SIZE 1000001
#define x_lc ((x<<1))
#define x_rc ((x<<1)|1)
#define x_mid ((t[x].l+t[x].r)>>1)
#define leng(x) (t[x].r-t[x].l+1)
struct road{
ll ver,cost,id;
};
struct node{
ll l,r;
ll sum;
ll maxn;
ll minn;
bool flag;
void reverse(){
flag^=1;
swap(maxn,minn);
maxn=-maxn;
minn=-minn;
sum=-sum;
}
};
struct tree{
node t[SIZE];
void build(ll x,ll l,ll r){
t[x].l=l;
t[x].r=r;
if(l==r) return;
build(x_lc,l,x_mid);
build(x_rc,x_mid+1,r);
}
void push(ll x){
if(t[x].flag){
t[x].flag=0;
t[x_lc].reverse();
t[x_rc].reverse();
}
}
void update(ll x){
t[x].maxn=max(t[x_lc].maxn,t[x_rc].maxn);
t[x].minn=min(t[x_lc].minn,t[x_rc].minn);
t[x].sum=t[x_lc].sum+t[x_rc].sum;
}
void change(ll x,ll a,ll b){
if(t[x].l==t[x].r){
t[x].maxn=b;
t[x].minn=b;
t[x].sum=b;
return;
}
push(x);
if(x_mid>=a) change(x_lc,a,b);
if(x_mid+1<=a) change(x_rc,a,b);
update(x);
}
void reverse(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r){
t[x].reverse();
return;
}
push(x);
if(x_mid>=l) reverse(x_lc,l,r);
if(x_mid+1<=r) reverse(x_rc,l,r);
update(x);
}
ll query_max(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r) return t[x].maxn;
ll res=-inf;
push(x);
if(x_mid>=l) res=max(res,query_max(x_lc,l,r));
if(x_mid+1<=r) res=max(res,query_max(x_rc,l,r));
return res;
}
ll query_min(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r) return t[x].minn;
ll res=inf;
push(x);
if(x_mid>=l) res=min(res,query_min(x_lc,l,r));
if(x_mid+1<=r) res=min(res,query_min(x_rc,l,r));
return res;
}
ll query_sum(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r) return t[x].sum;
ll res=0;
push(x);
if(x_mid>=l) res+=query_sum(x_lc,l,r);
if(x_mid+1<=r) res+=query_sum(x_rc,l,r);
return res;
}
}SGT;
ll n,m,cnt;
ll to[SIZE];
ll fa[SIZE],d[SIZE];
ll son[SIZE],sz[SIZE];
ll id[SIZE],top[SIZE];
vector<road> r[SIZE];
void dfs1(ll x){
sz[x]=1;
for(ll i=0;i<r[x].size();i++){
ll y=r[x][i].ver;
ll z=r[x][i].cost;
if(y==fa[x]) continue;
fa[y]=x;
d[y]=d[x]+1;
dfs1(y);
sz[x]+=sz[y];
if(sz[y]>sz[son[x]])
son[x]=y;
}
}
void dfs2(ll x,ll t){
id[x]=++cnt;
top[x]=t;
if(son[x]==0) return;
dfs2(son[x],t);
for(ll i=0;i<r[x].size();i++){
ll y=r[x][i].ver;
ll z=r[x][i].cost;
if(y==fa[x]) continue;
SGT.change(1,id[y],z);
to[r[x][i].id]=id[y];
if(y==son[x]) continue;
dfs2(y,y);
}
}
void change(ll x,ll y){
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
SGT.reverse(1,id[top[x]],id[x]);
x=fa[top[x]];
}
if(d[x]>d[y]) swap(x,y);
SGT.reverse(1,id[x]+1,id[y]);
}
ll query_max(ll x,ll y){
ll res=-inf;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
res=max(res,SGT.query_max(1,id[top[x]],id[x]));
x=fa[top[x]];
}
if(d[x]>d[y]) swap(x,y);
res=max(res,SGT.query_max(1,id[x]+1,id[y]));
return res;
}
ll query_min(ll x,ll y){
ll res=inf;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
res=min(res,SGT.query_min(1,id[top[x]],id[x]));
x=fa[top[x]];
}
if(d[x]>d[y]) swap(x,y);
res=min(res,SGT.query_min(1,id[x]+1,id[y]));
return res;
}
ll query_sum(ll x,ll y){
ll res=0;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
res+=SGT.query_sum(1,id[top[x]],id[x]);
x=fa[top[x]];
}
if(d[x]>d[y]) swap(x,y);
res+=SGT.query_sum(1,id[x]+1,id[y]);
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
SGT.build(1,1,n);
for(ll i=1;i<n;i++){
ll x;road y;
cin>>x>>y.ver>>y.cost;
x++;y.ver++;
y.id=i;
r[x].push_back(y);
swap(x,y.ver);
r[x].push_back(y);
}
dfs1(1);
dfs2(1,1);
cin>>m;
while(m--){
string op;
ll x,y;
cin>>op>>x>>y;
if(op=="C") SGT.change(1,to[x],y);
x++;y++;
if(op=="N") change(x,y);
if(op=="SUM") cout<<query_sum(x,y)<<endl;
if(op=="MAX") cout<<query_max(x,y)<<endl;
if(op=="MIN") cout<<query_min(x,y)<<endl;
}
return 0;
}