#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf (1LL<<60)
#define SIZE 1000001
#define x_lc ((x<<1))
#define x_rc ((x<<1)|1)
#define x_mid ((t[x].l+t[x].r)>>1)
#define leng(x) (t[x].r-t[x].l+1)
struct node{
ll l,r;
ll cl,cr;
ll data;
ll tag;
void change(ll x){
data=1;
tag=x;
cl=x;
cr=x;
}
};
node operator+ (node x,node y){
node new_node;
new_node.cl=x.cl;
new_node.cr=y.cr;
new_node.data=x.data+y.data;
if(x.cr==y.cl) new_node.data--;
return new_node;
}
struct point{
ll fa,d,sz,son;
ll id,top,w;
};
struct SegmentTree{
node t[SIZE];
void update(ll x){
t[x].cl=t[x_lc].cl;
t[x].cr=t[x_rc].cr;
t[x].data=t[x_lc].data+t[x_rc].data;
if(t[x_lc].cr==t[x_rc].cl) t[x].data--;
}
void push_down(ll x){
if(t[x].tag){
t[x_lc].change(t[x].tag);
t[x_rc].change(t[x].tag);
t[x].tag=0;
}
}
void build(ll x,ll l,ll r){
t[x].l=l;
t[x].r=r;
t[x].tag=0;
if(l==r){
t[x].data=0;
return;
}
build(x_lc,l,x_mid);
build(x_rc,x_mid+1,r);
update(x);
}
void change(ll x,ll l,ll r,ll y){
if(t[x].l>=l&&t[x].r<=r){
t[x].change(y);
return;
}
push_down(x);
if(x_mid>=l) change(x_lc,l,r,y);
if(x_mid+1<=r) change(x_rc,l,r,y);
update(x);
}
node query(ll x,ll l,ll r){
if(t[x].l>=l&&t[x].r<=r) return t[x];
push_down(x);
if(x_mid>=l&&x_mid+1<=r) return query(x_lc,l,r)+query(x_rc,l,r);
if(x_mid>=l) return query(x_lc,l,r);
return query(x_rc,l,r);
}
}SGT;
ll n,m,cnt;
point f[SIZE];
vector<ll> r[SIZE];
void dfs1(ll x){
f[x].sz=1;
for(ll i=0;i<r[x].size();i++){
ll y=r[x][i];
if(y==f[x].fa) continue;
f[y].fa=x;
f[y].d=f[x].d+1;
dfs1(y);
f[x].sz+=f[y].sz;
if(f[y].sz>f[f[x].son].sz)
f[x].son=y;
}
}
void dfs2(ll x,ll t){
f[x].id=++cnt;
SGT.change(1,f[x].id,f[x].id,f[x].w);
f[x].top=t;
if(f[x].son==0) return;
dfs2(f[x].son,t);
for(ll i=0;i<r[x].size();i++){
ll y=r[x][i];
if(y==f[x].fa) continue;
if(y==f[x].son) continue;
dfs2(y,y);
}
}
void change(ll x,ll y,ll data){
while(f[x].top!=f[y].top){
if(f[f[x].top].d<f[f[y].top].d) swap(x,y);
SGT.change(1,f[f[x].top].id,f[x].id,data);
x=f[f[x].top].fa;
}
if(f[x].d>f[y].d) swap(x,y);
SGT.change(1,f[x].id,f[y].id,data);
}
ll query(ll x,ll y){
ll res=0,addx=0,addy=0;
node left,right,all;
left.data=0;
right.data=0;
while(f[x].top!=f[y].top){
if(f[f[x].top].d>f[f[y].top].d){
addy=0;
node p=SGT.query(1,f[f[x].top].id,f[x].id);
if(left.data==0) left=p;
else left=left+p;
x=f[f[x].top].fa;
}
else{
addx=0;
node p=SGT.query(1,f[f[y].top].id,f[y].id);
if(right.data==0) right=p;
else right=p+right;
y=f[f[y].top].fa;
}
}
if(f[x].id>f[y].id) swap(x,y);
all=left+SGT.query(1,f[x].id,f[y].id)+right;
return all.data;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
SGT.build(1,1,n);
for(ll i=1;i<=n;i++)
cin>>f[i].w;
for(ll i=1;i<n;i++){
ll x,y;
cin>>x>>y;
r[x].push_back(y);
r[y].push_back(x);
}
dfs1(1);
dfs2(1,1);
while(m--){
char op;
ll x,y;
cin>>op>>x>>y;
if(op=='C') {ll z;cin>>z;change(x,y,z);}
if(op=='Q') cout<<query(x,y)<<endl;
}
return 0;
}