#include<cstdio>
#include<cstring>
#define ll_ long long
#define re_ register
#define maxn_ 100005
#define child ((id<<1)+1)
#define mid (((r-l)>>1)+l)
ll_ int a[maxn_],d[maxn_<<4],tag1[maxn_<<4],tag2[maxn_<<4];//1*2+
ll_ int n,m,p;
ll_ int read(void){
ll_ int r = 0,w = 1;
re_ char c;
c = getchar();
if(c == '-'){
w = -1;
c = getchar();
}
while(c>='0' && c<='9'){
r = r*10 + c-'0';
c = getchar();
}
return r*w;
}
void input(void){
n = read();
m = read();
p = read();
for(re_ int i = 1;i <= n;++ i)
a[i] = read();
for(re_ int i = 0;i < maxn_<<4;++ i)
tag1[i] = 1;
return;
}
void build(int id,int l,int r){
if(l == r)
d[id] = a[l] % p;
else{
build(child,l,mid);
build(child+1,mid+1,r);
d[id] = (d[child] + d[child+1]) % p;
}
return;
}
void pushdown(int id,int l,int r){
d[child] = (d[child]*tag1[id]%p + tag2[id]*(mid-l+1)%p) % p;
d[child+1] = (d[child+1]*tag1[id]%p + tag2[id]*(r-mid)%p) % p;
tag1[child] *= tag1[id];
tag1[child+1] *= tag1[id];
tag2[child] *= tag1[id];
tag2[child+1] *= tag1[id];
tag2[child] += tag2[id];
tag2[child+1] += tag2[id];
tag1[id] = 1;
tag2[id] = 0;
return;
}
void update(int id,int l,int r,int s,int e,int add,int mul){
#ifdef debug
printf("%d %d %d %d %d %d %d\n",id,l,r,s,e,add,mul);
Sleep(1000);
#endif
if(s<=l && e>=r){
d[id] = d[id]*mul + (r-l+1)*add;
tag1[id] *= mul;
tag2[id] *= mul;
tag2[id] += add;
}
else{
if(s <= mid)
update(child,l,mid,s,e,add,mul);
if(e > mid)
update(child+1,mid+1,r,s,e,add,mul);
d[id] = (d[child]+d[child+1])%p;
}
return;
}
ll_ int getsum(int id,int l,int r,int s,int e){
if(s<=l && e>=r)
return d[id];
else{
ll_ int ret = 0;
pushdown(id,l,r);
if(s <= mid)
ret += getsum(child,l,mid,s,e)%p;
if(e > mid)
ret += getsum(child+1,mid+1,r,s,e)%p;
return ret%p;
}
}
void solve(void){
ll_ int op,x,y,k;
for(re_ int i = 0;i < m;++ i){
op = read();
x = read();
y = read();
if(op == 1){
k = read();
update(0,1,n,x,y,0,k);
}
else if(op == 2){
k = read();
update(0,1,n,x,y,k,1);
}
else
printf("%lld\n",getsum(0,1,n,x,y));
}
return;
}
int main(void){
input();
build(0,1,n);
solve();
return 0;
}