#include <bits/stdc++.h>
using namespace std;
int A[1 << 21], c[1 << 21], ghussa[1 << 21], bahar[1 << 21], order[1 << 21],
    tym = 0;
long long lazy[1 << 21], tree[1 << 21];
vector<int> graph[100000];
void build(int node, int start, int end) {
  if (start == end) {
    tree[node] = 1LL << c[order[start]];
  } else {
    int mid = (start + end) / 2;
    build(2 * node, start, mid);
    build(2 * node + 1, mid + 1, end);
    tree[node] = tree[2 * node] | tree[2 * node + 1];
  }
}
void updateRange(int node, int start, int end, int l, int r, int val) {
  if (lazy[node] != 0) {
    tree[node] = lazy[node];
    if (start != end) {
      lazy[node * 2] = lazy[node];
      lazy[node * 2 + 1] = lazy[node];
    }
    lazy[node] = 0;
  }
  if (start > end or start > r or end < l) return;
  if (start >= l and end <= r) {
    tree[node] = 1LL << val;
    if (start != end) {
      lazy[node * 2] = tree[node];
      lazy[node * 2 + 1] = tree[node];
    }
    return;
  }
  int mid = (start + end) / 2;
  updateRange(node * 2, start, mid, l, r, val);
  updateRange(node * 2 + 1, mid + 1, end, l, r, val);
  tree[node] = tree[node * 2] | tree[node * 2 + 1];
}
long long queryRange(int node, int start, int end, int l, int r) {
  if (start > end or start > r or end < l) return 0LL;
  if (lazy[node] != 0) {
    tree[node] = lazy[node];
    if (start != end) {
      lazy[node * 2] = lazy[node];
      lazy[node * 2 + 1] = lazy[node];
    }
    lazy[node] = 0;
  }
  if (start >= l and end <= r) return tree[node];
  int mid = (start + end) / 2;
  long long p1 = queryRange(node * 2, start, mid, l, r);
  long long p2 = queryRange(node * 2 + 1, mid + 1, end, l, r);
  return p1 | p2;
}
void dfs(int n, int p) {
  ghussa[n] = tym;
  order[tym] = n;
  tym++;
  for (int i = 0; i < graph[n].size(); i++) {
    if (graph[n][i] != p) dfs(graph[n][i], n);
  }
  bahar[n] = tym - 1;
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%d", &c[i]);
  for (int i = 1; i <= n - 1; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    u--;
    v--;
    graph[u].push_back(v);
    graph[v].push_back(u);
  }
  dfs(0, -1);
  build(1, 0, n - 1);
  while (m--) {
    int tk, vk, ck;
    scanf("%d %d", &tk, &vk);
    if (tk == 1) {
      scanf("%d", &ck);
      vk--;
      updateRange(1, 0, n - 1, ghussa[vk], bahar[vk], ck);
    } else {
      vk--;
      int ans = 0;
      long long res = queryRange(1, 0, n - 1, ghussa[vk], bahar[vk]);
      printf("%d\n", __builtin_popcountll(res));
    }
  }
  return 0;
}
