#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
const int MAX = 1e5;
int MOD;
LL arr[MAX + 5];
LL tree[4 * MAX + 5];
LL lazy_add[4 * MAX + 5];
LL lazy_muti[4 * MAX + 5];
void build(int s,int t,int p){
if(s == t){
tree[p] = arr[s];
return;
}
int m = (s + t) / 2;
build(s,m,2 * p);
build(m+1,t,2 * p + 1);
tree[p] = tree[2 * p] + tree[2 * p + 1];
}
void pushdown_add(int s,int t,int p,int m){
if(lazy_add[p] != 0 && s != t){
tree[2 * p] += (m - s + 1) * lazy_add[p], tree[2 * p + 1] += (t - m) * lazy_add[p];
lazy_add[2 * p] += lazy_add[p], lazy_add[2 * p + 1] += lazy_add[p];
tree[2 * p] %= MOD, tree[2 * p + 1] %= MOD;
lazy_add[2 * p] %= MOD, lazy_add[2*p + 1] %= MOD;
lazy_add[p] = 0;
}
}
void pushdown_muti(int s,int t,int p,int m){
pushdown_add(s,t,p,m);
if(lazy_muti[p] != 0 && s != t){
tree[2 * p] *= lazy_muti[p], tree[2 * p + 1] *= lazy_muti[p];
lazy_muti[2 * p] += lazy_muti[p], lazy_muti[2 * p + 1] += lazy_muti[p];
tree[2 * p] %= MOD, tree[2 * p + 1] %= MOD;
lazy_add[2 * p] %= MOD, lazy_add[2*p + 1] %= MOD;
lazy_muti[p] = 0;
}
}
void update_muti(int L, int R,int k, int s ,int t, int p){
if(L <= s && t <= R){
lazy_muti[p] *= k; tree[p] = (tree[p]* k);
lazy_muti[p] %= MOD; tree[p] %= MOD;
return;
}
int m = (s + t) / 2;
pushdown_muti(s,t,p,m);
if(L <= m) update_muti(L,R,k,s,m,2 * p);
if(R > m) update_muti(L,R,k,m+1,t,2 * p + 1);
tree[p] = tree[2 * p] + tree[2 * p + 1];
}
void update_add(int L, int R,int k, int s ,int t, int p){
if(L <= s && t <= R){
tree[p] += (t - s + 1) * k; lazy_add[p] += k;
return;
}
int m = (s + t) / 2;
pushdown_add(s,t,p,m);
if(L <= m) update_add(L,R,k,s,m,2 * p);
if(R > m) update_add(L,R,k,m+1,t,2 * p + 1);
tree[p] = tree[2 * p] + tree[2 * p + 1];
}
LL getsum(int L, int R, int s, int t, int p){
if(L <= s && t <= R){
return tree[p];
}
int m = (s + t) / 2;
LL sum = 0;
pushdown_add(s,t,p,m);
if(L <= m) sum += getsum(L,R,s,m,2 * p);
if(R > m) sum += getsum(L,R,m+1,t,2*p+1);
return sum%MOD;
}
int main(){
int n,m;
int choose;
int x,y,k;
scanf("%d%d%d",&n,&m,&MOD);
for(int i = 1; i <= n; i++){
scanf("%lld",&arr[i]);
}
build(1,n,1);
while(scanf("%d",&choose)!=EOF){
if(choose == 1){
scanf("%d%d%d",&x,&y,&k);
update_muti(x,y,k,1,n,1);
}else if(choose == 2){
scanf("%d%d%d",&x,&y,&k);
update_add(x,y,k,1,n,1);
}else{
scanf("%d%d",&x,&y);
printf("%lld\n",getsum(x,y,1,n,1));
}
}
return 0;
}