#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define ll long long
#define INF 1000000000
#define p(x) ('0'<=x&&x<='9')
#define For(i,l,r) for(int i=l;i<=r;i++)
char cc; int C;
template <class T>
void read( T &x )
{
x=0; cc=getchar(); C=1;
while(!p(cc)) { if(cc=='-') C=-1; cc=getchar(); }
while(p(cc)) { x=x*10+cc-48; cc=getchar(); }
x*=C;
}
using namespace std;
#define N 100010
int to[N<<2],nxt[N<<2],fst[N],e_tot;
void add_e(const int &_,const int &__)
{
to[e_tot]=__; nxt[e_tot]=fst[_]++; fst[_]=e_tot++;
to[e_tot]=_; nxt[e_tot]=fst[__]++; fst[__]=e_tot++;
}
struct node
{
int l,r,c[2];
int cnt,col[2];
int tag;
node() { tag=-1; }
}pool[N<<2];
int pcnt=1;
#define L pool[x].l
#define R pool[x].r
#define Lc pool[x].c[0]
#define Rc pool[x].c[1]
#define Lcol pool[x].col[0]
#define Rcol pool[x].col[1]
#define CNT pool[x].cnt
#define TAG pool[x].tag
void PushUP(int x)
{
CNT=pool[Lc].cnt+pool[Rc].cnt-(int)(pool[Lc].col[1]==pool[Rc].col[0]);
Lcol=pool[Lc].col[0];
Rcol=pool[Rc].col[1];
if(CNT==1) TAG=Lcol;
}
void PushDown(int x)
{
pool[Lc].col[0]=pool[Lc].col[1]=pool[Rc].col[0]=pool[Rc].col[1]=pool[Lc].tag=pool[Rc].tag=TAG;
pool[Lc].cnt=pool[Rc].cnt=1;
TAG=-1;
}
void build(int x,int l,int r,int a[])
{
L=l; R=r;
if(l==r)
{
Lcol=Rcol=a[l];
CNT=1;
return;
}
int mid=(l+r)>>1;
build(Lc=++pcnt,l,mid,a);
build(Rc=++pcnt,mid+1,r,a);
PushUP(x);
}
int query(int x,int l,int r)
{
if(~TAG) return 1;
if(l<=L&&R<=r) return CNT;
int mid=(L+R)>>1;
if(mid>=r) return query(Lc,l,r);
if(mid<l) return query(Rc,l,r);
return query(Lc,l,r)+query(Rc,l,r)-(int)(pool[Lc].col[1]==pool[Rc].col[0]);
}
int fill(int x,int l,int r,int col)
{
if(l<=L&&R<=r)
{
Lcol=Rcol=TAG=col; CNT=1;
return 0;
}
int mid=(L+R)>>1;
if(~TAG) PushDown(x);
if(mid>=l) fill(Lc,l,r,col);
if(mid<r) fill(Rc,l,r,col);
PushUP(x);
}
int find(int x,int pos)
{
if(L==R) return Lcol;
if(~TAG) return TAG;
return find(pos<=((L+R)>>1)?Lc:Rc,pos);
}
int col[N],a[N],id[N],up[N],fa[N],dep[N],mxson[N],siz[N],tot;
int n,m;
void dfs1(int x,int f)
{
siz[x]=1;
for(int i=fst[x];~i;i=nxt[i])
{
if(to[i]==f) continue;
dfs1(to[i],x);
if(siz[to[i]]>siz[mxson[x]]) mxson[x]=to[i];
siz[x]+=siz[to[i]];
}
}
void dfs2(int x,int f)
{
id[x]=++tot;
if(!mxson[x]) return;
fa[mxson[x]]=fa[x]; up[mxson[x]]=up[x]; dep[mxson[x]]=dep[x];
dfs2(mxson[x],x);
for(int i=fst[x];~i;i=nxt[i])
{
if(to[i]==mxson[x]||to[i]==f) continue;
fa[to[i]]=x; up[to[i]]=to[i]; dep[to[i]]=dep[x]+1;
dfs2(to[i],x);
}
}
void init()
{
memset(fst,-1,sizeof(fst));
int _,__;
read(n); read(m);
For(i,1,n) read(col[i]);
For(i,1,n-1)
{
read(_); read(__);
add_e(_,__);
}
dfs1(1,0);
up[1]=1;
dfs2(1,0);
for(int i=1;i<=n;i++) a[id[i]]=col[i];
build(pcnt,1,n,a);
}
int LCA(int x,int y)
{
if(dep[x]>dep[y]) swap(x,y);
while(dep[x]<dep[y]) y=fa[y];
while(up[x]!=up[y]) x=fa[x],y=fa[y];
return id[x]>id[y]?y:x;
}
int find_col(int pos)
{ return find(1,pos); }
int solve()
{
static int rt,ret,a,b,last_a,last_b;
read(a); read(b); rt=LCA(a,b);
ret=last_a=last_b=0;
while(id[a]>=id[rt])
{
ret+=query(1,max(id[up[a]],id[rt]),id[a]);
if(last_a) ret-=(int)(find_col(id[last_a])==find_col(id[a]));
last_a=up[a]; a=fa[a];
}
while(id[b]>=id[rt])
{
ret+=query(1,max(id[up[b]],id[rt]),id[b]);
if(last_b) ret-=(int)(find_col(id[last_b])==find_col(id[b]));
last_b=up[b]; b=fa[b];
}
return ret-1;
}
void fill()
{
static int rt,a,b,col;
read(a); read(b); read(col); rt=LCA(a,b);
while(id[a]>=id[rt])
{
fill(1,max(id[up[a]],id[rt]),id[a],col);
a=fa[a];
}
while(id[b]>=id[rt])
{
fill(1,max(id[up[b]],id[rt]),id[b],col);
b=fa[b];
}
}
int main()
{
freopen("BZOJ2243.in","r",stdin);
char s[10];
init();
while(m--)
{
scanf("%s",s);
if(s[0]=='Q') printf("%d\n",solve());
else fill();
}
return 0;
}