#include <bits/stdc++.h>
using namespace std;
#define N 100010
int rt[N*20],lc[N*20],rc[N*20],sum[N*20],maxn[N*20],tot;
int n,q;
inline void update(int &p,int l,int r,int x,int v){
if(!p) p=++tot;
if(l==r) return void(maxn[p]=sum[p]=v);
int mid=l+r>>1;
if(x<=mid) update(lc[p],l,mid,x,v);
else update(rc[p],mid+1,r,x,v);
maxn[p]=max(maxn[lc[p]],maxn[rc[p]]);
sum[p]=sum[lc[p]]+sum[rc[p]];
}
inline void del(int p,int l,int r,int x,int v){
if(l==r) return sum[p]=0,void(maxn[p]=0);
int mid=l+r>>1;
if(x<=mid) update(lc[p],l,mid,x,v);
else update(rc[p],mid+1,r,x,v);
maxn[p]=max(maxn[lc[p]],maxn[rc[p]]);
sum[p]=sum[lc[p]]+sum[rc[p]];
}
inline int querysum(int p,int l,int r,int ql,int qr){
if(!p) return 0;
if(ql<=l&&r<=qr) return sum[p];
int mid=l+r>>1,ans=0;
if(ql<=mid)ans+=querysum(lc[p],l,mid,ql,qr);
if(qr>mid) ans+=querysum(rc[p],mid+1,r,ql,qr);
return ans;
}
inline int querymax(int p,int l,int r,int ql,int qr){
if(!p) return 0;
if(ql<=l&&r<=qr) return maxn[p];
int mid=l+r>>1,ans=0;
if(ql<=mid) ans=max(ans,querymax(lc[p],l,mid,ql,qr));
if(qr>mid) ans=max(ans,querymax(rc[p],mid+1,r,ql,qr));
return ans;
}
int first[N],to[N],nxt[N],cnt;
inline void add(int u,int v){
nxt[++cnt]=first[u];first[u]=cnt;
to[cnt]=v;
}
int siz[N],hson[N],dep[N],fa[N];
inline void dfs(int u,int f){
siz[u]=1;fa[u]=f;
for(int i=first[u];i;i=nxt[i]){
int v=to[i];
if(v==f) continue;
dep[v]=dep[u]+1;
dfs(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[hson[u]]) hson[u]=v;
}
}
int top[N],st[N],pre[N],last;
inline void _dfs(int u,int tp){
top[u]=tp;st[u]=++last;pre[tot]=u;
if(hson[u]) _dfs(hson[u],tp);
for(int i=first[u];i;i=nxt[i])
if(to[i]!=fa[u]&&to[i]!=hson[u])
_dfs(to[i],to[i]);
}
int querysum(int x,int y,int c){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=querysum(rt[c],1,n,st[top[x]],st[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans+=querysum(rt[c],1,n,st[x],st[y]);
return ans;
}
int querymax(int x,int y,int c){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans=max(ans,querymax(rt[c],1,n,st[top[x]],st[x]));
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
ans=max(ans,querymax(rt[c],1,n,st[x],st[y]));
return ans;
}
inline int rd(){
char c=getchar();int v=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') v=(v<<3)+(v<<1)+(c^48),c=getchar();
return v;
}
struct node{
int val,id;
}p[N];
int main(){
n=rd(),q=rd();
for(int i=1;i<=n;++i) p[i].val=rd(),p[i].id=rd();
for(int i=1;i<n;++i){int u=rd(),v=rd();add(u,v),add(v,u);}
dfs(1,0);
// cout<<"&(**&&(";
_dfs(1,1);
for(int i=1;i<=n;++i) update(rt[p[i].id],1,n,st[i],p[i].val);
while(q--){
char c=getchar();
while(c<'A'||c>'Z') c=getchar();
if(c=='C'){
c=getchar();
int x=rd(),v=rd();
if(c=='W') update(rt[p[x].id],1,n,st[x],v),p[x].val=v;
else del(rt[p[x].id],1,n,st[x],p[x].val),update(rt[v],1,n,st[x],p[x].val),p[x].id=v;
}
else{
c=getchar();
int x=rd(),y=rd();
if(c=='S') printf("%d\n",querysum(x,y,p[x].id));
else printf("%d\n",querymax(x,y,p[x].id));
}
}
}