#include<bits/stdc++.h>
#define ls k<<1
#define rs k<<1|1
using namespace std;
const int maxn=1e5+5;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
int res=0;
char ch=gc();
while(ch<'0'||ch>'9')
ch=gc();
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<<3)+(ch^'0');
ch=gc();
}
return res;
}
vector<int> G[maxn];
int n,q,tot,a[maxn],son[maxn],w[maxn],fa[maxn],dep[maxn],siz[maxn],first[maxn],dfn[maxn],DFN[maxn];
struct ST{
int l,r,num,add,L,R;
}f[maxn<<2];
void dfs1(int u){
siz[u]=1;
for(int i=0,len=G[u].size();i^len;++i){
int v=G[u][i];
if(v^fa[u]){
dep[v]=dep[u]+1;
fa[v]=u;
siz[u]+=siz[v];
dfs1(v);
if(siz[v]>siz[son[u]])
son[u]=v;
}
}
}
void dfs2(int u,int t){
dfn[u]=++tot;
DFN[tot]=u;
first[u]=t;
if(son[u])
dfs2(son[u],t);
for(int i=0,len=G[u].size();i^len;++i){
int v=G[u][i];
if((v^son[u])&&(v^fa[u]))
dfs2(v,v);
}
}
void build(int k,int l,int r){
f[k].add=-1,f[k].L=l,f[k].R=r;
if(l==r){
f[k].l=f[k].r=a[DFN[l]];
f[k].num=1;
return;
}
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
f[k].l=f[ls].l,f[k].r=f[rs].r;
f[k].num=f[ls].num+f[rs].num-(f[ls].r==f[rs].l);
}
inline void pushdown(int k){
if(f[k].add!=-1){
f[ls].num=f[rs].num=1;
f[ls].add=f[rs].add=f[ls].l=f[ls].r=f[rs].l=f[rs].r=f[k].add;
f[k].add=-1;
}
}
inline int find(int p){
int k=1;
while(f[k].L^f[k].R){
pushdown(k);
int mid=f[k].L+f[k].R>>1;
if(p<=mid)
k=ls;
else
k=rs;
}
return f[k].l;
}
void change(int k,int x,int y,int v){
if(f[k].add==v)
return;
if(x<=f[k].L&&f[k].R<=y){
f[k].num=1;
f[k].add=f[k].l=f[k].r=v;
return;
}
pushdown(k);
int mid=f[k].L+f[k].R>>1;
if(x<=mid)
change(ls,x,y,v);
if(y>mid)
change(rs,x,y,v);
f[k].l=f[ls].l,f[k].r=f[rs].r;
f[k].num=f[ls].num+f[rs].num-(f[ls].r==f[rs].l);
}
int query(int k,int x,int y){
if(x<=f[k].L&&f[k].R<=y)
return f[k].num;
pushdown(k);
int mid=f[k].L+f[k].R>>1,res=0;
if(x<=mid)
res+=query(ls,x,y);
if(y>mid)
res+=query(rs,x,y);
if(x<=mid&&y>mid)
res-=(f[ls].r==f[rs].l);
return res;
}
void push(int a,int b,int c){
while(first[a]^first[b]){
if(dep[first[a]]<dep[first[b]])
swap(a,b);
change(1,dfn[first[a]],dfn[a],c);
a=fa[first[a]];
}
if(dep[a]<dep[b])
swap(a,b);
change(1,dfn[b],dfn[a],c);
}
inline int ask(int a,int b){
int ans=0,l=-1,r=-1;
while(first[a]^first[b]){
if(dep[first[a]]<dep[first[b]]){
swap(l,r);
swap(a,b);
}
ans+=query(1,dfn[first[a]],dfn[a]);
if(l==find(dfn[a]))
--ans;
l=find(dfn[first[a]]);
a=fa[first[a]];
}
if(dep[a]<dep[b]){
swap(l,r);
swap(a,b);
}
ans+=query(1,dfn[b],dfn[a]);
ans-=(l==find(dfn[a]));
ans-=(r==find(dfn[b]));
return ans;
}
int main(){
n=read(),q=read();
for(int i=1;i<=n;++i)
a[i]=read();
for(int i=1;i<n;++i){
int u=read(),v=read();
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1);
dfs2(1,1);
build(1,1,n);
while(q--){
char ch=gc();
while(ch!='Q'&&ch!='C')
ch=gc();
int a=read(),b=read(),c;
if(ch^'C')
printf("%d\n",ask(a,b));
else{
c=read();
push(a,b,c);
}
}
return 0;
}