#include<iostream>
using namespace std;
int t[int(4e5)+10],xs[int(4e5)+10],js[int(4e5)+10];
int a[int(1e5)+10];
int n,m,p;
void addx(int root,int l,int r,int v){
t[root]*=v,t[root]%=p;
xs[root]*=v,xs[root]%=p;
}
void addj(int root,int l,int r,int v){
t[root]+=(r-l+1)*v,t[root]%=p;
js[root]+=v;js[root]%=p;
}
void push_down(int root,int l,int r){
addx(root*2,l,l+r>>1,xs[root]);
addx(root*2+1,(l+r>>1)+1,r,xs[root]);
addj(root*2,l,l+r>>1,js[root]);
addj(root*2+1,(l+r>>1)+1,r,js[root]);
xs[root]=1,js[root]=0;
}
void creat(int l,int r,int root){
if(l==r){
t[root]=a[l];
return;
}
creat(l,l+r>>1,root*2);
creat((l+r>>1)+1,r,root*2+1);
t[root]=t[root*2]+t[root*2+1];
t[root]%=p;
}
void updatej(int l,int r,int v,int x=1,int y=n,int root=1){
if(x>=l && y<=r){
addj(root,x,y,v);
return;
}
push_down(root,x,y);
int mid=x+y>>1;
if(l<=mid) updatej(l,r,v,x,mid,root*2);
if(r>mid) updatej(l,r,v,mid+1,y,root*2+1);
t[root]=t[root*2]+t[root*2+1];
}
void updatex(int l,int r,int v,int x=1,int y=n,int root=1){
if(x>=l && y<=r){
addx(root,x,y,v);
return;
}
push_down(root,x,y);
int mid=x+y>>1;
if(l<=mid) updatex(l,r,v,x,mid,root*2);
if(r>mid) updatex(l,r,v,mid+1,y,root*2+1);
t[root]=t[root*2]+t[root*2+1];
}
int sum(int l,int r,int x=1,int y=n,int root=1){
if(x>=l && y<=r)
return t[root];
push_down(root,x,y);
int mid=x+y>>1;
int cnt=0;
if(l<=mid) cnt+=sum(l,r,x,mid,root*2),cnt%=p;
if(r>mid) cnt+=sum(l,r,mid+1,y,root*2+1),cnt%=p;
return cnt%p;
}
int main() {
cin>>n>>m>>p;
for(int i=1;i<=n;i++)
cin>>a[i],a[i]%=p;
for(int i=1;i<=4*n;i++)
js[i]=1;
creat(1,n,1);
while(m--){
int opt,x,y,k;
cin>>opt;
switch (opt){
case 1:
cin>>x>>y>>k;
updatex(x,y,k);
break;
case 2:
cin>>x>>y>>k;
updatej(x,y,k);
break;
case 3:
cin>>x>>y;
cout<<sum(x,y)%p<<"\n";
break;
}
}
return 0;
}