#include <iostream>
#define int long long
#define ls (x<<1)
#define rs (x<<1|1)
const int M = 2e5+10;
int n,m;
struct EDGE
{
int Head[M],Next[M<<1],Ver[M<<1],Edge[M<<1],tot;
inline void add(int x,int y,int z)
{
Ver[++tot]=y,Edge[tot]=z,Next[tot]=Head[x],Head[x]=tot;
}
}E,E_;
int st[M],en[M],dis[M];
int dfn[M],rnk[M],top[M],fa[M],dep[M],siz[M],son[M],tot;
namespace Seg
{
struct Tree
{
int l,r,num,max,min,sum,tag;
}t[M<<2];
inline void pushUp(int x)
{
t[x].sum=t[ls].sum+t[rs].sum;
t[x].max=std::max(t[ls].max,t[rs].max);
t[x].min=std::min(t[ls].min,t[rs].min);
return ;
}
inline void pushDown(int x)
{
if(t[x].tag){
t[ls].sum=-t[ls].sum;
t[ls].num=-t[ls].num;
std::swap(t[ls].max,t[ls].min);
t[ls].min=-t[ls].min;
t[ls].max=-t[ls].max;
t[ls].tag^=1;
t[rs].sum=-t[rs].sum;
t[rs].num=-t[rs].num;
std::swap(t[rs].max,t[rs].min);
t[rs].min=-t[rs].min;
t[rs].max=-t[rs].max;
t[rs].tag^=1;
t[x].tag=0;
}
}
void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;
if(l==r){
t[x].num=t[x].sum=t[x].min=t[x].max=dis[rnk[l]];
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushUp(x);
return ;
}
void update_da(int x,int l,int r,int num)
{
if(t[x].l >= l&&t[x].r <= r){
t[x].num=t[x].sum=t[x].min=t[x].max=num;
return;
}
int mid=(t[x].l+t[x].r)>>1;
if(mid >= l) update_da(ls,l,r,num);
if(mid < r) update_da(rs,l,r,num);
pushUp(x);
return ;
}
void update_qu(int x,int l,int r)
{
if(t[x].l >= l&&t[x].r <= r){
t[x].sum=-t[x].sum;
t[x].num=-t[x].num;
std::swap(t[x].max,t[x].min);
t[x].min=-t[x].min;
t[x].max=-t[x].max;
t[x].tag^=1;
return;
}
pushDown(x);
int mid=(t[x].l+t[x].r)>>1;
if(mid >= l) update_qu(ls,l,r);
if(mid < r) update_qu(rs,l,r);
pushUp(x);
return ;
}
int getNum(int x,int l,int r,int mod)
{
if(t[x].l >= l&&t[x].r <= r){
if(mod==1)return t[x].sum;
if(mod==2)return t[x].min;
if(mod==3)return t[x].max;
}
pushDown(x);
int mid=(t[x].l+t[x].r)>>1,ans;
if(mod==1){
ans=0;
if(mid >= l) ans+=getNum(ls,l,r,mod);
if(mid < r) ans+=getNum(rs,l,r,mod);
}
if(mod==2){
ans=0x3f3f3f3f3f3f3f;
if(mid >= l) ans=std::min(ans,getNum(ls,l,r,mod));
if(mid < r) ans=std::min(ans,getNum(rs,l,r,mod));
}
if(mod==3){
ans=-0x3f3f3f3f3f3f3f;
if(mid >= l) ans=std::max(ans,getNum(ls,l,r,mod));
if(mid < r) ans=std::max(ans,getNum(rs,l,r,mod));
}
return ans;
}
}
void dfs1(int x,int f)
{
son[x]=-1;
siz[x]=1;
for(int i = E.Head[x];i;i=E.Next[i]){
int y=E.Ver[i],z=E.Edge[i];
if(y==f) continue;
fa[y]=x;
dep[y]=dep[x]+1;
dis[y]=z;
dfs1(y,x);
siz[x]+=siz[y];
if(son[x]==-1||siz[son[x]]<siz[y])son[x]=y;
}
}
void dfs2(int x,int t)
{
top[x]=t;
dfn[x]=++tot;
rnk[tot]=x;
if(son[x]==-1)return;
dfs2(son[x],t);
for(int i = E.Head[x];i;i=E.Next[i]){
int y=E.Ver[i];
if(y==fa[x]||y==son[x])continue;
dfs2(y,y);
}
}
inline void pathUpdate(int x,int y)
{
if(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
Seg::update_qu(1,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(x!=y){
if(dep[x]>dep[y]) std::swap(x,y);
Seg::update_qu(1,dfn[x]+1,dfn[y]);
}
return;
}
inline int path(int x,int y,int mod)
{
int ans;
if(mod==1) ans=0;
if(mod==2) ans=0x3f3f3f3f3f3f3f;
if(mod==3) ans=-0x3f3f3f3f3f3f3f;
if(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) std::swap(x,y);
if(mod==1) ans+=Seg::getNum(1,dfn[top[x]],dfn[x],mod);
if(mod==2) ans=std::min(Seg::getNum(1,dfn[top[x]],dfn[x],mod),ans);
if(mod==3) ans=std::max(Seg::getNum(1,dfn[top[x]],dfn[x],mod),ans);
x=fa[top[x]];
}
if(x!=y){
if(dep[x]>dep[y]) std::swap(x,y);
if(mod==1) ans+=Seg::getNum(1,dfn[x]+1,dfn[y],mod);
if(mod==2) ans=std::min(Seg::getNum(1,dfn[x]+1,dfn[y],mod),ans);
if(mod==3) ans=std::max(Seg::getNum(1,dfn[x]+1,dfn[y],mod),ans);
}
return ans;
}
inline int read(){
int num=0,fl=1;char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') fl=-1;
c=getchar();
}
while(c >='0'&&c <='9'){
num=(num<<3)+(num<<1)+(c^48);
c=getchar();
}
return num*fl;
}
signed main(){
n=read();
for(int i = 1;i < n;i++){
int x=read(),y=read(),z=read();
st[i]=x;en[i]=y;
E.add(x,y,z),E.add(y,x,z);
}
dfs1(0,-1);
dfs2(0,0);
Seg::build(1,1,n);
m=read();
while(m--){
char s[4];
scanf("%s",s+1);
if(s[1]=='S'){
int x=read(),y=read();
printf("%lld\n",path(x,y,1));
}
else if(s[2]=='I'){
int x=read(),y=read();
printf("%lld\n",path(x,y,2));
}
else if(s[2]=='A'){
int x=read(),y=read();
printf("%lld\n",path(x,y,3));
}
else if(s[1]=='C'){
int i=read(),num=read();
int x;
if(dep[en[i]]>dep[st[i]]) x=en[i];
else x=st[i];
Seg::update_da(1,dfn[x],dfn[x],num);
}
else if(s[1]=='N'){
int x=read(),y=read();
pathUpdate(x,y);
}
}
return 0;
}
WA on #11