#include <bits/stdc++.h>
using namespace std;
long long int color[400005], timee = 0, dis[400005], sz[400005], ara[400005],
                             tree[16 * 100005], lazy[16 * 100005];
vector<long long int> ad[400005];
set<long long int> st;
void dfs(long long int src, long long int pre) {
  ++timee;
  sz[src] = 1;
  dis[src] = timee;
  ara[timee] = src;
  for (long long int v : ad[src]) {
    if (v == pre) continue;
    dfs(v, src);
    sz[src] += sz[v];
  }
}
void build(long long int node, long long int b, long long int e) {
  if (b == e) {
    tree[node] = (1LL << color[ara[b]]);
    return;
  }
  long long int mid = (b + e) >> 1;
  long long int Left = node << 1;
  long long int Right = Left + 1;
  build(Left, b, mid);
  build(Right, mid + 1, e);
  tree[node] = tree[Left] | tree[Right];
}
void upd(long long int node, long long int b, long long int e,
         long long int val) {
  tree[node] = (1LL << val);
  lazy[node] = val;
}
void Shift(long long int node, long long int b, long long int e) {
  long long int mid = (b + e) >> 1;
  long long int Left = node << 1;
  long long int Right = Left + 1;
  upd(Left, b, mid, lazy[node]);
  upd(Right, mid + 1, e, lazy[node]);
  lazy[node] = 0;
}
void update(long long int node, long long int b, long long int e,
            long long int i, long long int j, long long int col) {
  if (i > e || j < b) return;
  if (b >= i && e <= j) {
    tree[node] = (1LL << col);
    lazy[node] = col;
    return;
  }
  if (lazy[node]) Shift(node, b, e);
  long long int mid = (b + e) >> 1;
  long long int Left = node << 1;
  long long int Right = Left + 1;
  update(Left, b, mid, i, j, col);
  update(Right, mid + 1, e, i, j, col);
  tree[node] = tree[Left] | tree[Right];
}
long long int query(long long int node, long long int b, long long int e,
                    long long int i, long long int j) {
  if (i > e || j < b) return 0;
  if (b >= i && e <= j) {
    return tree[node];
  }
  if (lazy[node]) Shift(node, b, e);
  long long int mid = (b + e) >> 1;
  long long int Left = node << 1;
  long long int Right = Left + 1;
  long long int p1 = query(Left, b, mid, i, j);
  long long int p2 = query(Right, mid + 1, e, i, j);
  return p1 | p2;
}
int main() {
  long long int n, q, i, j;
  scanf("%I64d %I64d", &n, &q);
  for (i = 1; i <= n; i++) {
    scanf("%I64d", &color[i]);
  }
  for (i = 1; i <= n - 1; i++) {
    long long int u, v;
    scanf("%I64d %I64d", &u, &v);
    ad[u].push_back(v);
    ad[v].push_back(u);
  }
  dfs(1, 0);
  build(1, 1, n);
  for (i = 1; i <= q; i++) {
    long long int ch;
    scanf("%I64d", &ch);
    if (ch == 1) {
      long long int v, val;
      scanf("%I64d %I64d", &v, &val);
      update(1, 1, n, dis[v], dis[v] + sz[v] - 1, val);
    } else {
      long long int val;
      scanf("%I64d", &val);
      long long int ans = query(1, 1, n, dis[val], dis[val] + sz[val] - 1);
      long long int cnt = 0;
      for (j = 1; j <= 60; j++) {
        if (ans & (1LL << j)) {
          cnt++;
        }
      }
      printf("%I64d\n", cnt);
      st.clear();
    }
  }
  return 0;
}
