#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64;
const int ONE = 500005;
const int INF = 2147483640;
int n,m,p,C;
int opt,x,y;
int a[ONE],phi[ONE],p_num;
int MOD;
int res;
struct power
{
int value;
int cnt;
}Node[ONE];
int get()
{
int res=1,Q=1;char c;
while( (c=getchar())<48 || c>57 )
if(c==‘-‘)Q=-1;
res=c-48;
while( (c=getchar())>=48 && c<=57 )
res=res*10+c-48;
return res*Q;
}
int Getphi(int n)
{
int res = n;
for(int i=2; i*i<=n; i++)
if(n % i == 0)
{
res = res/i*(i-1);
while(n % i == 0) n /= i;
}
if(n != 1) res = res/n*(n-1);
return res;
}
int Quickpow(int a,int b,int MOD)
{
int res = 1;
while(b)
{
if(b & 1) res = (s64)res * a % MOD;
a = (s64)a * a % MOD;
b >>= 1;
}
return res;
}
void Build(int i,int l,int r)
{
if(l == r)
{
Node[i].value = a[l] % MOD;
return;
}
int mid = l+r>>1;
Build(i<<1, l, mid);
Build(i<<1|1, mid + 1, r);
Node[i].value = (Node[i<<1].value + Node[i<<1|1].value) % MOD;
}
int Calc(int a, int times)
{
for(int i=times; i>=1; i--)
{
if(a >= phi[i]) a = a%phi[i] + phi[i];
a = Quickpow(C, a, phi[i-1]);
if(!a) a = phi[i-1];
}
return a;
}
void Update(int i,int l,int r,int L,int R)
{
if(Node[i].cnt >= p_num) return;
if(l == r)
{
Node[i].value = Calc(a[l], ++Node[i].cnt);
return;
}
int mid = l+r>>1;
if(L <= mid) Update(i<<1, l, mid, L, R);
if(mid+1 <= R) Update(i<<1|1, mid+1, r, L, R);
Node[i].value = (Node[i<<1].value + Node[i<<1|1].value) % MOD;
Node[i].cnt = min(Node[i<<1].cnt, Node[i<<1|1].cnt);
}
void Query(int i,int l,int r,int L,int R)
{
if(L<=l && r<=R)
{
res = (res + Node[i].value) % MOD;
return;
}
int mid = l+r>>1;
if(L <= mid) Query(i<<1, l, mid, L, R);
if(mid+1 <= R) Query(i<<1|1, mid+1, r, L, R);
}
int main()
{
n = get(); m = get(); p = get(); C = get();
for(int i=1; i<=n; i++) a[i] = get();
MOD = phi[0] = p;
while(p!=1) phi[++p_num] = p = Getphi(p);
phi[++p_num] = 1;
Build(1, 1, n);
while(m--)
{
opt = get();
x = get(); y = get();
if(!opt) Update(1, 1, n, x, y);
else
{
res = 0;
Query(1, 1, n, x, y);
printf("%d\n", res);
}
}
}