#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=1e7+10;
struct node{
ll l,r;
ll sum;
ll add;
ll mul;
};
ll N,M,mod;
ll a[MAXN];
node tree[MAXN*4];
void build(ll x,ll l,ll r)
{
tree[x].l=l;
tree[x].r=r;
tree[x].mul=1;
if(l==r)
{
tree[x].sum=a[l]%mod;
return;
}
ll mid=(l+r)/2;
build(x*2,l,mid);
build(x*2+1,mid+1,r);
tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;
}
void pushdown(ll x)
{
if(tree[x].add||tree[x].mul!=1)
{
tree[x*2].sum=(tree[x*2].sum*tree[x].mul+(tree[x*2].r-tree[x*2].l+1)*tree[x].add)%mod;
tree[x*2].add=(tree[x*2].add+tree[x].add)%mod;
tree[x*2].mul=(tree[x*2].mul*tree[x].mul)%mod;
tree[x*2+1].sum=(tree[x*2+1].sum*tree[x].mul+(tree[x*2+1].r-tree[x*2+1].l+1)*tree[x].add)%mod;
tree[x*2+1].add=(tree[x*2+1].add+tree[x].add)%mod;
tree[x*2+1].mul=(tree[x*2+1].mul*tree[x].mul)%mod;
tree[x].add=0;
tree[x].mul=1;
}
}
ll query(ll x,ll l,ll r)
{
pushdown(x);
if(l<=tree[x].l&&tree[x].r<=r)
return tree[x].sum%mod;
ll val=0;
ll mid=(tree[x].l+tree[x].r)/2;
if(l<=mid)
val=(val+query(x*2,l,r))%mod;
if(r>mid)
val=(val+query(x*2+1,l,r))%mod;
return val%mod;
}
void renew(ll x,ll l,ll r,ll p)
{
if(l<=tree[x].l&&tree[x].r<=r)
{
tree[x].sum=(tree[x].sum+(tree[x].r-tree[x].l+1)*p)%mod;
tree[x].add=(tree[x].add+p)%mod;
return;
}
pushdown(x);
ll mid=(tree[x].l+tree[x].r)/2;
if(l<=mid)
renew(x*2,l,r,p);
if(r>mid)
renew(x*2+1,l,r,p);
tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;
}
void Renew(ll x,ll l,ll r,ll p)
{
if(l<=tree[x].l&&tree[x].r<=r)
{
tree[x].sum=(tree[x].sum*p)%mod;
tree[x].add=(tree[x].add*p)%mod;
tree[x].mul=(tree[x].mul*p)%mod;
return;
}
pushdown(x);
ll mid=(tree[x].l+tree[x].r)/2;
if(l<=mid)
Renew(x*2,l,r,p);
if(r>mid)
Renew(x*2+1,l,r,p);
tree[x].sum=(tree[x*2].sum+tree[x*2+1].sum)%mod;
}
int main()
{
scanf("%lld%lld%lld",&N,&M,&mod);
for(ll i=1;i<=N;i++)
{
scanf("%lld",&a[i]);
a[i]%=mod;
}
build(1,1,N);
ll A,b,c,d;
while(M--)
{
scanf("%lld",&A);
if(A==1)
{
scanf("%lld%lld%lld",&b,&c,&d);
Renew(1,b,c,d);
}
if(A==2)
{
scanf("%lld%lld%lld",&b,&c,&d);
renew(1,b,c,d);
}
if(A==3)
{
scanf("%lld%lld",&b,&c);
printf("%lld\n",query(1,b,c)%mod);
}
}
return 0;
}