#include <bits/stdc++.h>
using namespace std;
int w[int(1e5) + 10], id[int(1e5) + 10];
int m;
bitset<1010> primes, aux;
struct segtree {
  bitset<1010> values;
  int start, end, mid, lazy;
  segtree *left, *right;
  segtree(int start, int end) : start(start), end(end) {
    lazy = 0;
    if (start != end) {
      mid = (start + end) / 2;
      left = new segtree(start, mid);
      right = new segtree(mid + 1, end);
      values = left->values | right->values;
    } else {
      left = right = NULL;
      values.reset();
      values[w[id[start]]] = 1;
    }
  }
  void rotate_mask(int x) {
    values = values << x | values >> (m - x);
    values &= aux;
  }
  void propagate() {
    lazy %= m;
    if (lazy) {
      rotate_mask(lazy);
      if (left != right) {
        left->lazy += lazy;
        left->lazy %= m;
        right->lazy += lazy;
        right->lazy %= m;
      }
      lazy = 0;
    }
  }
  void update(int x, int y, int sum) {
    propagate();
    if (x == start && y == end) {
      lazy += sum;
      propagate();
    } else {
      if (y <= mid)
        left->update(x, y, sum);
      else if (x > mid)
        right->update(x, y, sum);
      else
        left->update(x, mid, sum), right->update(mid + 1, y, sum);
      left->propagate();
      right->propagate();
      values = left->values | right->values;
    }
  }
  bitset<1010> query(int x, int y) {
    propagate();
    if (x == start && y == end) return values;
    if (y <= mid)
      return left->query(x, y);
    else if (x > mid)
      return right->query(x, y);
    else
      return left->query(x, mid) | right->query(mid + 1, y);
  }
};
vector<vector<int> > G;
int start[int(1e5) + 10], fin[int(1e5) + 10], n;
void preorder(int u, int p, int &t) {
  id[t] = u;
  start[u] = t++;
  for (int i = 0; i < G[u].size(); i++) {
    int v = G[u][i];
    if (v != p) preorder(v, u, t);
  }
  fin[u] = t - 1;
}
void sieve() {
  primes.set();
  primes[0] = primes[1] = 0;
  for (int i = 2; i <= 1000; i++)
    if (primes[i])
      for (int j = i + i; j <= 1000; j += i) primes[j] = 0;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> w[i], w[i] %= m;
  G = vector<vector<int> >(n);
  int a, b;
  for (int i = 0; i < n - 1; i++) {
    cin >> a >> b;
    a--;
    b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }
  int t = 0;
  preorder(0, -1, t);
  sieve();
  for (int i = m - 1; i >= 0; i--) aux[i] = 1;
  segtree st(0, n - 1);
  int q, op;
  cin >> q;
  while (q--) {
    cin >> op;
    if (op == 1) {
      cin >> a >> b;
      b %= m;
      a--;
      st.update(start[a], fin[a], b);
    } else {
      cin >> a;
      a--;
      cout << int((st.query(start[a], fin[a]) & primes).count()) << "\n";
    }
  }
}
