#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define re register
#define lson (o << 1)
#define rson (o << 1 | 1)
#define mid ( (l + r) >> 1 )
using namespace std;
inline long long read(){
char ch = getchar();
long long f = 1 , x = 0;
while(ch > '9' || ch < '0') {if(ch == '-') f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0' ; ch = getchar();}
return x * f;
}
long long n,m,flag,x,y,k;
long long a[100005];
struct Tree{
long long sum , add;
}t[400040];
inline void pushup(long long o) {
t[o].sum = t[lson].sum + t[rson].sum ;
}
inline void build(long long o , long long l , long long r) {
if(l == r) {
t[o].sum = a[l];
return ;
}
build(lson , l , mid);
build(rson , mid + 1 , r);
pushup(o);
}
inline void pushdown(long long o , long long l , long long r) {
if(t[o].add != 0) {
t[lson].sum += t[o].add * (mid - l + 1) ;
t[rson].sum += t[o].add * (r - mid ) ;
t[lson].add += t[o].add;
t[rson].add += t[o].add;
t[o].add = 0;
}
}
inline void add(long long o , long long l , long long r , long long from , long long to , long long v) {
if(from <= l && to >= r){
t[o].add += v ;
t[o].sum += v * (r - l + 1) ;
return ;
}
pushdown(o , l , r);
if(from <= mid) add(lson , l , mid , from , to , v);
if(to > mid) add(rson , mid + 1 , r , from , to , v);
pushup(o);
}
inline long long ask_sum(long long o , long long l ,long long r , long long from, long long to){
if(from <= l && to >= r) return t[o].sum;
long long ans = 0 ;
pushdown(o , l , r) ;
if(from <= mid) ans += ask_sum(lson , l , mid , from , to);
if(to > mid) ans += ask_sum(rson , mid + 1 , r , from , to);
return ans;
}
int main(){
n = read(); m = read();
for(re int i = 1 ; i <= n ; ++i) {
a[i] = read();
}
build(1 , 1 , n);
for(re int i = 1 ; i <= m ; ++i) {
flag = read();
if(flag == 1) {
x = read(); y = read(); k = read();
add(1 , 1 , n , x , y , k);
}
if(flag == 2) {
x = read(); y = read();
long long ans = ask_sum(1 , 1 , n , x , y) ;
printf("%lld
",ans);
}
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define re register
#define lson ( o << 1)
#define rson (o << 1 | 1)
#define mid ((l + r) >> 1)
using namespace std;
inline long long read() {
char ch = getchar();
long long f = 1 , x = 0;
while(ch > '9' || ch < '0') {if(ch == '-') f = -1 ;ch = getchar();}
while(ch >= '0' && ch <= '9') {x = (x << 1) + ( x << 3) + ch - '0';ch = getchar();}
return x * f;
}
long long n,m,p,flag,x,y,k;
long long a[100005];
struct Tree{
long long add , mul , sum ;
}t[400040];
inline void pushup(long long o){
t[o].sum = t[lson].sum + t[rson].sum;
}
inline void build(long long o , long long l , long long r) {
t[o].mul = 1 ; t[o].add = 0 ;
if(l == r) {
t[o].sum = a[l];
t[o].mul = 1;
return ;
}
build(lson , l , mid);
build(rson , mid + 1 , r);
pushup(o);
}
inline void pushdown(long long o , long long l , long long r){
if(t[o].mul != 1) {
t[lson].mul = (t[o].mul * t[lson].mul) % p;
t[rson].mul = (t[o].mul * t[rson].mul) % p;
t[lson].sum = (t[o].mul * t[lson].sum) % p;
t[rson].sum = (t[o].mul * t[rson].sum) % p;
t[lson].add = (t[o].mul * t[lson].add) % p;
t[rson].add = (t[o].mul * t[rson].add) % p;
t[o].mul = 1;
}
if(t[o].add) {
t[lson].sum = (t[lson].sum + (t[o].add * (mid - l + 1)) % p) % p;
t[rson].sum = (t[rson].sum + (t[o].add * (r - mid)) % p) % p;
t[lson].add = (t[lson].add + t[o].add) % p;
t[rson].add = (t[rson].add + t[o].add) % p;
t[o].add = 0;
}
}
inline void mul(long long o , long long l , long long r , long long from , long long to , long long v){
if(from <= l && to >= r) {
t[o].mul = t[o].mul * v % p ;
t[o].add = t[o].add * v % p ;
t[o].sum = t[o].sum * v % p ;
return ;
}
pushdown(o , l , r);
if(from <= mid) mul(lson , l , mid , from , to , v);
if(to > mid) mul(rson , mid + 1 , r , from , to , v) ;
pushup(o);
}
inline void add(long long o , long long l , long long r , long long from ,long long to , long long v){
if(from <= l && to >= r) {
t[o].add = (t[o].add + v) % p;
t[o].sum = (t[o].sum + v * (r - l + 1) ) % p;
return ;
}
pushdown(o , l , r) ;
if(from <= mid) add(lson , l , mid , from , to , v);
if(to > mid) add(rson , mid + 1 , r , from , to , v);
pushup(o);
}
inline long long query(long long o , long long l , long long r, long long from , long long to){
if(from <= l && to >= r) return t[o].sum;
long long ans = 0;
pushdown(o , l , r) ;
if(from <= mid) ans = (ans + query(lson , l , mid , from , to) ) % p;
if(to > mid) ans = (ans + query(rson , mid + 1 , r , from , to) ) % p;
return ans % p;
}
int main(){
n = read(); m = read() ; p = read();
for(re int i = 1 ; i <= n ; ++i)
a[i] = read();
build(1 , 1 , n);
for(re int i = 1 ; i <= m ; ++i) {
flag = read();
if(flag == 1) {
x = read(); y = read(); k = read();
mul(1 , 1 , n , x , y , k);
}
if(flag == 2){
x = read(); y = read(); k = read();
add(1 , 1 , n , x , y , k);
}
if(flag == 3) {
x = read(); y = read();
printf("%lld
" , query(1 , 1 , n , x , y) );
}
}
return 0 ;
}