RT
#include <bits/stdc++.h>
using namespace std;
const int maxn=500005;
int n,m,cnt,now,L,R,lc,rc,ans1,ans2;
int head[maxn],w[maxn];
int dfn[maxn],son[maxn],fa[maxn],top[maxn],dep[maxn],siz[maxn],rev[maxn];
struct edge{
int v,nxt;
}a[maxn<<1];
struct nod{
int val,lc,rc,lazy;
}tree[maxn<<2];
inline int read(){
int ret=0,f=1; char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){ret=ret*10+ch-'0';ch=getchar();}
return ret*f;
}
inline void add(int x,int y){
++cnt;
a[cnt].v =y;
a[cnt].nxt=head[x];
head[x]=cnt;
}
inline void pushup(int nod){
int ls=nod<<1,rs=ls+1;
tree[nod].lc=tree[ls].lc;
tree[nod].rc=tree[rs].rc;
tree[nod].val=tree[ls].val+tree[rs].val-(tree[ls].rc==tree[rs].lc);
}
inline void pushdown(int nod){
int lazy=tree[nod].lazy; int ls=nod<<1,rs=ls+1;
if(!lazy) return;
tree[nod].lazy=0;
tree[ls].val=tree[rs].val=1;
tree[ls].lc=tree[ls].rc=tree[ls].lazy=lazy;
tree[rs].lc=tree[rs].rc=tree[rs].lazy=lazy;
}
void dfs1(int x,int f){
fa[x]=f; siz[x]=1;
for(int k=head[x];k;k=a[k].nxt){
int v=a[k].v;
if(v==f) continue;
dep[v]=dep[x]+1;
dfs1(v,x); siz[x]+=siz[v];
if(siz[son[x]]<siz[v]) son[x]=v;
}
}
void dfs2(int x,int f){
int s=son[x];
top[s]=top[x]; dfn[x]=++now; rev[now]=x;
// cout<<x<<" "<<f<<" "<<son[x]<<endl;
if(!son[x]) return;
dfs2(s,x);
for(int k=head[x];k;k=a[k].nxt){
int v=a[k].v;
if(v==f||v==s) continue;
top[v]=v; dfs2(v,x);
}
}
void build(int nod,int l,int r){
if(l==r){
tree[nod].val=1;
tree[nod].lc=tree[nod].rc=w[rev[l]];
return;
}
int mid=l+r>>1; int ls=nod<<1,rs=ls+1;
build(ls,l,mid); build(rs,mid+1,r); pushup(nod);
// cout<<l<<" "<<r<<" "<<tree[nod].val<<endl;
}
void update(int nod,int l,int r,int ll,int rr,int val){
if(l==ll&&r==rr){
tree[nod].val=1;
tree[nod].lc=tree[nod].rc=val;
tree[nod].lazy=val;
return;
}
pushdown(nod);
int mid=l+r>>1; int ls=nod<<1,rs=ls+1;
if(rr<=mid){update(ls,l,mid,ll,rr,val);pushup(nod);return;}
if(ll>mid){update(rs,mid+1,r,ll,rr,val);pushup(nod);return;}
update(ls,l,mid,ll,mid,val); update(rs,mid+1,r,mid+1,rr,val); pushup(nod);
}
int query(int nod,int l,int r,int ll,int rr){
// cout<<l<<" "<<r<<" "<<ll<<" "<<rr<<" "<<tree[nod].val<<" "<<tree[nod].lc<<" "<<tree[nod].rc<<endl;
if(l==L) lc=tree[nod].lc;
if(r==R) rc=tree[nod].rc;
if(l==ll&&r==rr) return tree[nod].val;
pushdown(nod);
int mid=l+r>>1; int ls=nod<<1,rs=ls+1;
if(rr<=mid) return query(ls,l,mid,ll,rr);
if(ll>mid) return query(rs,mid+1,r,ll,rr);
return query(ls,l,mid,ll,mid)+query(rs,mid+1,r,mid+1,rr)-(tree[ls].rc==tree[rs].lc);
}
void scan(){
n=read(); m=read();
for(int k=1;k<=n;k++) w[k]=read();
for(int k=1;k<n;k++){
int x,y;
x=read(); y=read();
add(x,y); add(y,x);
}
}
void prework(){
dep[1]=1; dfs1(1,0);
top[1]=1; dfs2(1,0);
build(1,1,n);
}
int ask(int x,int y){
int ans=0; int xc=0,yc=0;
ans1=0; ans2=0;
while(top[x]!=top[y]){
int tx=top[x],ty=top[y];
if(dep[tx]<dep[ty]) swap(x,y),swap(tx,ty),swap(ans1,ans2);
L=dfn[tx]; R=dfn[x];
ans+=query(1,1,n,dfn[tx],dfn[x]);
x=fa[tx]; ans1-=(ans1==rc); ans1=lc;
}
if(dep[x]>dep[y]) swap(x,y),swap(ans1,ans2);
L=dfn[x]; R=dfn[y];
ans+=query(1,1,n,dfn[x],dfn[y]);
ans-=(lc==ans1); ans-=(rc==ans2);
return ans;
}
void change(int x,int y,int val){
while(top[x]!=top[y]){
int tx=top[x],ty=top[y];
if(dep[tx]<dep[ty]) swap(x,y),swap(tx,ty);
update(1,1,n,dfn[tx],dfn[x],val); x=fa[tx];
}
if(dep[x]>dep[y]) swap(x,y);
update(1,1,n,dfn[x],dfn[y],val);
}
void solve(){
for(int k=1;k<=m;k++){
char ch=getchar();
while(!isalpha(ch)) ch=getchar();
int opt=(ch=='C'); int l,r,val;
l=read(); r=read();
if(opt){val=read();change(l,r,val);}
else{printf("%d\n",ask(l,r));}
}
}
signed main(){
scan(); prework(); solve();
return 0;
}