#include<iostream>
#define lc p << 1
#define rc p << 1 | 1
using namespace std;
const int N = 1e5 + 10;
int n, q, m;
int a[N];
struct Node {
int l, r;
long long sum;
int tag1,tag2 = 1;
}node[N<<2];
void push_up(int p) {
node[p].sum = node[lc].sum + node[rc].sum;
}
void build(int p, int l, int r)
{
node[p].l = l, node[p].r;
if (l == r) node[p].sum = a[p];
int mid = l + r >> 1;
if (l <= mid) build(lc, l, mid);
if (r > mid) build(rc, mid + 1, r);
push_up(p);
}
void push_down(int p)
{
if (node[p].tag1) {
node[lc].sum += node[p].tag1 * (node[lc].r - node[lc].l + 1);
node[rc].sum += node[p].tag1 * (node[rc].r - node[rc].l + 1);
node[lc].tag1 += node[p].tag1;
node[rc].tag1 += node[p].tag1;
node[p].tag1 = 0;
return;
}
if (node[p].tag2)
{
node[lc].sum *= node[p].tag2;
node[rc].sum *= node[p].tag2;
node[lc].tag2 *= node[p].tag2;
node[rc].tag2 *= node[p].tag2;
node[p].tag2 *= 1;
}
}
void section_update1(int p, int x, int y, int val)
{
if (node[p].l >= x && node[p].r <= y)
{
node[p].sum += val * (node[p].r - node[p].l + 1);
node[p].tag1 += val;
return;
}
push_down(p);
int mid = node[p].l + node[p].r >> 1;
if (x <= mid) section_update1(lc, x, mid, val);
if (y > mid) section_update1(rc, mid + 1, y, val);
push_up(p);
}
void section_update2(int p, int x,int y, int val)
{
if (node[p].l >= x && node[p].r <= y) {
node[p].sum *= val;
node[p].tag2 *= val;
return;
}
push_down(p);
int mid = node[p].l + node[p].r >> 1;
if (x <= mid) section_update2(lc, x, mid, val);
if (y > mid) section_update2(rc, mid + 1, y, val);
push_up(p);
}
long long query(int p, int x, int y)
{
long long tmp = 0;
if (node[p].l >= x && node[p].r <= y) return node[p].sum;
int mid = node[p].l + node[p].r >> 1;
if (x <= mid) tmp += query(lc, x, y);
if (y > mid) tmp += query(rc, x, y);
return tmp;
}
int main()
{
cin >> n >> q >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 0; i < q; i++)
{
int op;
cin >> op;
if (op == 1) {
int x, y, k;
cin >> x >> y >> k;
section_update2(1, x, y, k);
}
else if (op == 2) {
int x, y, k;
cin >> x >> y >> k;
section_update1(1, x, y, k);
}
else if (op == 3) {
int x, y;
cin >> x >> y;
long long ans = query(1, x, y) % m;
cout << ans << '\n';
}
}
return 0;
}