#include<bits/stdc++.h>
#define MAXN 400005
#define ll long long
using namespace std;
struct node {
int l,r;
ll val,add,mul;
}t[MAXN];
int n,m,mod;
int a[MAXN];
void build(int p,int l,int r) {
t[p].l = l; t[p].r = r;t[p].val = 0;t[p].mul = 1;
if(l == r) {
t[p].val = a[l]; return ;
}
int mid = (l + r) >> 1;
build(p << 1,l,mid);
build(p << 1 | 1,mid + 1,r);
t[p].val = (t[p << 1].val + t[p << 1 | 1].val) % mod;
}
void spread(int p) {
t[p << 1].add = (t[p << 1].add * t[p].mul + t[p].add) % mod;
t[p << 1 | 1].add = (t[p << 1 | 1].add * t[p].mul + t[p].add) % mod;
t[p << 1].mul = (t[p << 1].mul * t[p].mul) % mod;
t[p << 1 | 1].mul = (t[p << 1 | 1].mul * t[p].mul) % mod;
t[p << 1].val = (t[p << 1].val * t[p].mul + t[p << 1].add * (t[p << 1].r - t[p << 1].l + 1)) % mod;
t[p << 1 | 1].val = (t[p << 1 | 1].val * t[p].mul + t[p << 1 | 1].add * (t[p << 1 | 1].r - t[p << 1 | 1].l + 1)) % mod;
t[p].add = 0;
t[p].mul = 1;
}
void mul(int p,int x,int y,ll k) {
if(t[p].l >= x && t[p].r <= y) {
t[p].val = (t[p].val * k) % mod;
t[p].add = (t[p].add * k) % mod;
t[p].mul = (t[p].mul * k) % mod;
return ;
}
spread(p);
if((t[p].l + t[p].r) >> 1 >= x) mul(p << 1,x,y,k);
if((t[p].l + t[p].r) >> 1 < y) mul(p << 1 | 1,x,y,k);
t[p].val = (t[p << 1].val + t[p << 1 | 1].val) % mod;
}
void add(int p,int x,int y,ll k) {
if(t[p].l >= x && t[p].r <= y) {
t[p].val = (t[p].val + (t[p].r - t[p].l + 1) * k) % mod;
t[p].add = (t[p].add + k) % mod;
return ;
}
spread(p);
if(((t[p].l + t[p].r) >> 1) >= x) add(p << 1,x,y,k);
if(((t[p].l + t[p].r) >> 1) < y) add(p << 1 | 1,x,y,k);
t[p].val = (t[p << 1].val + t[p << 1 | 1].val) % mod;
}
ll query(int p,int x,int y) {
if(t[p].l >= x && t[p].r <= y) return t[p].val;
spread(p);
ll ans = 0;
if(((t[p].l + t[p].r) >> 1) >= x) ans = (ans + query(p << 1,x,y)) % mod;
if(((t[p].l + t[p].r) >> 1) < y) ans = (ans + query(p << 1 | 1,x,y)) % mod;
return ans % mod;
}
int main()
{
scanf("%d%d%lld",&n,&m,&mod);
for(int i = 1;i <= n;i ++) {
scanf("%d",&a[i]);
}
build(1,1,n);
for(int i = 1;i <= m;i ++) {
int opt;
scanf("%d",&opt);
int x,y;
ll k;
if(opt == 1) {
scanf("%d%d%lld",&x,&y,&k);
mul(1,x,y,k);
}
else if(opt == 2) {
scanf("%d%d%lld",&x,&y,&k);
add(1,x,y,k);
}
else {
scanf("%d%d",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
return 0;
}