#include <bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
const int MAXN = 100005;
const int M = 1000;
int n, m, timer, tp, a, b, c, q;
int t_in[MAXN], t_out[MAXN], vall[MAXN], arr[MAXN];
bitset<M> t[4 * MAXN];
bitset<M> bt, pr;
int lazy[4 * MAXN] = {0};
vector<vector<int> > g(MAXN);
void DFS(int, int);
void build(int, int, int);
void update(int, int, int, int, int, int);
void push(int);
void get_prime();
bitset<M> get(int, int, int, int, int);
int main() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) cin >> vall[i], vall[i] % m;
  for (int i = 1; i < n; i++) {
    cin >> a >> b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  DFS(1, 0);
  get_prime();
  build(1, 1, n);
  cin >> q;
  while (q--) {
    cin >> tp;
    if (tp == 1) {
      cin >> a >> b;
      b %= m;
      update(1, 1, n, t_in[a], t_out[a], b);
    } else {
      cin >> a;
      bt = get(1, 1, n, t_in[a], t_out[a]);
      bt = bt & pr;
      cout << bt.count() << endl;
    }
  }
  return 0;
}
void DFS(int f, int p) {
  t_in[f] = ++timer;
  arr[timer] = f;
  for (int i = 0; i < g[f].size(); i++) {
    if (g[f][i] != p) DFS(g[f][i], f);
  }
  t_out[f] = timer;
}
void build(int f, int tl, int tr) {
  if (tl == tr) {
    t[f].set(vall[arr[tl]] % m, 1);
    return;
  }
  int tm = (tl + tr) / 2;
  build(f * 2, tl, tm);
  build(f * 2 + 1, tm + 1, tr);
  t[f] = t[f * 2] | t[f * 2 + 1];
}
void make_shift(int f, int s_val) {
  t[f] = (t[f] >> (m - s_val)) | ((t[f] << (M - m + s_val)) >> (M - m));
}
void push(int f) {
  if (lazy[f] == 0) return;
  lazy[f] %= m;
  lazy[f * 2] += lazy[f];
  lazy[f * 2] %= m;
  lazy[f * 2 + 1] += lazy[f];
  lazy[f * 2 + 1] %= m;
  make_shift(2 * f, lazy[f]);
  make_shift(2 * f + 1, lazy[f]);
  lazy[f] = 0;
}
void update(int f, int tl, int tr, int l, int r, int x) {
  if (l > r) return;
  if (tl == l && tr == r) {
    lazy[f] += x;
    lazy[f] %= m;
    make_shift(f, x);
    return;
  }
  push(f);
  int tm = (tl + tr) / 2;
  update(f * 2, tl, tm, l, min(tm, r), x);
  update(f * 2 + 1, tm + 1, tr, max(tm + 1, l), r, x);
  t[f] = t[f * 2] | t[f * 2 + 1];
}
bitset<M> k;
bitset<M> get(int f, int tl, int tr, int l, int r) {
  if (l > r) return k;
  if (tl == l && tr == r) return t[f];
  int tm = (tl + tr) / 2;
  push(f);
  return get(f * 2, tl, tm, l, min(r, tm)) |
         get(f * 2 + 1, tm + 1, tr, max(l, tm + 1), r);
}
void get_prime() {
  bitset<M> tt;
  for (int i = 2; i < M; i++) {
    if (tt[i]) continue;
    pr[i] = 1;
    for (int j = i * i; j < M; j += i) tt[j] = 1;
  }
}
