#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,a[100010],b[100010];
struct trees{
int l,r,sum,st,en,lz;
}tree[400010];
void perhup(int i){
tree[i].st=tree[i*2].st;
tree[i].en=tree[i*2+1].en;
tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
if (tree[i*2].en==tree[i*2+1].st){
tree[i].sum--;
}
return ;
}
void build(int i,int l,int r){
tree[i].l=l;
tree[i].r=r;
tree[i].lz=-1e9-1;
if (l==r){
tree[i].st=a[l];
tree[i].en=a[l];
tree[i].sum=1;
return ;
}
int mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
perhup(i);
return ;
}
void pushdown(int i){
if (tree[i].lz!=-1e9-1){
tree[i*2].st=tree[i].lz;
tree[i*2].en=tree[i].lz;
tree[i*2].sum=1;
tree[i*2].lz=tree[i].lz;
tree[i*2+1].st=tree[i].lz;
tree[i*2+1].en=tree[i].lz;
tree[i*2+1].sum=1;
tree[i*2+1].lz=tree[i].lz;
tree[i].lz=-1e9-1;
}
return ;
}
void change(int i,int l,int r,int x){
if (tree[i].l>=l&&tree[i].r<=r){
tree[i].en=x;
tree[i].st=x;
tree[i].sum=1;
tree[i].lz=x;
return ;
}
if (tree[i].l>r||tree[i].r<l){
return ;
}
pushdown(i);
if (tree[i*2].r>=l) change(i*2,l,r,x);
if (tree[i*2+1].l<=r) change(i*2+1,l,r,x);
perhup(i);
return ;
}
int ens=-1e9-1;
int lc=-1e9-1,rc=-1e9-1;
int query(int i,int l,int r){
int ans=0;
if (tree[i].l>=l&&tree[i].r<=r){
if (tree[i].l==l){
lc=tree[i].st;
}
if (tree[i].r==r){
rc=tree[i].en;
}
ans=tree[i].sum;
if (tree[i*2].en==tree[i*2+1].st) ans--;
return tree[i].sum;
}
if (tree[i].l>r||tree[i].r<l) return 0;
pushdown(i);
if (tree[i].l<l&&tree[i].r>r&&tree[i*2].r>=l&&tree[i*2].r<r){
ans+=query(i*2,l,r);
ans+=query(i*2+1,l,r);
if (tree[i*2].en==tree[i*2+1].st){
ans--;
}
return ans;
}
if (tree[i*2].r>=l) ans+=query(i*2,l,r);
if (tree[i*2+1].l<=r) ans+=query(i*2+1,l,r);
perhup(i);
return ans;
}
int en,fi[100010];
struct rec{
int e,nex;
}z[200010];
void add(int s,int e){
en++;
z[en].e=e;
z[en].nex=fi[s];
fi[s]=en;
}
int cnt,fa[100010],son[100010],siz[100010],deep[100010],top[100010],id[100010];
void dfs1(int x,int f,int de){
fa[x]=f;
siz[x]=1;
deep[x]=de;
int p=-1;
for (int j=fi[x];j!=0;j=z[j].nex){
int i=z[j].e;
if (deep[i]==0){
dfs1(i,x,de+1);
siz[x]+=siz[i];
if (p==-1||siz[p]<siz[i]){
p=i;
}
}
}
son[x]=p;
return ;
}
void dfs2(int x,int topp){
top[x]=topp;
cnt++;
id[x]=cnt;
a[cnt]=b[x];
if (son[x]==-1){
return ;
}
dfs2(son[x],topp);
for (int j=fi[x];j!=0;j=z[j].nex){
int i=z[j].e;
if (i!=son[x]&&i!=fa[x]){
dfs2(i,i);
}
}
return ;
}
void qchange(int x,int y,int k){
while (top[x]!=top[y]){
if (deep[top[x]]<deep[top[y]]){
swap(x,y);
}
change(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
change(1,min(id[x],id[y]),max(id[x],id[y]),k);
return ;
}
void qsum(int x,int y){
int ans1=-1,ans2=-1;
int ans=0;
while (top[x]!=top[y]){
if (deep[top[x]]<deep[top[y]]){
swap(x,y);
swap(ans1,ans2);
}
ans+=query(1,id[top[x]],id[x]);
if (rc==ans1){
ans--;
}
ans1=lc;
x=fa[top[x]];
}
if (id[x]>id[y]){
swap(x,y);
swap(ans1,ans2);
}
ans+=query(1,id[x],id[y]);
if (rc==ans1){
ans--;
}
if (lc==ans2){
ans--;
}
printf("%d\n",ans);
return ;
}
char op;
int x,y;
int main(){
scanf("%d",&n);
int m;
scanf("%d",&m);
for (int i=1;i<=n;i++){
scanf("%d",&b[i]);
}
for (int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
memset(son,-1,sizeof(son));
dfs1(1,-1,1);
dfs2(1,1);
build(1,1,n);
for (int i=1;i<=m;i++){
cin>>op;
scanf("%d%d",&x,&y);
if (op=='C'){
int k;
scanf("%d",&k);
qchange(x,y,k);
}
else{
qsum(x,y);
}
}
return 0;
}