rt
#include<bits/stdc++.h>
#define int long long
using namespace std;
int init(){
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
return 0;
}
const int maxn=1e6+10,mod=1e9+7,init_=init();
inline int read(){
int n=0,x=0,c;
while((c=getchar())<'0'||c>'9') x=c=='-';
do (n*=10)+=c-'0';while((c=getchar())>='0'&&c<='9');
return x?-n:n;
}
inline int write(int n){
if(n<0) putchar('-'),n=-n;
if(n>9) write(n/10);
putchar('0'+n%10);
return n;
}
int n=read(),m=read();
map<pair<int,int>,int> odt;
pair<int,int> split(int x){
if(x>n) return {0,0};
auto it=prev(odt.upper_bound({x,n+1}))->first;
int w=odt[it];
if(it.first==x) return it;
odt.erase(it),odt[{it.first,x-1}]=w,odt[{x,it.second}]=w;
return {x,it.second};
}
signed main(){
for(int i=1;i<=n;++i) odt[{i,i}]=read()%mod;
for(int j=1;j<=m;++j){
int opt=read();
if(opt==1){
int l=read(),r=read(),ans=0;
auto rs=split(r+1),ls=split(l);
for(auto it=odt.find(ls);it!=odt.end()&&it->first!=rs;++it) (ans+=(it->first.second-it->first.first+1)%mod*it->second%mod)%=mod;
write(ans),puts("");
}
else if(opt==2){
int l=read(),r=read();
auto rs=split(r+1),ls=split(l);
for(auto it=odt.find(ls);it!=odt.end()&&it->first!=rs;++it,odt.erase(prev(it)));
odt[{l,r}]=read()%mod;
}
else if(opt==3){
int l=read(),r=read(),val=read();
auto rs=split(r+1),ls=split(l);
for(auto it=odt.find(ls);it!=odt.end()&&it->first!=rs;++it) (it->second+=val)%=mod;
}
else if(opt==4){
int l1=read(),r1=read(),l2=read(),r2=read();
pair<int,int> r1s,l1s,r2s,l2s;
if(l1<l2) r2s=split(r2+1),l2s=split(l2),r1s=split(r1+1),l1s=split(l1);
else r1s=split(r1+1),l1s=split(l1),r2s=split(r2+1),l2s=split(l2);
queue<pair<pair<int,int>,int>> tmp;
for(auto it=odt.find(l1s);it!=odt.end()&&it->first!=r1s;++it) tmp.push({{it->first.first-l1+l2,it->first.second-l1+l2},it->second});
for(auto it=odt.find(l2s);it!=odt.end()&&it->first!=r2s;++it,odt.erase(prev(it)));
while(tmp.size()) odt[tmp.front().first]=tmp.front().second,tmp.pop();
}
else if(opt==5){
int l1=read(),r1=read(),l2=read(),r2=read();
queue<pair<pair<int,int>,int>> tmp,tmp1;
pair<int,int> r1s,l1s,r2s,l2s;
if(l1<l2) r2s=split(r2+1),l2s=split(l2),r1s=split(r1+1),l1s=split(l1);
else r1s=split(r1+1),l1s=split(l1),r2s=split(r2+1),l2s=split(l2);
for(auto it=odt.find(l1s);it!=odt.end()&&it->first!=r1s;++it,odt.erase(prev(it))) tmp.push({{it->first.first-l1+l2,it->first.second-l1+l2},it->second});
for(auto it=odt.find(l2s);it!=odt.end()&&it->first!=r2s;++it,odt.erase(prev(it))) tmp1.push({{it->first.first-l2+l1,it->first.second-l2+l1},it->second});
while(tmp.size()) odt[tmp.front().first]=tmp.front().second,tmp.pop();
while(tmp1.size()) odt[tmp1.front().first]=tmp1.front().second,tmp1.pop();
}
else if(opt==6){
int l=read(),r=read();
queue<pair<pair<int,int>,int>> tmp;
auto rs=split(r+1),ls=split(l);
for(auto it=odt.find(ls);it!=odt.end()&&it->first!=rs;++it,odt.erase(prev(it)))
tmp.push({{r-it->first.second+l,r-it->first.first+l},it->second});
while(tmp.size()) odt[tmp.front().first]=tmp.front().second,tmp.pop();
}
}
for(auto it=odt.begin();it!=odt.end();++it) for(int k=it->first.second-it->first.first+1;k--;) write(it->second%mod),putchar(' ');
return 0;
}/*
*/