#include<bits/stdc++.h>
#define F first
#define S second
using namespace std;
const int N=1e5+5;
int n,m,c[N];
int dfn[N],rev[N],sfn;
int fa[N],top[N],dep[N],siz[N],son[N];
struct SGT{
#define mid (l+r>>1)
#define lp p<<1
#define rp p<<1|1
int lc[N<<2],rc[N<<2],lz[N<<2],num[N<<2];
inline void pushup(int p){
lc[p]=lc[lp];
rc[p]=rc[rp];
num[p]=num[lp]+num[rp]-(lc[rp]==rc[lp]);
}
inline void build(int p,int l,int r){
if(l==r)return lc[p]=rc[p]=c[rev[l]],num[p]=1,void();
build(lp,l,mid);
build(rp,mid+1,r);
return pushup(p);
}
inline void uplz(int p,int w){
num[p]=1;
lc[p]=rc[p]=lz[p]=w;
}
inline void pushdown(int p){
if(lz[p]){
uplz(lp,lz[p]);
uplz(rp,lz[p]);
lz[p]=0;
}
}
inline void modify(int p,int l,int r,int L,int R,int w){
if(l>R||L>r)return;
if(L<=l&&r<=R)return uplz(p,w);
pushdown(p);
modify(lp,l,mid,L,R,w);
modify(rp,mid+1,r,L,R,w);
return pushup(p);
}
inline pair<pair<int,int>,int> merge(pair<pair<int,int>,int> A,pair<pair<int,int>,int> B){
if(!A.S)return B;
if(!B.S)return A;
return {{A.F.F,B.F.S},A.S+B.S-(A.F.S==B.F.F)};
}
inline pair<pair<int,int>,int> query(int p,int l,int r,int L,int R,int flag){
if(l>R||L>r)return {{0,0},0};
if(L<=l&&r<=R){
if(flag)return {{lc[p],rc[p]},num[p]};
return {{rc[p],lc[p]},num[p]};
}
pushdown(p);
if(flag)return merge(query(lp,l,mid,L,R,flag),query(rp,mid+1,r,L,R,flag));
return merge(query(rp,mid+1,r,L,R,flag),query(lp,l,mid,L,R,flag));
}
}t;
vector<int>e[N];
inline void dfs_son(int u,int f){
dep[u]=dep[f]+1;
siz[u]=1;
fa[u]=f;
for(auto v:e[u])if(v^f){
dfs_son(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
inline void dfs_top(int u,int tp){
rev[dfn[u]=++sfn]=u;
top[u]=tp;
if(!son[u])return;
dfs_top(son[u],tp);
for(auto v:e[u])
if(v^fa[u]&&v^son[u])
dfs_top(v,v);
}
inline int query(int l,int r){
if(dfn[l]>dfn[r])l^=r,r^=l,l^=r;
pair<pair<int,int>,int>L,R;
while(top[l]!=top[r]){
if(dep[top[l]]>dep[top[r]]){
L=t.merge(L,t.query(1,1,n,dfn[top[l]],dfn[l],0));
l=fa[top[l]];
}
else{
R=t.merge(t.query(1,1,n,dfn[top[r]],dfn[r],1),R);
r=fa[top[r]];
}
}
if(l!=r){
if(dfn[l]>dfn[r])L=t.merge(L,t.query(1,1,n,dfn[r],dfn[l],0));
else R=t.merge(t.query(1,1,n,dfn[l],dfn[r],1),R);
}
L=t.merge(L,R);
return L.S;
}
inline void modify(int u,int v,int C){
if(dep[u]<dep[v])u^=v,v^=u,u^=v;
while(top[u]!=top[v]){
t.modify(1,1,n,dfn[top[u]],dfn[u],C);
u=fa[top[u]];
if(dep[top[u]]<dep[top[v]])u^=v,v^=u,u^=v;
}
if(dep[u]>dep[v])u^=v,v^=u,u^=v;
return t.modify(1,1,n,dfn[u],dfn[v],C);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
e[u].emplace_back(v);
e[v].emplace_back(u);
}
dfs_son(1,0);
dfs_top(1,1);
t.build(1,1,n);
char op[2];
for(int i=1,l,r,C;i<=m;i++){
scanf("%s%d%d",op,&l,&r);
if(op[0]=='Q')printf("%d\n",query(l,r));
else{
scanf("%d",&C);
modify(l,r,C);
}
}
return 0;
}