#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = (1 << 18) + 5;
const int MAXM = 1005;
bitset<MAXM> STree[MAXN], Prime, mask;
int Lazy[MAXN], a[MAXN], in[MAXN], out[MAXN], time_tag, n, m, H[MAXN];
vector<int> G[MAXN];
void dfs(int i, int fa) {
  in[i] = ++time_tag;
  H[in[i]] = i;
  for (int v : G[i]) {
    if (v == fa) continue;
    dfs(v, i);
  }
  out[i] = time_tag;
}
void init(int k, int l, int r) {
  if (r == l) return;
  if (r - l == 1) {
    STree[k][a[H[l]]] = 1;
    return;
  }
  int m = l + r >> 1;
  init(k << 1, l, m);
  init(k << 1 | 1, m, r);
  STree[k] = STree[k << 1] | STree[k << 1 | 1];
  return;
}
void inline push_down(int k) {
  if (Lazy[k]) {
    (Lazy[k << 1] += Lazy[k]) %= m;
    (Lazy[k << 1 | 1] += Lazy[k]) %= m;
    STree[k << 1] = ((STree[k << 1] << Lazy[k]) & mask) |
                    ((STree[k << 1] >> (m - Lazy[k])) & mask);
    STree[k << 1 | 1] = ((STree[k << 1 | 1] << Lazy[k]) & mask) |
                        ((STree[k << 1 | 1] >> (m - Lazy[k])) & mask);
    Lazy[k] = 0;
  }
}
void inline maintain(int k) {
  STree[k] = STree[k << 1] | STree[k << 1 | 1];
  return;
}
void modify(int k, int l, int r, int ql, int qr, int val) {
  if (ql >= r || qr <= l) return;
  if (ql <= l && r <= qr) {
    (Lazy[k] += val) %= m;
    STree[k] = ((STree[k] << val) & mask) | ((STree[k] >> (m - val)) & mask);
    return;
  }
  push_down(k);
  int m = l + r >> 1;
  modify(k << 1, l, m, ql, qr, val);
  modify(k << 1 | 1, m, r, ql, qr, val);
  maintain(k);
}
bitset<MAXM> query(int k, int l, int r, int ql, int qr) {
  if (ql >= r || qr <= l) return bitset<MAXM>();
  if (ql <= l && r <= qr) return STree[k];
  push_down(k);
  int m = l + r >> 1;
  bitset<MAXM> ret =
      query(k << 1, l, m, ql, qr) | query(k << 1 | 1, m, r, ql, qr);
  maintain(k);
  return ret;
}
int main() {
  Prime = ~Prime;
  Prime[0] = Prime[1] = 0;
  for (int i = (2); i < (1001); i++) {
    if (Prime[i]) {
      for (int j = i + i; j <= 1000; j += i) {
        Prime[j] = 0;
      }
    }
  }
  scanf("%d%d", &n, &m);
  for (int i = (0); i < (m); i++) mask[i] = 1;
  for (int i = (1); i < (n + 1); i++) scanf("%d", a + i), a[i] %= m;
  for (int i = (1); i < (n); i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    G[u].push_back(v), G[v].push_back(u);
  }
  dfs(1, -1);
  init(1, 1, time_tag + 1);
  int q;
  scanf("%d", &q);
  for (int cas = (0); cas < (q); cas++) {
    int op, v, x;
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d%d", &v, &x);
      modify(1, 1, time_tag + 1, in[v], out[v] + 1, x % m);
    } else {
      scanf("%d", &v);
      bitset<MAXM> res = Prime & query(1, 1, time_tag + 1, in[v], out[v] + 1);
      printf("%d\n", res.count());
    }
  }
}
