// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1000>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void build(int idx,int s,int e) {
    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= (tree[idx]<<v) | (tree[idx]>>(md-v)) ;
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]); lazy[l] = (lazy[l]+lazy[idx]) % md;
    Rotate(r,lazy[idx]); lazy[r] = (lazy[r]+lazy[idx]) % md;
    lazy[idx] = 0;
}

void push_up(int idx,int l,int r)
{
    tree[idx] = (tree[l]|tree[r]);
}

void update(int idx,int s,int e,int x,int y,int v)
{
    if(s==x && e==y)
    {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) update(l,s,mid,x,y,v);
    else if(x>mid) update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask query(int idx,int s,int e,int x,int y)
{
    if( s==x && e==y ) return tree[idx];
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) return query(l,s,mid,x,y);
    else if(x>mid) return query(r,mid+1,e,x,y);
    else
    {
        mask a = query(l,s,mid,x,mid);
        mask b = query(r,mid+1,e,mid+1,y);
        return (a|b);
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime;

void sieve() {
    prime.set();
    for(int i=2; i<1000; i++) {
        for(int j=(i+i); j<1000; j+=i) {
            prime.reset(j);
        }
    }
    prime.reset(0);
    prime.reset(1);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q)
    {
        DI(cmd);

        if(cmd==1)
        {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        }
        else
        {
            DI(x);
            mask res = query(1,1,n,st[x],ed[x]);
            int ret = (res&prime).count();
            PI(ret);
        }

    }

    return 0;
}


// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1001>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void push_up(int idx,int l,int r) {
    tree[idx] = (tree[l]|tree[r]);
}

void build(int idx,int s,int e) {

    tree[idx].reset();

    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= ( (tree[idx]<<v) | (tree[idx]>>(md-v)) );
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]);
    Rotate(r,lazy[idx]);

    lazy[l] = (lazy[l]+lazy[idx]) % md;
    lazy[r] = (lazy[r]+lazy[idx]) % md;

    lazy[idx] = 0;
}

void update(int idx,int s,int e,int x,int y,int v) {

    if(s==x && e==y) {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }

    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);

    if(lazy[idx]) push_down(idx,l,r);

    if(y<=mid)      update(l,s,mid,x,y,v);
    else if(x>mid)  update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask ret;

void query(int idx,int s,int e,int x,int y) {
    if( s==x && e==y ) {
        ret = ( ret | tree[idx] ) ;
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid)      query(l,s,mid,x,y);
    else if(x>mid)  query(r,mid+1,e,x,y);
    else {
        query(l,s,mid,x,mid);
        query(r,mid+1,e,mid+1,y);
        return;
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime;

void sieve() {
    prime.set();
    for(int i=2; i<1000; i++) {
        if( prime[i] )
        for(int j=(i+i); j<1000; j+=i) {
            prime.reset(j);
        }
    }
    prime.reset(0);
    prime.reset(1);
    prime.reset(1000);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q) {
        DI(cmd);
        if(cmd==1) {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        } else {
            DI(x);
            ret.reset();
            query(1,1,n,st[x],ed[x]);
            int cnt = (ret&prime).count();
            PI(cnt);
        }
    }

    return 0;
}


// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1001>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void build(int idx,int s,int e) {
    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= (tree[idx]<<v) | (tree[idx]>>(md-v)) ;
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]); lazy[l] = (lazy[l]+lazy[idx]) % md;
    Rotate(r,lazy[idx]); lazy[r] = (lazy[r]+lazy[idx]) % md;
    lazy[idx] = 0;
}

void push_up(int idx,int l,int r)
{
    tree[idx] = (tree[l]|tree[r]);
}

void update(int idx,int s,int e,int x,int y,int v)
{
    if(s==x && e==y)
    {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) update(l,s,mid,x,y,v);
    else if(x>mid) update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask query(int idx,int s,int e,int x,int y)
{
    if( s==x && e==y ) return tree[idx];
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) return query(l,s,mid,x,y);
    else if(x>mid) return query(r,mid+1,e,x,y);
    else
    {
        mask a = query(l,s,mid,x,mid);
        mask b = query(r,mid+1,e,mid+1,y);
        return (a|b);
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime;

void sieve() {
    prime.set();
    for(int i=2; i<1000; i++) {
        if( prime[i] )
        for(int j=(i+i); j<1000; j+=i) {
            prime.reset(j);
        }
    }
    prime.reset(0);
    prime.reset(1);
    prime.reset(1000);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q)
    {
        DI(cmd);

        if(cmd==1)
        {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        }
        else
        {
            DI(x);
            mask res = query(1,1,n,st[x],ed[x]);
            int ret = (res&prime).count();
            PI(ret);
        }

    }

    return 0;
}


// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1001>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void push_up(int idx,int l,int r) {
    tree[idx] = (tree[l]|tree[r]);
}

void build(int idx,int s,int e) {

//    tree[idx].reset();

    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= ( (tree[idx]<<v) | (tree[idx]>>(md-v)) );
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]);
    Rotate(r,lazy[idx]);

    lazy[l] = (lazy[l]+lazy[idx]) % md;
    lazy[r] = (lazy[r]+lazy[idx]) % md;

    lazy[idx] = 0;
}

