#include <bits/stdc++.h>
using namespace std;
const int N=100000;
#define re register
#define lc (p<<1)
#define rc (p<<1|1)
inline int rd(){
char c=getchar();
int v=0,f=1;
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') v=(v<<3)+(v<<1)+(c^48),c=getchar();
return v*f;
}
struct node{
int u,v,w,nxt;
}e[N<<1];
int first[N],last;
inline void add(re int u,re int v,re int w){
e[++last].u=u,e[last].v=v,e[last].w=w;
e[last].nxt=first[u];
first[u]=last;
}
int st[N],siz[N],hson[N],top[N],pre[N],fa[N],dep[N],tot,a[N];
void dfs(re int u,re int faa){
siz[u]=1;
fa[u]=faa;
hson[u]=0;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fa[u]) continue;
dep[v]=dep[u]+1;
dfs(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[hson[u]]) hson[u]=v;
}
return;
}
void _dfs(re int u,re int tp){
st[u]=++tot;
pre[tot]=u;
top[u]=tp;
if(hson[u]) _dfs(hson[u],tp);
for(int i=first[u];i;i=e[i].nxt)
if(e[i].v!=fa[u]&&hson[u]!=e[i].v)
_dfs(e[i].v,e[i].v);
return;
}
struct tree{
int l,r,lcol,rcol,sum,lazy;
tree(){l=r=lcol=rcol=sum=lazy=0;}
}t[N<<2];
inline void pushup(re int p){
t[p].lcol=t[lc].lcol;
t[p].rcol=t[rc].rcol;
t[p].sum=t[lc].sum+t[rc].sum-(t[lc].rcol==t[rc].lcol);
}
inline void pushnow(re int p,re int v){
t[p].lcol=t[p].rcol=v;
t[p].lazy=v;
t[p].sum=1;
}
inline void pushdown(re int p){
if(t[p].lazy){
pushnow(lc,t[p].lazy);
pushnow(rc,t[p].lazy);
t[p].lazy=0;
}
}
void build(re int p,re int l,re int r){
t[p].l=l,t[p].r=r;
if(l==r) {
t[p].lcol=t[p].rcol=a[pre[l]];
t[p].sum=1;
t[p].lazy=0;
return;
}
re int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(p);
return ;
}
void change(re int p,re int ql,re int qr,re int v){
if(t[p].l>=ql&&t[p].r<=qr){
pushnow(p,v);
return;
}
pushdown(p);
re int mid=t[p].l+t[p].r>>1;
if(ql<=mid) change(lc,ql,qr,v);
if(qr>mid) change(rc,ql,qr,v);
pushup(p);
return;
}
tree query(re int p,re int ql,re int qr){
if(t[p].l>=ql&&t[p].r<=qr){
return t[p];
}
pushdown(p);
re int mid=t[p].l+t[p].r>>1;
re tree ll,rr;
if(ql<=mid) ll=query(lc,ql,qr);
if(qr>mid) rr=query(rc,ql,qr);
re tree ans;
ans.sum+=ll.sum+rr.sum-(ll.rcol==rr.lcol);
ans.rcol=rr.rcol?rr.rcol:ll.rcol;
ans.lcol=ll.lcol?ll.lcol:rr.lcol;
return ans;
}
void change(re int x,re int y,re int v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[x]]) swap(x,y);
change(1,st[top[x]],st[x],v);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
change(1,st[x],st[y],v);
}
int query(re int x,re int y){
re int lastx=-1,lasty=-1,ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y),swap(lastx,lasty);
re tree k=query(1,st[top[x]],st[x]);
ans+=(k.sum-(k.rcol==lastx));
lastx=k.lcol;
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y),swap(lastx,lasty);
re tree k=query(1,st[x],st[y]);
ans+=k.sum-(k.lcol==lastx)-(k.rcol==lasty);
return ans;
}
int main(){
re int n,m;scanf("%d%d",&n,&m);
for(re int i=1;i<=n;i++) scanf("%d",&a[i]);
for(re int i=1;i<n;i++) {
re int u=rd(),v=rd();
add(u,v,0);
add(v,u,0);
}
dep[1]=st[1]=pre[1]=st[0]=1;
dfs(1,0);
_dfs(1,1);
build(1,1,n);
while(m--){
re char c=getchar();
while(c!='Q'&&c!='C') c=getchar();
if(c=='Q'){
re int x,y;scanf("%d%d",&x,&y);
// cout<<query(x,y)<<"\n";
printf("%d\n",query(x,y));
}
else{
re int x,y,v;
scanf("%d%d%d",&x,&y,&v);
change(x,y,v);
}
}
}