#include<bits/stdc++.h>
using namespace std;
struct node{
long long l;
long long r;
long long sum=0;
long long tag1=0;
long long tag2=1;
};
node tree[1000010];
long long a[1000010];
long long ret=0;
long long n,m,p;
void make_tree(long long id,long long l,long long r){
tree[id].l=l;
tree[id].r=r;
if(l==r){
tree[id].sum=a[l];
return;
}
long long mid=(l+r)/2;
make_tree(id*2,l,mid);
make_tree(id*2+1,mid+1,r);
return;
}
void push_up(long long id){
tree[id].sum=(tree[id*2].sum%p)+(tree[id*2+1].sum)%p;
tree[id].sum%=p;
return;
}
void push_down(long long id){
if(!tree[id].tag1 && tree[id].tag2==1){
return;
}
tree[id*2].sum*=tree[id].tag2;
tree[id*2].sum+=tree[id].tag1*(tree[id*2].r-tree[id*2].l+1);
tree[id*2].sum%=p;
tree[id*2+1].sum*=tree[id].tag2;
tree[id*2+1].sum+=tree[id].tag1*(tree[id*2+1].r-tree[id*2+1].l+1);
tree[id*2+1].sum%=p;
tree[id*2].tag2=(tree[id*2].tag2*tree[id].tag2)%p;
tree[id*2+1].tag2=(tree[id*2+1].tag2*tree[id].tag2)%p;
tree[id*2].tag1=(tree[id*2].tag1+tree[id].tag1)%p;
tree[id*2+1].tag1=(tree[id*2+1].tag1+tree[id].tag1)%p;
tree[id].tag1=0;
tree[id].tag2=1;
return;
}
long long ans_l,ans_r,ans;
void add(long long id){
if(tree[id].r<ans_l || tree[id].l>ans_r){
return;
}
if(tree[id].l>=ans_l && tree[id].r<=ans_r){
tree[id].sum=tree[id].sum*ans%p;
tree[id].tag2=tree[id].tag2*ans%p;
tree[id].tag1=tree[id].tag1*ans%p;
return;
}
if(tree[id].l==tree[id].r){
return;
}
push_down(id);
add(id*2);
add(id*2+1);
push_up(id);
return;
}
void mul(long long id){
if(tree[id].r<ans_l || tree[id].l>ans_r){
return;
}
if(tree[id].l>=ans_l && tree[id].r<=ans_r){
tree[id].sum=(tree[id].sum+(tree[id].r-tree[id].l+1)*ans)%p;
tree[id].tag1=(tree[id].tag1+ans)%p;
return;
}
if(tree[id].l==tree[id].r){
return;
}
push_down(id);
mul(id*2);
mul(id*2+1);
push_up(id);
return;
}
void work_tree(long long id){
if(tree[id].r<ans_l || tree[id].l>ans_r){
return;
}
if(tree[id].l>=ans_l && tree[id].r<=ans_r){
ret+=tree[id].sum;
ret%=p;
return;
}
if(tree[id].l==tree[id].r){
return;
}
push_down(id);
work_tree(id*2);
work_tree(id*2+1);
push_up(id);
}
void Init(long long x,long long y,long long k){
ans_l=x;
ans_r=y;
ans=k%p;
ret=0;
}
int main(){
scanf("%lld%lld%lld",&n,&m,&p);
for(long long i=1;i<=n;i++){
scanf("%lld",&a[i]);
a[i]%=p;
}
make_tree(1,1,n);
while(m--){
long long op;
scanf("%d",&op);
if(op==1){
long long x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
Init(x,y,k);
add(1);
}
if(op==2){
long long x,y,k;
scanf("%lld%lld%lld",&x,&y,&k);
Init(x,y,k);
mul(1);
}
if(op==3){
long long x,y;
scanf("%lld%lld",&x,&y);
Init(x,y,114514);
work_tree(1);
printf("%lld\n",ret);
}
}
return 0;
}