void update(int idx,int s,int e,int x,int y,int v) {

    if(s==x && e==y) {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }

    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);

    if(lazy[idx]) push_down(idx,l,r);

    if(y<=mid)      update(l,s,mid,x,y,v);
    else if(x>mid)  update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask ret;

void query(int idx,int s,int e,int x,int y) {
    if( s==x && e==y ) {
        ret = ( ret | tree[idx] ) ;
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid)      query(l,s,mid,x,y);
    else if(x>mid)  query(r,mid+1,e,x,y);
    else {
        query(l,s,mid,x,mid);
        query(r,mid+1,e,mid+1,y);
        return;
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime;

void sieve() {
    prime.set();
    for(int i=2; i<1000; i++) {
        if( prime[i] )
        for(int j=(i+i); j<1000; j+=i) {
            prime.reset(j);
        }
    }
    prime.reset(0);
    prime.reset(1);
    rep(i,md,1000) prime.reset(i);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q) {
        DI(cmd);
        if(cmd==1) {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        } else {
            DI(x);
            ret.reset();
            query(1,1,n,st[x],ed[x]);
            int cnt = (ret&prime).count();
            PI(cnt);
        }
    }

    return 0;
}


// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1001>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void build(int idx,int s,int e) {
    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= (tree[idx]<<v) | (tree[idx]>>(md-v)) ;
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]); lazy[l] = (lazy[l]+lazy[idx]) % md;
    Rotate(r,lazy[idx]); lazy[r] = (lazy[r]+lazy[idx]) % md;
    lazy[idx] = 0;
}

void push_up(int idx,int l,int r)
{
    tree[idx] = (tree[l]|tree[r]);
}

void update(int idx,int s,int e,int x,int y,int v)
{
    if(s==x && e==y)
    {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) update(l,s,mid,x,y,v);
    else if(x>mid) update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask query(int idx,int s,int e,int x,int y)
{
    if( s==x && e==y ) return tree[idx];
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) return query(l,s,mid,x,y);
    else if(x>mid) return query(r,mid+1,e,x,y);
    else
    {
        mask a = query(l,s,mid,x,mid);
        mask b = query(r,mid+1,e,mid+1,y);
        return (a|b);
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime;

void sieve() {
    prime.set();
    for(int i=2; i<1000; i++) {
        for(int j=(i+i); j<1000; j+=i) {
            prime.reset(j);
        }
    }
    prime.reset(0);
    prime.reset(1);
    prime.reset(1000);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q)
    {
        DI(cmd);

        if(cmd==1)
        {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        }
        else
        {
            DI(x);
            mask res = query(1,1,n,st[x],ed[x]);
            int ret = (res&prime).count();
            PI(ret);
        }

    }

    return 0;
}


// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1001>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void build(int idx,int s,int e) {
    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= (tree[idx]<<v) | (tree[idx]>>(md-v)) ;
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]); lazy[l] = (lazy[l]+lazy[idx]) % md;
    Rotate(r,lazy[idx]); lazy[r] = (lazy[r]+lazy[idx]) % md;
    lazy[idx] = 0;
}

void push_up(int idx,int l,int r)
{
    tree[idx] = (tree[l]|tree[r]);
}

void update(int idx,int s,int e,int x,int y,int v)
{
    if(s==x && e==y)
    {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) update(l,s,mid,x,y,v);
    else if(x>mid) update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask query(int idx,int s,int e,int x,int y)
{
    if( s==x && e==y ) return tree[idx];
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid) return query(l,s,mid,x,y);
    else if(x>mid) return query(r,mid+1,e,x,y);
    else
    {
        mask a = query(l,s,mid,x,mid);
        mask b = query(r,mid+1,e,mid+1,y);
        return (a|b);
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime;

void sieve() {
    prime.set();
    for(int i=2; i<1000; i++) {
        for(int j=(i+i); j<1000; j+=i) {
            prime.reset(j);
        }
    }
    prime.reset(0);
    prime.reset(1);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q)
    {
        DI(cmd);

        if(cmd==1)
        {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        }
        else
        {
            DI(x);
            mask res = query(1,1,n,st[x],ed[x]);
            int ret = (res&prime).count();
            PI(ret);
        }

    }

    return 0;
}


// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1001>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void push_up(int idx,int l,int r) {
    tree[idx] = (tree[l]|tree[r]);
}

void build(int idx,int s,int e) {

    tree[idx].reset();

    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= ( (tree[idx]<<v) | (tree[idx]>>(md-v)) );
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]);
    Rotate(r,lazy[idx]);

    lazy[l] = (lazy[l]+lazy[idx]) % md;
    lazy[r] = (lazy[r]+lazy[idx]) % md;

    lazy[idx] = 0;
}

void update(int idx,int s,int e,int x,int y,int v) {

    if(s==x && e==y) {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }

    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);

    if(lazy[idx]) push_down(idx,l,r);

    if(y<=mid)      update(l,s,mid,x,y,v);
    else if(x>mid)  update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask ret;

