#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct TREE {
int l,r,lc,rc,d,lazy;
}t[N*4];
struct EDGE{
int to,next;
}e[N*2];
int a[N],w[N],fa[N],deep[N],siz[N],son[N],h[N],tot,top[N],id[N],cnt,cr,cl,n,m;
void add (int u,int v){
e[++tot].to=v;
e[tot].next=h[u];
h[u]=tot;
}
void build (int k,int l,int r){
t[k].l=l;
t[k].r=r;
if (l==r){
t[k].lc=t[k].rc=w[l];
t[k].d=1;
return;
}
int mid=(l+r)>>1;
build(k*2,l,mid);
build (k*2+1,mid+1,r);
t[k].lc=t[k*2].lc;
t[k].rc=t[k*2+1].rc;
t[k].d=t[k*2+1].d+t[k*2].d;
if (t[k*2].rc==t[k*2+1].lc){
t[k].d--;
}
}
void pushdown(int k){
if (t[k].l!=t[k].r&&t[k].lazy){
t[k*2].lazy=t[k*2+1].lazy=t[k*2].lc=t[k*2+1].rc=t[k*2].rc=t[k*2+1].lc=t[k].lazy;
t[k*2].d=t[k*2+1].d=1;
}
t[k].lazy=0;
}
void change (int k,int l,int r,int c){
if (t[k].r<l||t[k].l>r){
return;
}
if (t[k].r<=r&&t[k].l>=l){
t[k].lazy=t[k].lc=t[k].rc=c;
t[k].d=1;
return;
}
pushdown(k);
change (k*2,l,r,c);
change(k*2+1,l,r,c);
t[k].d=t[k*2].d+t[k*2+1].d;
t[k].lc=t[k*2].lc;
t[k].rc=t[k*2].rc;
if (t[k*2].rc==t[k*2+1].lc){
t[k].d--;
}
}
int query (int k,int l,int r){
if (t[k].l==l)cl=t[k].lc;
if (t[k].r==r)cr=t[k].rc;
if (t[k].r<=r&&t[k].l>=l){
return t[k].d;
}
pushdown (k);
int mid=(t[k].l+t[k].r)>>1,res=0;
bool ok=0;
if (r<=mid)return query(k*2,l,r);
if (l>mid)return query(k*2+1,l,r);
res=query(k*2,l,r)+query(k*2+1,l,r);
if (t[k*2].rc==t[k*2+1].lc){
res--;
}
return res;
}
void dfs1 (int x,int f,int dep){
fa[x]=f;
deep[x]=dep;
siz[x]=1;
int mx=0;
for (int i=h[x];i;i=e[i].next){
int y=e[i].to;
if (y==f)continue;
dfs1(y,x,dep+1);
siz[x]+=siz[y];
if (siz[y]>mx){
mx=siz[y];
son[x]=y;
}
}
}
void dfs2 (int x,int tp){
top[x]=tp;
id[x]=++cnt;
w[cnt]=a[x];
if (!son[x]){
return;
}
dfs2(son[x],tp);
for (int i=h[x];i;i=e[i].next){
int y=e[i].to;
if (y==fa[x]||y==son[x])continue;
dfs2(y,y);
}
}
void crange (int u,int v,int c){
while (top[u]!=top[v]){
if (deep[top[u]]<deep[top[v]]){
swap(u,v);
}
change (1,id[top[u]],id[u],c);
u=fa[top[u]];
}
if (deep[u]>deep[v]){
swap(u,v);
}
change (1,id[u],id[v],c);
}
int qrange (int u,int v){
int ans=0,cl1=-1,cl2=-1;
while (top[u]!=top[v]){
if (deep[top[u]]<deep[top[v]]){
swap(u,v);swap(cl1,cl2);
}
ans+=query(1,id[top[u]],id[u]);
if (cl1==cr)ans--;
u=fa[top[u]];
cl1=cl;
}
if (deep[u]>deep[v]){
swap(u,v);swap(cl1,cl2);
}
ans+=query(1,id[u],id[v]);
if(cl1==cr)ans--;
if (cl2==cl)ans--;
return ans;
}
int main (){
scanf ("%d %d",&n,&m);
for (int i=1;i<=n;i++){
scanf ("%d",&a[i]);
}
for (int i=1;i<n;i++){
int u,v;
scanf ("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1,1,1);
dfs2(1,1);
build(1,1,n);
while (m--){
char opt;
cin>>opt;
if (opt=='C'){
int x,y,z;
scanf ("%d%d%d",&x,&y,&z);
crange(x,y,z);
}
else {
int x,y;
scanf ("%d%d",&x,&y);
printf ("%d\n",qrange(x,y));
}
}
return 0;
}