RT
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
typedef long long ll;
int n, m, mod;
ll sum[maxn << 2], a[maxn];
ll lazymul[maxn << 2], lazyadd[maxn << 2];
int L[maxn << 2], R[maxn << 2];
int len(int x) {
return R[x] - L[x] + 1;
}
void pushup(int x) {
sum[x] = (sum[x << 1] + sum[x << 1 + 1]) % mod;
}
void pushdown(int x) {
if(lazymul[x] != 1) {
lazymul[x << 1] *= lazymul[x];lazymul[x << 1] %= mod;
lazymul[x << 1 + 1] *= lazymul[x];lazymul[x << 1 + 1] %= mod;
lazyadd[x << 1] += lazyadd[x];lazyadd[x << 1] %= mod;
lazyadd[x << 1 + 1] += lazyadd[x];lazyadd[x << 1 + 1] %= mod;
sum[x << 1] *= lazymul[x];sum[x << 1] %= mod;
sum[x << 1 + 1] *= lazymul[x];sum[x << 1 + 1] %= mod;
lazymul[x] = 1;
}
if(lazyadd[x]) {
lazyadd[x << 1] += lazyadd[x];lazyadd[x << 1] %= mod;
lazyadd[x << 1 + 1] += lazyadd[x];lazyadd[x << 1 + 1] %= mod;
sum[x << 1] += lazyadd[x] * len(x << 1);sum[x << 1] %= mod;
sum[x << 1 + 1] += lazyadd[x] * len(x << 1 + 1);sum[x << 1 + 1] %= mod;
lazyadd[x] = 0;
}
return;
}
void build(int l, int r, int x) {
L[x] = l, R[x] = r, lazymul[x] = 1;
if(l == r) {
sum[x] = a[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, x << 1);
build(mid + 1, r, x << 1 + 1);
pushup(x);
}
ll query(int l, int r, int x) {
if(l <= L[x] && R[x] <= r) return sum[x];
pushdown(x);
int mid = (L[x] + R[x]) >> 1;
ll ans = 0LL;
if(l <= mid) ans += query(l, r, x << 1);
if(r > mid) ans += query(l, r, x << 1 + 1);
return ans % mod;
}
void updateadd(int l, int r, int x, ll d) {
if(l <= L[x] && R[x] <= r) {
lazyadd[x] += d;lazyadd[x] %= mod;
sum[x] += d * len(x);sum[x] %= mod;
return;
}
pushdown(x);
int mid = (L[x] + R[x]) >> 1;
if(l <= mid) updateadd(l, r, x << 1, d);
if(r > mid) updateadd(l, r, x << 1 + 1, d);
pushup(x);
return;
}
void updatemul(int l, int r, int x, ll d) {
if(l <= L[x] && R[x] <= r) {
lazymul[x] *= d;lazymul[x] %= mod;
lazyadd[x] *= d;lazyadd[x] %= mod;
sum[x] *= d * len(x);sum[x] %= mod;
return;
}
pushdown(x);
int mid = (L[x] + R[x]) >> 1;
if(l <= mid) updatemul(l, r, x << 1, d);
if(r > mid) updatemul(l, r, x << 1 + 1, d);
pushup(x);
return;
}
int main() {
scanf("%d%d%lld", &n, &m, &mod);
for(int i = 1;i <= n;i++) scanf("%lld", &a[i]);
build(1, n, 1);
while(m--) {
int op, x, y;ll k;scanf("%d%d%d", &op, &x, &y);
if(op == 1) {
scanf("%lld", &k);
updatemul(x, y, 1, k);
}
if(op == 2) {
scanf("%lld", &k);
updateadd(x, y, 1, k);
}
if(op == 3) {
printf("%lld\n", query(x, y, 1));
}
}
return 0;
}