#include<bits/stdc++.h>
using namespace std;
const int M = 1e5 + 10; typedef long long ll;
int n, q, m;
ll sgt[M << 2], lzts[M << 2], lztc[M << 2], a[M];
void up(int u) {
sgt[u] = (sgt[u * 2] + sgt[u * 2 + 1]) % m;
}
void buildd(int u, int L, int R) {
if(L == R) {
sgt[u] = a[L] % m;
return;
}
lztc[u] = 1;
int mid = L + (R - L >> 1);
buildd(u * 2, L, mid);
buildd(u * 2 + 1, mid + 1, R);
}
void mtagc(int u, int val) {
(lzts[u] *= val) %= m; (sgt[u] *= val) %= m;
(lztc[u] *= val) %= m;
}
void cdown(int u, int L, int R) {
int mid = L + (R - L >> 1);
mtagc(u * 2, lztc[u]);
mtagc(u * 2 + 1, lztc[u]);
lztc[u] = 1;
}
void mtags(int u, int len, int val) {
(sgt[u] += len * val) %= m;
(lzts[u] += val) %= m;
}
void sdown(int u, int L, int R) {
int mid = L + (R - L >> 1);
mtags(u * 2, mid - L + 1, lzts[u]);
mtags(u * 2 + 1, R - mid, lzts[u]);
lzts[u] = 0;
}
void down(int u, int L, int R) {
cdown(u, L, R); sdown(u, L, R);
}
void cheng(int u, int l, int r, int L, int R, int val) {
if(l <= L && R <= r)
mtagc(u, val);
else if(!(r < L || R < l)) {
down(u, L, R);
int mid = L + (R - L >> 1);
cheng(u * 2, l, r, L, mid, val);
cheng(u * 2 + 1, l ,r, mid + 1, R, val);
up(u);
}
}
void addd(int u, int l, int r, int L, int R, int val) {
if(l <= L && R <= r)
mtags(u, R - L + 1, val);
else if(!(r < L || R < l)) {
down(u, L, R);
int mid = L + (R - L >> 1);
addd(u * 2, l, r, L, mid, val);
addd(u * 2 + 1, l ,r, mid + 1, R, val);
up(u);
}
}
ll queryy(int u, int l, int r, int L, int R) {
if(l <= L && R <= r)
return sgt[u] % m;
else if(!(r < L || R < l)) {
down(u, L, R);
int mid = L + (R - L >> 1);
return (queryy(u * 2, l, r, L, mid) % m + queryy(u * 2 + 1, l, r, mid + 1, R) % m) % m;
}
else return 0;
}
int main() {
scanf("%d %d %d", &n, &q, &m);
for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
buildd(1, 1, n);
for(int i = 1, t, x, y, k; i <= q; ++i) {
scanf("%d", &t);
if(t == 1) {
scanf("%d %d %d", &x, &y, &k);
cheng(1, x, y, 1, n, k);
}
else if(t == 2) {
scanf("%d %d %d", &x, &y, &k);
addd(1, x, y, 1, n, k);
}
else {
scanf("%d %d", &x, &y);
ll ans = queryy(1, x, y, 1, n) % m;
cout << ans << "\n";
}
}
return 0;
}