#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,m;
int p=571373;
int num[N];
struct node{
int l,r,sum;
int lazyadd,lazypro;
node(){l=r=sum=lazyadd=0;lazypro=1;}
}a[N<<2];
inline int read(){
int x=0;
bool f=true;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='0')f=false;
for(;isdigit(ch);ch=getchar())
x=(x<<1)+(x<<3)+ch-'0';
return f?x:~(x-1);
}
inline void update(int k){
a[k].sum=(a[k<<1].sum%p+a[k<<1|1].sum%p)%p;
}
void build(int k,int l,int r){
a[k].l=l,a[k].r=r;
if(l==r){
a[k].sum=num[l];
return;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
update(k);
}
void pushdown(int k){
a[k<<1].sum=(a[k<<1].sum*a[k].lazypro%p+a[k].lazyadd*(a[k<<1].r-a[k<<1].l+1)%p)%p;
a[k<<1|1].sum=(a[k<<1|1].sum*a[k].lazypro%p+a[k].lazyadd*(a[k<<1|1].r-a[k<<1|1].l+1)%p)%p;
a[k<<1].lazyadd=(a[k<<1].lazyadd*a[k].lazypro%p+a[k].lazyadd)%p;
a[k<<1|1].lazyadd=(a[k<<1|1].lazyadd*a[k].lazypro%p+a[k].lazyadd)%p;
a[k<<1].lazypro=a[k<<1].lazypro*a[k].lazypro%p;
a[k<<1|1].lazypro=a[k<<1].lazypro*a[k].lazypro%p;
a[k].lazypro=1;
a[k].lazyadd=0;
}
void add(int x,int k,int l,int r){
if(l<=a[k].l&&r>=a[k].r){
a[k].sum=(a[k].sum+x*(a[k].r-a[k].l+1))%p;
a[k].lazyadd=(a[k].lazyadd+x%p)%p;
return;
}
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
if(l<=mid)add(x,k<<1,l,r);
if(r>mid)add(x,k<<1|1,l,r);
update(k);
}
void pro(int x,int k,int l,int r){
if(l<=a[k].l&&r>=a[k].r){
a[k].sum=a[k].sum*x%p;
a[k].lazyadd=a[k].lazyadd*x%p;
a[k].lazypro=a[k].lazypro*x%p;
return;
}
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
if(l<=mid)pro(x,k<<1,l,r);
if(r>mid)pro(x,k<<1|1,l,r);
update(k);
}
int query(int k,int l,int r){
if(l<=a[k].l&&r>=a[k].r){
return a[k].sum;
}
int ans=0;
pushdown(k);
int mid=(a[k].l+a[k].r)>>1;
if(l<=mid)ans+=query(k<<1,l,r);
if(r>mid)ans+=query(k<<1|1,l,r);
return ans;
}
signed main(){
n=read(),m=read(),p=read();
for(int i=1;i<=n;i++)num[i]=read();
build(1,1,n);
while(m--){
int opt,x,y,k;
opt=read();
x=read();
y=read();
if(opt==1){
k=read();
pro(k,1,x,y);
}
if(opt==2){
k=read();
add(k,1,x,y);
}
if(opt==3){
printf("%d\n",query(1,x,y)%p);
}
}
system("pause");
return 0;
}