void query(int idx,int s,int e,int x,int y) {
    if( s==x && e==y ) {
        ret = ( ret | tree[idx] ) ;
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid)      query(l,s,mid,x,y);
    else if(x>mid)  query(r,mid+1,e,x,y);
    else {
        query(l,s,mid,x,mid);
        query(r,mid+1,e,mid+1,y);
        return;
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime;

void sieve() {
    prime.set();
    for(int i=2; i<md; i++) {
        if( prime[i] )
        for(int j=(i+i); j<md; j+=i) {
            prime.reset(j);
        }
    }
    prime.reset(0);
    prime.reset(1);
    prime.reset(1000);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q) {
        DI(cmd);
        if(cmd==1) {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        } else {
            DI(x);
            ret.reset();
            query(1,1,n,st[x],ed[x]);
            int cnt = (ret&prime).count();
            PI(cnt);
        }
    }

    return 0;
}


// ==========================================================================
//
//                Starting by the name of Almighty Allah
//
// ==========================================================================

#include<bits/stdc++.h>

#include <algorithm>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iostream>
#include <fstream>
#include <numeric>
#include <string>
#include <vector>
#include <cstring>
#include <map>
#include <iterator>
#include <deque>
#include <climits>
#include <complex>
#include <bitset>

using namespace std;

#define LL                          long long
#define ULL                         unsigned long long

// I/O
#define I(X)                        scanf("%d",     &(X))
#define II(X, Y)                    scanf("%d%d",   &(X), &(Y))
#define III(X, Y, Z)                scanf("%d%d%d", &(X), &(Y), &(Z))

#define IL(X)                       scanf("%lld", &X)
#define IIL(X,Y )                   scanf("%lld%lld", &X,&Y)
#define IIIL(X,Y,Z)                 scanf("%lld%lld%lld", &X,&Y,&Z)

#define ID(x)                       scanf("%lf",&x)
#define IID(x,y)                    scanf("%lf%lf",&x,&y)
#define IIID(x,y,z)                 scanf("%lf%lf%lf",&x,&y,&z)

#define DI(X)         int X;        I(X);
#define DII(X, Y)     int X, Y;     II(X,Y)
#define DIII(X, Y, Z) int X, Y, Z;  III(X,Y,Z);

#define DIL(X)        LL X;         IL(X)
#define DIIL(X,Y)     LL X,Y;       IIL(X,Y)
#define DIIIL(X,Y,Z)  LL X,Y,Z;     IIIL(X,Y,Z)

#define DDI(x)        double x;     ID(x);
#define DDII(x,y)     double x,y;   IID(x,y);
#define DDDII(x,y,z)  double x,y,z; IIID(x,y,z);

#define SS(s)                       scanf("%s",s)

#define PI(x)                       printf("%d\n",      x)
#define PII(x,y)                    printf("%d %d\n",   x,y)
#define PIII(x,y,z)                 printf("%d %d %d\n",x,y,z)

#define PIL(x)                      printf("%lld\n",          x)
#define PIIL(x,y)                   printf("%lld %lld\n",     x,y)
#define PIIIL(x,y,z)                printf("%lld %lld %lld\n",x,y,z)

// LOOP
#define rep(i,a,b)                  for(int i=a;i<=b;i++)
#define rev(i,a,b)                  for(int i=a;i>=b;i--)
#define repv(i,a)                   for(int i=0;i<(int)a.size();i++)
#define revv(i,a)                   for(int i=((int)a.size())-1;i>=0;i--)

#define FS(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++)
#define PR(x)                       for(typeof (x.begin()) it = x.begin(); it != x.end (); it++) {  cout << *it << " "; } cout << endl;

// array initialization
#define MEM(a,val)                  memset(a,val,sizeof(a));
#define SET(a)                      memset(a,-1,sizeof a)
#define CLR(a)                      memset(a,0,sizeof a)

// min-max
#define Max(a,b)                    (a>b?a:b)
#define Min(a,b)                    (a<b?a:b)
#define _Max(a,b,c)                 Max(a,Max(b,c))
#define _Min(a,b,c)                 Min(a,Min(b,c))
#define MAX(a)                      (*max_element(all(a)))
#define MIN(a)                      (*min_element(all(a)))

#define FastMax(x,y)                ((((y-x)>>(32-1))&(x^y))^y)
#define FastMin(x,y)                ((((y-x)>>(32-1))&(x^y))^x)

#define SQR(n)          ((n)*(n))

#define all(a)          a.begin(),a.end()
#define PB              push_back
#define NL              puts("");
#define pline           cout << "_________________________" << endl;
// pair
#define XX              first
#define YY              second
// binary search
#define LB(a,x)         (lower_bound(all(a),x)-a.begin())
#define UB(a,x)         (upper_bound(all(a),x)-a.begin())

//#define SI(X)           X=in<int>()
//#define SII(X,Y)        X=in<int>(),Y=in<int>()
//#define SIII(X,Y,Z)     X=in<int>(),Y=in<int>(),Z=in<int>()
//
//#define SL(X)           X=in<LL>()
//#define SLL(X,Y)        X=in<LL>(),Y=in<LL>()
//#define SLLL(X,Y,Z)     X=in<LL>(),Y=in<LL>(),Z=in<LL>()

//#define SEG             int mid=(s+e)>>1,l=(idx<<1),r=(l|1);
#define in(l,x,r)       ( l<=x && x<=r )

// Bit-op
#define countbit(x)     __builtin_popcount(x)
template< class T, class X > inline bool checkbit(T a, X pos) { T t=1;return ((a&(t<<pos))>0);  }
template< class T, class X > inline T      setbit(T a, X pos) { T t=1;return (a|(t<<pos));      }
template< class T, class X > inline T    resetbit(T a, X pos) { T t=1;return (a&(~(t<<pos)));   }
template< class T, class X > inline T   togglebit(T a, X pos) { T t=1;return (a^(t<<pos));      }
// mathematics
template<typename T> T POW(T base,T power)              { T ret=1; while(power)  { if(power & 1) ret=(ret*base); base=(base*base);  power>>=1; }return ret; }
template<typename T> T PPOW(T B,T P)                    { if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T> T Bigmod(T base,T power,T mod)     { T ret=1; while(power)  { if(power & 1) ret=(ret*base)%mod; base=(base*base)%mod;  power>>=1; }return ret; }
template<typename T> T ModInverse(T number,T mod)       { return Bigmod(number,mod-2,mod); }
template<typename T> T GCD(T a,T b)                     { if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<typename T> T LCM(T a,T b)                     { if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/GCD(a,b));}
template<typename T> T EUCLIDE(T a,T b,T &x,T &y)       { if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}
template<typename T> T ABS(T a)                         { if(a<0)return -a;else return a;}
// geometry
template<typename T> double DIS(T x1,T y1,T x2, T y2)   { return sqrt( (double)( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );}
template<typename T> T ANGLE(T x1,T y1,T x2, T y2)      { return atan( double(y1-y2) / double(x1-x2));}
template<typename T> LL isLeft(T a,T b,T c)             { return (c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y); }
// Degree and Radian
//double DEG(double x) { return (180.0*x)/(M_PI*1.0);}
//double RAD(double x) { return (x*(M_PI*1.0))/(180.0);}

// debug
void P_ARR(int *ar,int a,int b) {  if(a>b) swap(a,b); if(a<=b) cout << ar[a]; for(int i=a+1;i<=b;i++) cout << " "<<ar[i];  cout << endl; }
template<typename T> T In(){ char ch; T n = 0; bool ng = false; while (1) { ch = getchar(); if (ch == '-') { ng = true; ch = getchar(); break;} if (ch>='0' && ch<='9') break; }    while (1) { n = n*10 + (ch - '0'); ch = getchar(); if (ch<'0' || ch>'9')   break;    }  return (ng?-n:n);  }

//int month[]={31,28,31,30,31,30,31,31,30,31,30,31};                                    /// month
//int dir[5][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1} };                                  /// 4 Direction
//int dir[9][2] = { {0,0},{1,0},{0,1},{-1,0},{0,-1},{-1,1},{-1,-1},{1,-1},{1,1}};       /// 8 direction
//int dir[9][2] = { {0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1} };    /// Knight Direction
//int dir[8][2] = { {0,0},{2,0},{1,1},{-1,1} ,{-2,0} , {-1,-1} ,{1,-1} };               /// Hexagonal Direction
// dir[][0] = x value, dir[][1] = y value

/// ======================================================================================================
#define  debug  0
#define  AA     if(debug)
#define  eps     (1e-7)
#define  pi      (2.0*acos(0.0)) //#define PI acos(-1.0)
// IO
#define  READ   freopen("C:\\Users\\shaheen\\Desktop\\input.txt","r",stdin)
#define  WRITE  freopen("C:\\Users\\shaheen\\Desktop\\output.txt","w",stdout)
#define  _cin   ios_base::sync_with_stdio(0); cin.tie(0);
#define  F      fflush(stdout)
#define  FF     cout << flush
//              0123456789
#define  MX     400007
#define  MOD    1000000007LL
#define  inf    1000000000

#define  mask    bitset<1001>

mask tree[MX];
int ar[MX];
int st[MX],ed[MX];
vector<int>adj[MX];
int id[MX];
int cl;

void push_up(int idx,int l,int r) {
    tree[idx] = (tree[l]|tree[r]);
}

void build(int idx,int s,int e) {

    tree[idx].reset();

    if(s==e) {
        tree[idx].set(ar[ id[s] ]);
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    build(l,s,mid);
    build(r,mid+1,e);
    tree[idx] = (tree[l]|tree[r]);
}

int lazy[MX];
int md;

void Rotate(int idx,int v)
{
    tree[idx]= ( (tree[idx]<<v) | (tree[idx]>>(md-v)) );
}

void push_down(int idx,int l,int r)
{
    Rotate(l,lazy[idx]);
    Rotate(r,lazy[idx]);

    lazy[l] = (lazy[l]+lazy[idx]) % md;
    lazy[r] = (lazy[r]+lazy[idx]) % md;

    lazy[idx] = 0;
}

void update(int idx,int s,int e,int x,int y,int v) {

    if(s==x && e==y) {
        lazy[idx]=(lazy[idx]+v)%md;
        Rotate(idx,v);
        return;
    }

    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);

    if(lazy[idx]) push_down(idx,l,r);

    if(y<=mid)      update(l,s,mid,x,y,v);
    else if(x>mid)  update(r,mid+1,e,x,y,v);
    else {
        update(l,s,mid,x,mid,v);
        update(r,mid+1,e,mid+1,y,v);
    }

    push_up(idx,l,r);
}

mask ret;

void query(int idx,int s,int e,int x,int y) {
    if( s==x && e==y ) {
        ret = ( ret | tree[idx] ) ;
        return;
    }
    int mid = (s+e)>>1 , l = (idx<<1) , r = (l|1);
    if(lazy[idx]) push_down(idx,l,r);
    if(y<=mid)      query(l,s,mid,x,y);
    else if(x>mid)  query(r,mid+1,e,x,y);
    else {
        query(l,s,mid,x,mid);
        query(r,mid+1,e,mid+1,y);
        return;
    }
}

void dfs(int u,int papa)
{
    st[u]  = ++cl;
    id[cl] = u;
    repv(i,adj[u]){
        int v = adj[u][i];
        if(v==papa) continue;
        dfs(v,u);
    }
    ed[u] = cl;
}

mask prime,prm;

void sieve() {
    prm.set();
    for(int i=2; i<md; i++) {
        if( prm[i] )
        for(int j=(i+i); j<md; j+=i) {
            prm.reset(j);
        }
    }
    prime.reset();
    rep(i,2,md-1) if( prm[i] ) prime.set(i);
}

int main()
{
    DI(n);
    I(md);

    rep(i,1,n) {
        I(ar[i]);
        ar[i]%=md;
    }

    rep(i,1,n-1){
        DII(x,y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs(1,0);

    build(1,1,n);

    sieve();

    DI(q);

    rep(qq,1,q) {
        DI(cmd);
        if(cmd==1) {
            DII(x,v);
            v%=md;
            update(1,1,n,st[x],ed[x],v);
        } else {
            DI(x);
            ret.reset();
            query(1,1,n,st[x],ed[x]);
            int cnt = (ret&prime).count();
            PI(cnt);
        }
    }

    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define For(i,l,r) for (int i = l; i <= r; ++i)
#define Cor(i,l,r) for (int i = l; i >= r; --i)
#define next __next__

const int MaxN = 222222;
int v[MaxN], next[MaxN], h[MaxN], tot;
void add(int b, int e) {
	v[++tot] = e; next[tot] = h[b]; h[b] = tot;
	v[++tot] = b; next[tot] = h[e]; h[e] = tot;
}

int id = 0;
int vis[MaxN], L[MaxN], R[MaxN], seq[MaxN], A[MaxN];
void dfs(int x) {
	vis[x] = true;
	seq[L[x] = ++id] = x;
	for (int z = h[x]; z; z = next[z]) if (!vis[v[z]]) {
		dfs(v[z]);
	}
	R[x] = id;
}

const int B = 62;
int BLK = 0;
int MOD;

struct TData {
	long long Mask[22];
	TData() {}
	void clear() { memset(Mask, 0, sizeof Mask); }
	void set(int x, long long val) {
		long long &S = Mask[x / B];
		x %= B;
		if (S >> x & 1) S -= 1LL << x;
		S |= val << x;
	}
	int get(int x) {
		return Mask[x / B] >> (x % B) & 1;
	}
	TData operator + (const TData &b) const {
		TData ret;
		memcpy(ret.Mask, Mask, sizeof Mask);
		For(i,0,BLK) ret.Mask[i] |= b.Mask[i];
		return ret;
	}
	TData move(int offset) {
		offset %= MOD;
		TData ret; ret.clear();
		for (int i = 0; i < MOD;) {
			int t = (i + offset) % MOD;
			int nxt_i = min(MOD - 1, i / B * B + B - 1);
			int nxt_t = min(MOD - 1, t / B * B + B - 1);
			int inc = min(nxt_i - i, nxt_t - t) + 1;
			ret.Mask[t / B] |= (Mask[i / B] >> i % B & ((1LL << inc) - 1)) << (t % B);
			i += inc;
		}
		return ret;
	}
};

struct SegTreeNode {
	int l, r, offset;
	TData info;
	SegTreeNode() {}
	void init(int _l, int _r, int _val) {
		l = _l, r = _r;
		info.clear();
		info.set(_val % MOD, 1);
		offset = 0;
	}
	void make_add(int c) {
		(offset += c) %= MOD;
		info = info.move(c % MOD);
	}
}T[MaxN * 2];

struct SegmentTree {
	void push(int t) {
		if (T[t].offset) {
			if (T[t].l == T[t].r) return ;
			T[t + t].make_add(T[t].offset);
			T[t + t + 1].make_add(T[t].offset);
			T[t].offset = 0;
		}
	}
	void update(int t) {
		if (T[t].l == T[t].r) return ;
		T[t].info = T[t + t].info + T[t + t + 1].info;
	}
	void modify(int t, int l, int r, int val) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			T[t].make_add(val);
			return ;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		if (l <= mid) modify(t + t, l, r, val);
		if (r > mid) modify(t + t + 1, l, r, val);
		update(t);
	}
	TData ask(int t, int l, int r) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			return T[t].info;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		TData ret; ret.clear();
		if (l <= mid) ret = ret + ask(t + t, l, r);
		if (r > mid) ret = ret + ask(t + t + 1, l, r);
		update(t);
		return ret;
	}
	void build(int t, int l, int r, int *seq) {
		T[t].init(l, r, A[seq[l]]);
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build(t + t, l, mid, seq);
		build(t + t + 1, mid + 1, r, seq);
		update(t);
	}
}Tab;

int arr[MaxN], appear[1111];

int n, Q;
int main() {
	cin >> n >> MOD;
	vector<int> primes;
	For(i,2,MOD - 1) {
		bool valid = true;
		For(j,2,i - 1) if (i % j == 0) valid = false ;
		if (valid) primes.push_back(i);
	}

	BLK = (MOD + B - 1) / B;

	For(i,1,n) scanf("%d", &A[i]);
	For(i,1,n - 1) {
		int b, e;
		scanf("%d%d", &b, &e);
		add(b, e);
	}

	dfs(1);

	Tab.build(1, 1, n, seq);

	For(i,1,n) arr[i] = A[seq[i]] % MOD;

	cin >> Q;
	For(i,1,Q) {
		int op, v, x;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &v, &x);
			Tab.modify(1, L[v], R[v], x);

			//For(j,L[v],R[v]) {
			//	arr[j] += x;
			//	arr[j] %= MOD;
			//}
		}
		if (op == 2) {
			scanf("%d", &v);
			TData ans = Tab.ask(1, L[v], R[v]);
			int num = 0;
			for (auto cand : primes) if (ans.get(cand) == 1) ++num;
			printf("%d\n", num);

			//memset(appear, 0, sizeof appear);
			//For(j,L[v],R[v]) appear[arr[j]] = true;
			//for (auto cand : primes) if (appear[cand]) --num;

			//assert(num == 0);

		}
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define For(i,l,r) for (int i = l; i <= r; ++i)
#define Cor(i,l,r) for (int i = l; i >= r; --i)
#define next __next__

const int MaxN = 222222;
int v[MaxN], next[MaxN], h[MaxN], tot;
void add(int b, int e) {
	v[++tot] = e; next[tot] = h[b]; h[b] = tot;
	v[++tot] = b; next[tot] = h[e]; h[e] = tot;
}

int id = 0;
int vis[MaxN], L[MaxN], R[MaxN], seq[MaxN], A[MaxN];
void dfs(int x) {
	vis[x] = true;
	seq[L[x] = ++id] = x;
	for (int z = h[x]; z; z = next[z]) if (!vis[v[z]]) {
		dfs(v[z]);
	}
	R[x] = id;
}

const int B = 62;
int BLK = 0;
int MOD;

struct TData {
	long long Mask[22];
	TData() {}
	void clear() { memset(Mask, 0, sizeof Mask); }
	void set(int x, long long val) {
		long long &S = Mask[x / B];
		x %= B;
		if (S >> x & 1) S -= 1LL << x;
		S |= val << x;
	}
	int get(int x) {
		return Mask[x / B] >> (x % B) & 1;
	}
	TData operator + (const TData &b) const {
		TData ret;
		memcpy(ret.Mask, Mask, sizeof Mask);
		For(i,0,BLK) ret.Mask[i] |= b.Mask[i];
		return ret;
	}
	TData move(int offset) {
		offset %= MOD;
		TData ret; ret.clear();
		for (int i = 0; i < MOD;) {
			int t = (i + offset) % MOD;
			int nxt_i = min(MOD - 1, i / B * B + B - 1);
			int nxt_t = min(MOD - 1, t / B * B + B - 1);
			int inc = min(nxt_i - i, nxt_t - t) + 1;
			ret.Mask[t / B] |= (Mask[i / B] >> i % B & ((1LL << inc) - 1)) << (t % B);
			i += inc;
		}
		return ret;
	}
};

struct SegTreeNode {
	int l, r, offset;
	TData info;
	SegTreeNode() {}
	void init(int _l, int _r, int _val) {
		l = _l, r = _r;
		info.clear();
		info.set(_val % MOD, 1);
		offset = 0;
	}
	void make_add(int c) {
		(offset += c) %= MOD;
		info = info.move(c % MOD);
	}
}T[MaxN * 2];

struct SegmentTree {
	void push(int t) {
		if (T[t].offset) {
			if (T[t].l == T[t].r) return ;
			T[t + t].make_add(T[t].offset);
			T[t + t + 1].make_add(T[t].offset);
			T[t].offset = 0;
		}
	}
	void update(int t) {
		if (T[t].l == T[t].r) return ;
		T[t].info = T[t + t].info + T[t + t + 1].info;
	}
	void modify(int t, int l, int r, int val) {
		if (l <= T[t].l && T[t].r <= r) {
			T[t].make_add(val);
			return ;
		}
		push(t);
		int mid = (T[t].l + T[t].r) >> 1;
		if (l <= mid) modify(t + t, l, r, val);
		if (r > mid) modify(t + t + 1, l, r, val);
		update(t);
	}
	TData ask(int t, int l, int r) {
		if (l <= T[t].l && T[t].r <= r) {
			return T[t].info;
		}
		push(t);
		int mid = (T[t].l + T[t].r) >> 1;
		TData ret; ret.clear();
		if (l <= mid) ret = ret + ask(t + t, l, r);
		if (r > mid) ret = ret + ask(t + t + 1, l, r);
		update(t);
		return ret;
	}
	void build(int t, int l, int r, int *seq) {
		T[t].init(l, r, A[seq[l]]);
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build(t + t, l, mid, seq);
		build(t + t + 1, mid + 1, r, seq);
		update(t);
	}
}Tab;

int arr[MaxN], appear[1111];

int n, Q;
int main() {
	cin >> n >> MOD;
	vector<int> primes;
	For(i,2,MOD - 1) {
		bool valid = true;
		For(j,2,i - 1) if (i % j == 0) valid = false ;
		if (valid) primes.push_back(i);
	}

	BLK = (MOD + B - 1) / B;

	For(i,1,n) scanf("%d", &A[i]);
	For(i,1,n - 1) {
		int b, e;
		scanf("%d%d", &b, &e);
		add(b, e);
	}

	dfs(1);

	Tab.build(1, 1, n, seq);

	For(i,1,n) arr[i] = A[seq[i]] % MOD;

	cin >> Q;
	For(i,1,Q) {
		int op, v, x;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &v, &x);
			Tab.modify(1, L[v], R[v], x);

			For(j,L[v],R[v]) {
				arr[j] += x;
				arr[j] %= MOD;
			}
		}
		if (op == 2) {
			scanf("%d", &v);
			TData ans = Tab.ask(1, L[v], R[v]);
			int num = 0;
			for (auto cand : primes) if (ans.get(cand) == 1) ++num;
			printf("%d\n", num);

			memset(appear, 0, sizeof appear);
			For(j,L[v],R[v]) appear[arr[j]] = true;
			for (auto cand : primes) if (appear[cand]) --num;

			assert(num == 0);

		}
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define For(i,l,r) for (int i = l; i <= r; ++i)
#define Cor(i,l,r) for (int i = l; i >= r; --i)
#define next __next__

const int MaxN = 222222;
int v[MaxN], next[MaxN], h[MaxN], tot;
void add(int b, int e) {
	v[++tot] = e; next[tot] = h[b]; h[b] = tot;
	v[++tot] = b; next[tot] = h[e]; h[e] = tot;
}

int id = 0;
int vis[MaxN], L[MaxN], R[MaxN], seq[MaxN], A[MaxN];
void dfs(int x) {
	vis[x] = true;
	seq[L[x] = ++id] = x;
	for (int z = h[x]; z; z = next[z]) if (!vis[v[z]]) {
		dfs(v[z]);
	}
	R[x] = id;
}

const int B = 62;
int BLK = 0;
int MOD;

struct TData {
	long long Mask[22];
	TData() {}
	void clear() { memset(Mask, 0, sizeof Mask); }
	void set(int x, long long val) {
		long long &S = Mask[x / B];
		x %= B;
		if (S >> x & 1) S -= 1LL << x;
		S |= val << x;
	}
	int get(int x) {
		return Mask[x / B] >> (x % B) & 1;
	}
	TData operator + (const TData &b) const {
		TData ret;
		memcpy(ret.Mask, Mask, sizeof Mask);
		For(i,0,BLK) ret.Mask[i] |= b.Mask[i];
		return ret;
	}
	TData move(int offset) {
		offset %= MOD;
		TData ret; ret.clear();
		for (int i = 0; i < MOD;) {
			int t = (i + offset) % MOD;
			int nxt_i = min(MOD - 1, i / B * B + B - 1);
			int nxt_t = min(MOD - 1, t / B * B + B - 1);
			int inc = min(nxt_i - i, nxt_t - t) + 1;
			ret.Mask[t / B] |= (Mask[i / B] >> i % B & ((1LL << inc) - 1)) << (t % B);
			i += inc;
		}
		return ret;
	}
};

struct SegTreeNode {
	int l, r, offset;
	TData info;
	SegTreeNode() {}
	void init(int _l, int _r, int _val) {
		l = _l, r = _r;
		info.clear();
		info.set(_val % MOD, 1);
		offset = 0;
	}
	void make_add(int c) {
		(offset += c) %= MOD;
		info = info.move(c % MOD);
	}
}T[MaxN * 2];

struct SegmentTree {
	void push(int t) {
		if (T[t].offset) {
			if (T[t].l == T[t].r) return ;
			T[t + t].make_add(T[t].offset);
			T[t + t + 1].make_add(T[t].offset);
			T[t].offset = 0;
		}
	}
	void update(int t) {
		if (T[t].l == T[t].r) return ;
		T[t].info = T[t + t].info + T[t + t + 1].info;
	}
	void modify(int t, int l, int r, int val) {
		if (l <= T[t].l && T[t].r <= r) {
			T[t].make_add(val);
			return ;
		}
		push(t);
		int mid = (T[t].l + T[t].r) >> 1;
		if (l <= mid) modify(t + t, l, r, val);
		if (r > mid) modify(t + t + 1, l, r, val);
		update(t);
	}
	TData ask(int t, int l, int r) {
		if (l <= T[t].l && T[t].r <= r) {
			return T[t].info;
		}
		push(t);
		int mid = (T[t].l + T[t].r) >> 1;
		TData ret; ret.clear();
		if (l <= mid) ret = ret + ask(t + t, l, r);
		if (r > mid) ret = ret + ask(t + t + 1, l, r);
		update(t);
		return ret;
	}
	void build(int t, int l, int r, int *seq) {
		T[t].init(l, r, A[seq[l]]);
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build(t + t, l, mid, seq);
		build(t + t + 1, mid + 1, r, seq);
		update(t);
	}
}Tab;

int arr[MaxN], appear[1111];

int n, Q;
int main() {
	cin >> n >> MOD;
	vector<int> primes;
	For(i,2,MOD - 1) {
		bool valid = true;
		For(j,2,i - 1) if (i % j == 0) valid = false ;
		if (valid) primes.push_back(i);
	}

	BLK = (MOD + B - 1) / B;

	For(i,1,n) scanf("%d", &A[i]);
	For(i,1,n - 1) {
		int b, e;
		scanf("%d%d", &b, &e);
		add(b, e);
	}

	dfs(1);

	Tab.build(1, 1, n, seq);

	For(i,1,n) arr[i] = A[seq[i]] % MOD;

	cin >> Q;
	For(i,1,Q) {
		int op, v, x;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &v, &x);
			Tab.modify(1, L[v], R[v], x);

			//For(j,L[v],R[v]) {
			//	arr[j] += x;
			//	arr[j] %= MOD;
			//}
		}
		if (op == 2) {
			scanf("%d", &v);
			TData ans = Tab.ask(1, L[v], R[v]);
			int num = 0;
			for (auto cand : primes) if (ans.get(cand) == 1) ++num;
			printf("%d\n", num);

			//memset(appear, 0, sizeof appear);
			//For(j,L[v],R[v]) appear[arr[j]] = true;
			//for (auto cand : primes) if (appear[cand]) --num;

			//assert(num == 0);

		}
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define For(i,l,r) for (int i = l; i <= r; ++i)
#define Cor(i,l,r) for (int i = l; i >= r; --i)
#define next __next__

const int MaxN = 222222;
int v[MaxN], next[MaxN], h[MaxN], tot;
void add(int b, int e) {
	v[++tot] = e; next[tot] = h[b]; h[b] = tot;
	v[++tot] = b; next[tot] = h[e]; h[e] = tot;
}

int id = 0;
int vis[MaxN], L[MaxN], R[MaxN], seq[MaxN], A[MaxN];
void dfs(int x) {
	vis[x] = true;
	seq[L[x] = ++id] = x;
	for (int z = h[x]; z; z = next[z]) if (!vis[v[z]]) {
		dfs(v[z]);
	}
	R[x] = id;
}

const int B = 62;
int BLK = 0;
int MOD;

struct TData {
	long long Mask[22];
	TData() {}
	void clear() { memset(Mask, 0, sizeof Mask); }
	void set(int x, long long val) {
		long long &S = Mask[x / B];
		x %= B;
		if (S >> x & 1) S -= 1LL << x;
		S |= val << x;
	}
	int get(int x) {
		return Mask[x / B] >> (x % B) & 1;
	}
	TData operator + (const TData &b) const {
		TData ret;
		memcpy(ret.Mask, Mask, sizeof Mask);
		For(i,0,BLK) ret.Mask[i] |= b.Mask[i];
		return ret;
	}
	TData move(int offset) {
		offset %= MOD;
		TData ret; ret.clear();
		for (int i = 0; i < MOD; ++i) {
			int t = (i + offset) % MOD;
			int nxt_i = min(MOD - 1, i / B * B + B - 1);
			int nxt_t = min(MOD - 1, t / B * B + B - 1);
			int inc = min(nxt_i - i, nxt_t - t) + 1;
			ret.Mask[nxt_t / B] |= (Mask[nxt_i / B] >> i % B & ((1LL << inc) - 1)) << (t % B);
			i += inc;
		}
		return ret;
	}
};

struct SegTreeNode {
	int l, r, offset;
	TData info;
	SegTreeNode() {}
	void init(int _l, int _r, int _val) {
		l = _l, r = _r;
		info.clear();
		info.set(_val % MOD, 1);
		offset = 0;
	}
	void make_add(int c) {
		(offset += c) %= MOD;
		info = info.move(c % MOD);
	}
}T[MaxN * 2];

struct SegmentTree {
	void push(int t) {
		if (T[t].offset) {
			if (T[t].l == T[t].r) return ;
			T[t + t].make_add(T[t].offset);
			T[t + t + 1].make_add(T[t].offset);
			T[t].offset = 0;
		}
	}
	void update(int t) {
		if (T[t].l == T[t].r) return ;
		T[t].info = T[t + t].info + T[t + t + 1].info;
	}
	void modify(int t, int l, int r, int val) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			T[t].make_add(val);
			return ;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		if (l <= mid) modify(t + t, l, r, val);
		if (r > mid) modify(t + t + 1, l, r, val);
		update(t);
	}
	TData ask(int t, int l, int r) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			return T[t].info;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		TData ret; ret.clear();
		if (l <= mid) ret = ret + ask(t + t, l, r);
		if (r > mid) ret = ret + ask(t + t + 1, l, r);
		update(t);
		return ret;
	}
	void build(int t, int l, int r, int *seq) {
		T[t].init(l, r, A[seq[l]]);
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build(t + t, l, mid, seq);
		build(t + t + 1, mid + 1, r, seq);
		update(t);
	}
}Tab;

int n, Q;
int main() {
	cin >> n >> MOD;
	vector<int> primes;
	For(i,2,MOD) {
		bool valid = true;
		For(j,2,i - 1) if (i % j == 0) valid = false ;
		if (valid) primes.push_back(i);
	}

	BLK = (MOD + B - 1) / B;

	For(i,1,n) scanf("%d", &A[i]);
	For(i,1,n - 1) {
		int b, e;
		scanf("%d%d", &b, &e);
		add(b, e);
	}

	dfs(1);

	Tab.build(1, 1, n, seq);

	cin >> Q;
	For(i,1,Q) {
		int op, v, x;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &v, &x);
			Tab.modify(1, L[v], R[v], x);
		}
		if (op == 2) {
			scanf("%d", &v);
			TData ans = Tab.ask(1, L[v], R[v]);
			int num = 0;
			for (auto cand : primes) if (ans.get(cand) == 1) ++num;
			printf("%d\n", num);
		}
	}

	return 0;
}