#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#define fre 1
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define MAXN 10005
typedef long long ll;
ll a[MAXN], ans[MAXN<<2], q;
struct tag{
ll add; ll mul;
} tag[MAXN<<2];
void f(ll p, ll l, ll r, ll add, ll mul){
ans[p] = ((add * (r - l + 1)) % q + (ans[p] * mul) % q) % q;
tag[p].mul = (mul * tag[p].mul) % q;
tag[p].add = ((tag[p].add * mul) % q + add) % q;
}
void push_up(ll p){ans[p] = (ans[ls(p)] + ans[rs(p)]) % q;}
void push_down(ll p, ll l, ll r){
ll mid = l + ((r - l)>>1);
f(ls(p), l, mid, tag[p].add, tag[p].mul);
f(rs(p), mid + 1, r, tag[p].add, tag[p].mul);
tag[p].add = 0;
tag[p].mul = 1;
}
void build(ll p, ll l, ll r){
if(l == r){
ans[p] = a[l];
return;
}
ll mid = l + ((r - l)>>1);
build(ls(p), l, mid);
build(rs(p), mid + 1, r);
push_up(p);
}
//注意乘法优先
void update_add(ll p, ll s, ll t, ll l, ll r, ll k){
//printf("s = %d, t = %d, l = %d, r = %d, ans[p] = %d\n",s, t, l, r, ans[p]);
if(s <= l && r <= t){
ans[p] = (ans[p] + k * (r - l + 1) % q) % q;
tag[p].add = (tag[p].add + k) % q;
return;
}
if((!tag[p].mul || tag[p].add) && l != r)
push_down(p, l, r);
ll mid = l + ((r - l)>>1);
if(s <= mid)
update_add(ls(p), s, t, l, mid, k);
if(mid < t)
update_add(rs(p), s, t, mid + 1, r, k);
push_up(p);
}
void update_mul(ll p, ll s, ll t, ll l, ll r, ll k){
if(s <= l && r <= t){
ans[p] = (ans[p] * k) % q;
tag[p].add = (tag[p].add * k) % q;
tag[p].mul = (tag[p].mul * k) % q;
return;
}
if((!tag[p].mul || tag[p].add) && l != r)
push_down(p, l, r);
ll mid = l + ((r - l)>>1);
if(s <= mid)
update_mul(ls(p), s, t, l, mid, k);
if(mid < t)
update_mul(rs(p), s, t, mid + 1, r, k);
push_up(p);
}
ll query(ll p, ll s, ll t, ll l, ll r){
if(s <= l && r <= t)
return ans[p];
ll res = 0, mid = l + ((r - l)>>1);
if((!tag[p].mul || tag[p].add) && r != l)
push_down(p, l, r);
if(s <= mid)
res = query(ls(p), s, t, l, mid);
if(mid < t)
res += query(rs(p), s, t, mid + 1, r);
return res % q;
}
int main(){
#ifdef fre
FILE *in, *out;
in = freopen("in.txt", "r", stdin);
out = freopen("out.txt", "w", stdout);
#endif
ll n,m, x, y, z, op;
scanf("%lld%lld%lld", &n, &m, &q);
for(int i = 1; i <= 4 * n; i++)
tag[i].mul = 1;
for(int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
build(1, 1, n);
while(m--){
scanf("%lld", &op);
switch (op){
case 1:{
scanf("%lld%lld%lld", &x, &y, &z);
update_mul(1, x, y, 1, n, z);
break;
}
case 2:{
scanf("%lld%lld%lld", &x, &y, &z);
update_add(1, x, y, 1, n, z);
break;
}
case 3:{
scanf("%lld%lld", &x, &y);
printf("%lld\n", query(1, x, y, 1, n) % q);
break;
}
}
}
#ifdef fre
fclose(in);
fclose(out);
#endif
return 0;
}