rt
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
int fa,dep,size,maxson,w,id,top;
vector<int>e;
}tr[N];
int dfn[N],tot=0;
void dfs1(int x,int fa,int dep){
tr[x].fa=fa,tr[x].dep=dep,tr[x].maxson=0,tr[x].size=1;
int maxx=-1;
for(auto it:tr[x].e){
if(it==tr[x].fa) continue;
dfs1(it,x,dep+1);
tr[x].size+=tr[it].size;
if(tr[it].size>maxx) maxx=tr[it].size,tr[x].maxson=it;
}
}
void dfs2(int x,int top){
tr[x].top=top,dfn[++tot]=tr[x].w,tr[x].id=tot;
if(!tr[x].maxson) return;
dfs2(tr[x].maxson,top);
for(auto it:tr[x].e){
if(it==tr[x].fa||it==tr[x].maxson) continue;
dfs2(it,it);
}
}
class XDS{
public:
struct node{
int l,r;
int col,lc,rc,num;
int tag;
}tr[N*4];
inline void pushup(int x){
tr[x].num=tr[x*2].num+tr[x*2+1].num;
if(tr[x*2].rc==tr[x*2+1].lc) tr[x].num--;
}
inline void pushdown(int x){
if(tr[x].tag!=-1){
tr[x*2+1].col=tr[x*2].col=tr[x*2+1].tag=tr[x*2].tag=tr[x].tag;
tr[x*2+1].num=tr[x*2].num=1;
tr[x].lc=tr[x].rc=tr[x].tag;
tr[x].tag=-1;
}
}
void build(int x,int l,int r){
tr[x].l=l,tr[x].r=r;
if(l==r){
tr[x].lc=tr[x].rc=tr[x].col=dfn[l];
tr[x].num=1,tr[x].tag=-1;
return;
}
int mid=(l+r)/2;
build(x*2,l,mid),build(x*2+1,mid+1,r);
pushup(x);
}
int query(int x,int l,int r){
if(tr[x].l>=l&&tr[x].r<=r) return tr[x].num;
//if(tr[x].num==1) return 1;
pushdown(x);
int mid=(tr[x].l+tr[x].r)/2;
int sum=0;
if(l<=mid) sum=query(x*2,l,r);
if(r>mid) sum+=query(x*2+1,l,r);
if(l<=mid&&r>mid){
if(tr[x*2].rc==tr[x*2+1].lc) sum--;
}
return sum;
}
void change(int x,int l,int r,int k){
if(tr[x].l>=l&&tr[x].r<=r){
tr[x].num=1;
tr[x].col=tr[x].tag=tr[x].lc=tr[x].rc=k;
}
pushdown(x);
int mid=(tr[x].l+tr[x].r)/2;
if(l<=mid) change(x*2,l,r,k);
if(r>mid) change(x*2+1,l,r,k);
pushup(x);
}
};
XDS xds;
int n,m;
inline void qchange(int a,int b,int c){
while(tr[a].top!=tr[b].top){
if(tr[tr[a].top].dep<tr[tr[b].top].dep) swap(a,b);
int t=tr[a].top;
xds.change(1,tr[t].id,tr[a].id,c);
a=tr[t].fa;
}
if(tr[a].dep>tr[b].dep) swap(a,b);
if(a!=b) xds.change(1,tr[a].id,tr[b].id,c);
}
inline int qnum(int a,int b){
int ans=0;
while(tr[a].top!=tr[b].top){
if(tr[tr[a].top].dep<tr[tr[b].top].dep) swap(a,b);
int t=tr[a].top;
ans+=xds.query(1,tr[t].id,tr[a].id);
if(tr[a].w==tr[t].w) ans--;
a=tr[t].fa;
}
if(tr[a].dep>tr[b].dep) swap(a,b);
if(a!=b) ans+=xds.query(1,tr[a].id,tr[b].id);
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>tr[i].w;
for(int i=1;i<=n-1;i++){
int u,v;
cin>>u>>v;
tr[u].e.push_back(v),tr[v].e.push_back(u);
}
dfs1(1,1,1);
dfs2(1,1);
xds.build(1,1,n);
while(m--){
char op;
int a,b,c;
cin>>op;
if(op=='C'){
cin>>a>>b>>c;
qchange(a,b,c);
}
else{
cin>>a>>b;
cout<<qnum(a,b)<<endl;
}
}
}