#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
#define Mod(x) ((x) %= m)
struct Tree {
int l , r;
ll pre , add , mul;
}t[600050];
ll n , m , q , op , x , y , k , a[100050];
inline void unionn (int num)
{
t[num].pre = t[num*2].pre + t[num*2+1].pre;
Mod(t[num].pre);
return;
}
inline void f (int num , ll addx , ll mulx)
{
t[num].pre = (t[num].pre * mulx % m + addx * (t[num].r - t[num].l + 1) % m);
t[num].add = t[num].add * mulx + addx;
t[num].mul *= mulx;
Mod(t[num].pre);
Mod(t[num].mul);
Mod(t[num].add);
return;
}
inline void down (int num)
{
f(num*2 , t[num].add , t[num].mul);
f(num*2+1 , t[num].add , t[num].mul);
t[num].add = 0;
t[num].mul = 1;
return;
}
void update_add (int num , int L , int R , ll x)
{
const int l = t[num].l , r = t[num].r , mid = (l+r)>>1;
if(L <= l && R >= r)
{
t[num].pre += (r-l+1) * x;
t[num].add += x;
Mod(t[num].pre);
Mod(t[num].add);
return;
}
down (num);
if(L <= mid)
update_add(num*2 , L , R , x);
if(R >= mid+1)
update_add(num*2+1 , L , R , x);
unionn (num);
return;
}
void update_mul (int num , int L , int R , ll x)
{
const int l = t[num].l , r = t[num].r , mid = (l+r)>>1;
if(L <= l && R >= r)
{
t[num].pre *= x;
t[num].add *= x;
t[num].mul *= x;
Mod(t[num].pre);
Mod(t[num].add);
Mod(t[num].mul);
return;
}
down (num);
if(L <= mid)
update_add(num*2 , L , R , x);
if(R >= mid+1)
update_add(num*2+1 , L , R , x);
unionn (num);
return;
}
ll sum (int num , int L , int R)
{
const int l = t[num].l , r = t[num].r , mid = (l+r)>>1;
if(L <= l && R >= r)
return t[num].pre % m;
down(num);
ll ans = 0;
if(L <= mid)
ans += sum (num*2 , L , R);
if(R >= mid+1)
ans += sum (num*2+1 , L , R);
return ans % m;
}
void build (int num , int L , int R)
{
t[num].l = L , t[num].r = R , t[num].mul = 1 , t[num].add = 0;
if(L == R)
{
t[num].pre = a[L] % m;
return;
}
int mid = (L+R) >> 1;
build(num*2 , L , mid);
build(num*2+1 , mid+1 , R);
unionn(num);
return;
}
int main()
{
scanf("%lld%lld%lld",&n,&q,&m);
for(int i = 1 ; i <= n ; i ++)
scanf("%lld",&a[i]);
build (1 , 1 , n);
while (q --)
{
scanf("%lld%lld%lld",&op,&x,&y);
if(op == 1)
{
scanf("%lld",&k);
Mod(k);
update_mul(1,x,y,k);
}
else if(op == 2)
{
scanf("%lld",&k);
Mod(k);
update_add(1,x,y,k);
}
else{
printf("%lld\n",sum(1,x,y)%m);
}
}
return 0;
}