#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
int a[N];
vector<int> edge[N];
void add(int u, int v) {
edge[u].push_back(v);
}
int father[N];
int son[N];
int size[N];
int dep[N];
void dfs1(int x) {
size[x] = 1;
for (int i = 0; i < (int)edge[x].size(); ++i) {
int to = edge[x][i];
if (to == father[x]) {
continue;
}
father[to] = x;
dep[to] = dep[x] + 1;
dfs1(to);
size[x] += size[to];
if (size[to] > size[son[x]]) {
son[x] = to;
}
}
}
int top[N];
int id[N], idtot;
void dfs2(int x, int t) {
top[x] = t;
id[x] = ++idtot;
if (son[x]) {
dfs2(son[x], t);
}
for (int i = 0; i < (int)edge[x].size(); ++i) {
int to = edge[x][i];
if (to == father[x] || to == son[x]) {
continue;
}
dfs2(to, to);
}
}
struct Tree {
Tree *ls, *rs;
int left, cnt, right, lazy;
Tree() {
left = cnt = right = lazy = 0;
}
void update(int k) {
left = right = k;
cnt = 0;
}
void merge(Tree t1, Tree t2) {
cnt = t1.cnt + t2.cnt + ((t1.right != t2.left) && t1.right && t2.left);
left = t1.left ? t1.left : t2.left;
right = t2.right ? t2.right : t1.right;
}
} seg[N + N], *root = seg;
int tot;
void build(Tree *t, int l, int r) {
if (l == r) {
return;
}
int mid = (l + r) >> 1;
t->ls = &seg[++tot];
t->rs = &seg[++tot];
build(t->ls, l, mid);
build(t->rs, mid + 1, r);
}
void pushdown(Tree *t) {
if (!t->lazy) {
return;
}
t->ls->update(t->lazy);
t->rs->update(t->lazy);
t->lazy = 0;
}
void change(Tree *t, int l, int r, int x, int y, int k) {
if (x <= l && r <= y) {
t->update(k);
return;
}
pushdown(t);
int mid = (l + r) >> 1;
if (x <= mid) {
change(t->ls, l, mid, x, y, k);
}
if (mid < y) {
change(t->rs, mid + 1, r, x, y, k);
}
t->merge(*t->ls, *t->rs);
}
Tree query(Tree *t, int l, int r, int x, int y) {
if (x <= l && r <= y) {
return *t;
}
pushdown(t);
int mid = (l + r) >> 1;
Tree ans;
if (x <= mid) {
ans.merge(ans, query(t->ls, l, mid, x, y));
}
if (mid < y) {
ans.merge(ans, query(t->rs, mid + 1, r, x, y));
}
return ans;
}
int n;
void treechange(int x, int y, int k) {
while (top[x] != top[y]) {
if (dep[x] < dep[y]) {
swap(x, y);
}
change(root, 1, n, id[top[x]], id[x], k);
x = father[top[x]];
}
if (dep[x] < dep[y]) {
swap(x, y);
}
change(root, 1, n, id[y], id[x], k);
}
int treequery(int x, int y) {
// printf("fuc");
Tree ans1, ans2;
while (top[x] != top[y]) {
// printf("%d %d\n", x, y);
if (dep[x] < dep[y]) {
ans2.merge(query(root, 1, n, id[top[y]], id[y]), ans2);
y = father[top[y]];
}
else {
ans1.merge(query(root, 1, n, id[top[x]], id[x]), ans1);
x = father[top[x]];
}
}
if (dep[x] < dep[y]) {
Tree t = query(root, 1, n, id[x], id[y]);
swap(ans1.left, ans1.right);
t.merge(ans1, t);
t.merge(t, ans2);
return t.cnt;
}
else {
Tree t = query(root, 1, n, id[y], id[x]);
swap(ans2.left, ans2.right);
t.merge(ans1, t);
t.merge(t, ans2);
return t.cnt;
}
}
int main() {
int m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for (int i = 1; i < n; ++i) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
dfs1(1);
dfs2(1, 1);
build(root, 1, n);
for (int i = 1; i <= n; ++i) {
change(root, 1, n, id[i], id[i], a[i]);
}
for (int i = 1; i <= m; ++i) {
char s[5];
int x, y, k;
// printf("%d ", i);
scanf("%s%d%d", s, &x, &y);
// printf("%d %d\n", x, y);
if (s[0] == 'C') {
scanf("%d", &k);
treechange(x, y, k);
}
else {
printf("%d\n", treequery(x, y) + 1);
}
}
}