#include <bits/stdc++.h>
using namespace std;
const int MAX = 4e5 + 9;
int n, m, c[MAX], startRange[MAX], finishRange[MAX];
int l, r, val;
long long lazy[(MAX << 2)], tree[(MAX << 2)];
vector<int> adj[MAX];
vector<int> v;
void dfs(int cur, int par = -1) {
  v.push_back(cur);
  startRange[cur] = (int)v.size() - 1;
  for (int i = 0; i < adj[cur].size(); ++i) {
    int child = adj[cur][i];
    if (child != par) {
      dfs(child, cur);
    }
  }
  finishRange[cur] = (int)v.size() - 1;
}
void build(int low, int high, int pos) {
  if (low == high) {
    tree[pos] |= (1LL << c[v[low]]);
    return;
  }
  int mid = ((low + high) >> 1);
  build(low, mid, (pos << 1));
  build(mid + 1, high, (pos << 1) + 1);
  tree[pos] = (tree[(pos << 1)] | tree[(pos << 1) + 1]);
}
void push(int low, int high, int pos) {
  if (lazy[pos]) {
    tree[pos] = lazy[pos];
    if (low != high) {
      lazy[(pos << 1)] = lazy[pos];
      lazy[(pos << 1) + 1] = lazy[pos];
    }
    lazy[pos] = 0;
  }
}
long long qwr(int low, int high, int pos) {
  push(low, high, pos);
  if (l > high || r < low) {
    return 0;
  }
  if (l <= low && r >= high) {
    return tree[pos];
  }
  int mid = ((low + high) >> 1);
  return (qwr(low, mid, (pos << 1)) | qwr(mid + 1, high, (pos << 1) + 1));
}
void upd(int low, int high, int pos) {
  push(low, high, pos);
  if (l > high || r < low) {
    return;
  }
  if (l <= low && r >= high) {
    tree[pos] = (1LL << val);
    if (low != high) {
      lazy[(pos << 1)] = tree[pos];
      lazy[(pos << 1) + 1] = tree[pos];
    }
    return;
  }
  int mid = ((low + high) >> 1);
  upd(low, mid, (pos << 1));
  upd(mid + 1, high, (pos << 1) + 1);
  tree[pos] = (tree[(pos << 1)] | tree[(pos << 1) + 1]);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> m;
  for (int i = 1; i <= n; ++i) {
    cin >> c[i];
  }
  for (int i = 0; i < n - 1; ++i) {
    int x, y;
    cin >> x >> y;
    adj[x].push_back(y);
    adj[y].push_back(x);
  }
  v.push_back(-1);
  dfs(1);
  build(1, n, 1);
  while (m--) {
    int type;
    cin >> type;
    if (type == 1) {
      int node;
      cin >> node >> val;
      l = startRange[node];
      r = finishRange[node];
      upd(1, n, 1);
    } else {
      int node;
      cin >> node;
      l = startRange[node];
      r = finishRange[node];
      long long res = qwr(1, n, 1);
      cout << __builtin_popcountll(res) << "\n";
    }
  }
  return 0;
}
