#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
const int MOD=pow(2,20);
int n,m,x,y,k,a[N];
int op;
struct{
int Left,Right;
long long data,add;
}t[N*4];
void Build_Tree(int p,int Left,int Right){
t[p].Left=Left;
t[p].Right=Right;
if(Left==Right){
t[p].data=a[Left];
return;
}
else{
int mid=(Left+Right)/2;
Build_Tree(p*2,Left,mid);
Build_Tree(p*2+1,mid+1,Right);
t[p].data=t[p*2].data+t[p*2+1].data;
}
}
void spread(int p){
if(t[p].add){
t[p*2].data+=t[p].add*(t[p*2].Right-t[p*2].Left+1);
t[p*2+1].data+=t[p].add*(t[p*2+1].Right-t[p*2+1].Left+1);
t[p*2].add+=t[p].add;
t[p*2+1].add+=t[p].add;
t[p].add=0;
}
}
void Change_Value(int p,int l,int r,int value){
if(t[p].Left>=l&&t[p].Right<=r){
t[p].data+=value*(t[p].Right-t[p].Left+1);
t[p].add+=value;
}else{
spread(p);
int mid=(t[p].Left+t[p].Right)/2;
if(l<=mid) Change_Value(p*2,l,r,value);
if(r>mid) Change_Value(p*2+1,l,r,value);
t[p].data=t[p*2].data+t[p*2+1].data;
}
}
long long Ask(int p,int Left,int Right){
if(Left<=t[p].Left&&Right>=t[p].Right) return t[p].data%MOD;
spread(p);
int mid=(t[p].Left+t[p].Right)/2;
long long ans=1;
if(Left<=mid) ans*=Ask(p*2,Left,Right)%MOD;
if(Right>mid) ans*=Ask(p*2+1,Left,Right)%MOD;
return ans%MOD;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++){
cin>>a[i];
}
Build_Tree(1,1,n);
for(int i=1;i<=m;i++){
cin>>op;
if(op==1){
scanf("%lld%lld%lld",&x,&y,&k);
Change_Value(1,x,y,k);
}
else if(op==2){
scanf("%lld%lld",&x,&y);
printf("%lld\n",Ask(1,x,y));
}
}
return 0;
}