rt.
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define tii tuple<int,int,int>
int n,m;
int a[100050];
vector<int>e[100050];
struct Node{
int pre,siz,dep;
int son,top,val;
int dfn,idx;
Node(){
pre=-1,siz=1,dep=0;
son=-1,top=-1,val=0;
dfn=-1,idx=-1;
}
}node[100050];
struct Tree{
int lc,rc,sum,laz,col;
Tree(){lc=rc=sum=laz=col=0;}
}s[500050];
#define ls p<<1
#define rs p<<1|1
void pushup(int p){
s[p].sum=s[ls].sum+s[rs].sum;
if(s[ls].rc==s[rs].lc)s[p].sum--;
s[p].lc=s[ls].lc;
s[p].rc=s[rs].rc;
}
void pushdown(int p,int l,int r){
if(s[p].laz){
s[ls].laz=s[rs].laz=s[p].laz;
s[ls].sum=s[rs].sum=1;
s[ls].lc=s[ls].rc=s[p].laz;
s[rs].lc=s[rs].rc=s[p].laz;
s[p].laz=0;
}
}
void build(int p,int l,int r){
if(l==r){
s[p].lc=s[p].rc=a[node[l].dfn];
s[p].sum=1;
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(p);
}
void modify(int p,int l,int r,int L,int R,int v){
if(L<=l&&r<=R){
s[p].sum=1;
s[p].lc=s[p].rc=v;
s[p].laz=v;
pushdown(p,l,r);
return;
}
pushdown(p,l,r);
int mid=(l+r)>>1;
if(L<=mid)modify(ls,l,mid,L,R,v);
if(mid<R)modify(rs,mid+1,r,L,R,v);
pushup(p);
}
Tree merge(Tree l,Tree r){
if(!l.sum)return r;
if(!r.sum)return l;
Tree x;
x.lc=l.lc,x.rc=r.rc;
x.sum=l.sum+r.sum-(l.rc==r.lc);
return x;
}
Tree query(int p,int l,int r,int L,int R){
if(L<=l&&r<=R)return s[p];
pushdown(p,l,r);
int mid=(l+r)>>1;
if(L>mid)return query(rs,mid+1,r,L,R);
if(R<=mid)return query(ls,l,mid,L,R);
return merge(query(ls,l,mid,L,R),query(rs,mid+1,r,L,R));
}
void dfs1(int x,int pre){
node[x].pre=pre;
node[x].dep=node[pre].dep+1;
node[x].val=a[x];
for(auto i:e[x]){
if(i==pre)continue;
dfs1(i,x);
node[x].siz+=node[i].siz;
if(node[x].son==-1)node[x].son=i;
else if(node[node[x].son].siz<node[i].siz)node[x].son=i;
}
}
int dfncnt=0;
void dfs2(int x,int top){
node[x].top=top;
node[x].dfn=++dfncnt;
node[dfncnt].idx=x;
if(node[x].son!=-1)dfs2(node[x].son,top);
for(auto i:e[x]){
if(i==node[x].pre)continue;
if(i==node[x].son)continue;
dfs2(i,i);
}
}
void Link(int u,int v,vector<pii>&link){
while(node[u].top!=node[v].top){
int topu=node[u].top,topv=node[v].top;
if(node[topu].dep>node[topv].dep){
link.push_back((pii){node[topu].dfn,node[u].dfn});
u=node[topu].pre;
}
else{
link.push_back((pii){node[topv].dfn,node[v].dfn});
v=node[topv].pre;
}
}
if(node[u].dep>node[v].dep)link.push_back((pii){node[v].dfn,node[u].dfn});
else link.push_back((pii){node[u].dfn,node[v].dfn});
}
int querylink(int x,int y){
Tree l,r;
while(node[x].top!=node[y].top){
int topx=node[x].top,topy=node[y].top;
if(node[topx].dep<node[topy].dep){
r=merge(query(1,1,n,node[topy].dfn,node[y].dfn),r);
y=node[topy].pre;
}
else{
l=merge(query(1,1,n,node[topx].dfn,node[x].dfn),l);
x=node[topx].pre;
}
}
if(node[x].dep<node[y].dep)r=merge(query(1,1,n,node[x].dfn,node[y].dfn),r);
else l=merge(query(1,1,n,node[y].dfn,node[x].dfn),l);
swap(l.lc,l.rc);
return merge(l,r).sum;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1,1);
dfs2(1,1);
build(1,1,n);
while(m--){
char op;
int a,b,c;
vector<pii>link;
cin>>op;
if(op=='C'){
cin>>a>>b>>c;
Link(a,b,link);
for(auto i:link)modify(1,1,n,i.first,i.second,c);
}
if(op=='Q'){
cin>>a>>b;
//Link(a,b,link);
cout<<querylink(a,b)<<endl;
}
}
return 0;
}