#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <vector>#include <cstdlib>#include <iostream>#include <queue>using namespace std;#define ll long long#define For(i, l, r) for (int i = (int)(l); i <= (int)(r); ++i)#define in(x) x = gi()inline int gi(){ char tmp = getchar(); int ans = 0; while (!isdigit(tmp)) tmp = getchar(); while (isdigit(tmp)) ans = ans * 10 + tmp - '0', tmp = getchar(); return ans;}const int N = 1e5 + 10;#define LOG 58int n, m, p, c;int cntp;struct Seg{ int min, sum;} T[N << 2];#define ls (pos << 1)#define rs (ls | 1)#define mid ((l + r) >> 1)#define lson ls, l, mid#define rson rs, mid + 1, rinline void Pu(int pos){ T[pos].min = min(T[ls].min, T[rs].min); T[pos].sum = T[ls].sum + T[rs].sum; while(T[pos].sum >= p) T[pos].sum -= p;}int A[LOG][N], Phi[N];void Update(int pos, int l, int r, int ql, int qr){ if (T[pos].min >= cntp) return; if (l == r) { T[pos].min++; T[pos].sum = A[T[pos].min][l]; return; } if (ql <= mid) Update(lson, ql, qr); if (qr > mid) Update(rson, ql, qr); Pu(pos);}int Query(int pos, int l, int r, int ql, int qr){ if (ql <= l && r <= qr) { return T[pos].sum; } int ans = 0; if (ql <= mid) ans += Query(lson, ql, qr); if (qr > mid) ans = 1ll * (ans + Query(rson, ql, qr)) % p; return ans % p;}inline int Get(int n){ static int t, i, ans; t = n, ans = n; for (i = 2; i * i <= n; ++i) if (t % i == 0) { while (!(t % i)) t /= i; ans = ans / i * (i - 1); } if (t > 1) ans = ans / t * (t - 1); return ans;}int Pow1[1<<16][LOG], Pow2[1<<16][LOG];inline int Mod(long long x, int p){ if (x >= p) return x % p +p ; return x;}void Pre(){ For(i, 0, cntp) { Pow2[0][i] = Pow1[0][i] = 1; For(j, 1, (1<<15)-1) Pow1[j][i] = Mod(1ll * Pow1[j - 1][i] * c, Phi[i]); Pow2[1][i] = Mod(1ll*Pow1[(1<<15)-1][i]*c,Phi[i]); For(j, 2, (1<<15)-1) Pow2[j][i] = Mod(1ll * Pow2[j - 1][i] * Pow2[1][i], Phi[i]); } return;}int Pow(int a, int b){ int j = a & 32767, k = a >> 15; return Mod(1ll * Pow1[j][b] * Pow2[k][b], Phi[b]);}int F(int x, int a, int b){ if (!a) return Mod(x, Phi[b]); if (b == cntp) return c ? 1 : 0; return Pow(F(x, a - 1, b + 1), b);}void Build(int pos, int l, int r){ if (l == r) { T[pos].min = 0; T[pos].sum = A[0][l]; return; } Build(lson), Build(rson); Pu(pos);}signed main(){#ifdef NICEGUODONG freopen("data.in", "r", stdin);#endif in(n), in(m), in(p), in(c); Phi[0]=p; while(Phi[cntp]>1){ int x=cntp; Phi[++cntp]=Get(Phi[x]); } Phi[++cntp]=1; Pre(); For(i, 1, n) A[0][i] = gi() ; // diff For(i, 1, n){ For(j, 1, cntp+1) A[j][i] = F(A[0][i], j, 0) % p; A[0][i] %= p; } Build(1, 1, n); // return 0; For(i, 1, m) { int opt, l, r; in(opt), in(l), in(r); if (opt == 0) Update(1, 1, n, l, r); if (opt == 1) { cout << (Query(1, 1, n, l, r)) % p; putchar('\n'); } } return 0;}