#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define int long long
using namespace std;
const int N=1e5+10;
char eof_flag;inline char read(int*s){if(eof_flag)return 0;int k=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9')){if(c==EOF){eof_flag=1;return 0;}c=getchar();}f=(c=='-')?-1:1;k=(c=='-')?0:(c^48);c=getchar();while(c>='0'&&c<='9')k=(k<<1)+(k<<3)+(c^48),c=getchar();if(c==EOF)eof_flag=1;(*s)=f>0?k:-k;return 1;}
inline void write(int x){if(x<0)putchar('-'),x=-x;if(x>9)write(x/10);putchar(x%10+'0');return;}
int n,q;
int size[N],dep[N],f[N],top[N],son[N],idx[N],seq[N],cnt,s[N],col[N];
int tot,root[N];
vector<int> e[N];
struct node {int l,r,maxx,sum;}t[N*40];
inline void push_up(int u)
{
t[u].sum=t[t[u].l].sum+t[t[u].r].sum;
t[u].maxx=max(t[t[u].l].maxx,t[t[u].r].maxx);
return ;
}
inline void update(int &u,int l,int r,int pos,int w)
{
if (!u) u=++tot;
if (l==r)
{
t[u].sum=t[u].maxx=w;
return ;
}
int mid=l+r>>1;
if (pos<=mid) update(t[u].l,l,mid,pos,w);
else update(t[u].r,mid+1,r,pos,w);
push_up(u);
return ;
}
inline int query_max(int u,int l,int r,int L,int R)
{
if (!u) return -1;
if (r<L or l>R) return -1;
if (l>=L and r<=R) return t[u].maxx;
int mid=l+r>>1;
return max(query_max(t[u].l,l,mid,L,R),query_max(t[u].r,mid+1,r,L,R));
}
inline int query_sum(int u,int l,int r,int L,int R)
{
if (!u) return 0;
if (r<L or l>R) return 0;
if (l>=L and r<=R) return t[u].sum;
int mid=l+r>>1;
return query_sum(t[u].l,l,mid,L,R)+query_sum(t[u].r,mid+1,r,L,R);
}
inline void dfs(int u,int fa)
{
dep[u]=dep[fa]+1,f[u]=fa;
size[u]=1;
for (auto v : e[u])
{
if (v==fa) continue;
dfs(v,u);
if (size[v]>size[son[u]]) son[u]=v;
}
return ;
}
inline void df5(int u,int topfa)
{
idx[u]=++cnt,seq[cnt]=u;
top[u]=topfa;
if (son[u]) df5(son[u],topfa);
for (auto v : e[u])
{
if (v==f[u] or v==son[u]) continue;
df5(v,v);
}
return ;
}
inline int query_range_max(int u,int v)
{
int ans=-1,tmp=col[v];
while (top[u]!=top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
ans=max(ans,query_max(root[tmp],1,n,idx[top[u]],idx[u]));
u=f[top[u]];
}
if (dep[u]<dep[v]) swap(u,v);
ans=max(ans,query_max(root[tmp],1,n,idx[v],idx[u]));
return ans;
}
inline int query_range_sum(int u,int v)
{
int ans=0,tmp=col[v];
while (top[u]!=top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
ans+=query_sum(root[tmp],1,n,idx[top[u]],idx[u]);
u=f[top[u]];
}
if (dep[u]<dep[v]) swap(u,v);
ans+=query_sum(root[tmp],1,n,idx[v],idx[u]);
return ans;
}
signed main()
{
ios::sync_with_stdio(0);
cin>>n>>q;
for (int i=1;i<=n;i++) cin>>s[i]>>col[i];
for (int i=1;i<=n-1;i++)
{
int u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0),df5(1,1);
// update(root[col[seq[1]]],1,n,1,s[seq[1]]);
for (int i=1;i<=n;i++) update(root[col[seq[i]]],1,n,i,s[seq[i]]);
while (q--)
{
string t;
int u,v;
cin>>t;
cin>>u>>v;
// cout<<t<<" "<<u<<" "<<v<<endl;
if (t=="CC")
{
update(root[col[u]],1,n,idx[u],0);
col[u]=v;
update(root[col[u]],1,n,idx[u],t[u]);
}
if (t=="CW") t[u]=v,update(root[col[u]],1,n,idx[u],v);
if (t=="QS") cout<<query_range_max(u,v)<<endl;
if (t=="QM") cout<<query_range_sum(u,v)<<endl;
}
return 0;
}
没过样例。。。