#include<bits/stdc++.h>
#define int long long
#define double long double
#define INF INT_MAX
using namespace std;
const int maxn=1e6+5,mod=1e9+7;
int n,m;
int a[maxn];
struct node {
int l,r;
mutable int v;
node(int L,int R=-1,int V=0) : l(L),r(R),v(V) {}
bool operator < (const node &x) const {
return l<x.l;
}
};
set<node> ODT;
set<node>::iterator spilit(int pos) {
set<node>::iterator it=ODT.lower_bound(node(pos,-1,0));
if(it!=ODT.end() && it->l==pos) return it;
it--;
if(it->r<pos) return ODT.end();
int V=it->v,L=it->l,R=it->r;
ODT.erase(it);
ODT.insert(node(L,pos-1,V));
return ODT.insert(node(pos,R,V)).first;
}
void bulldoze(int l,int r,int x) {
set<node>::iterator itr=spilit(r+1),itl=spilit(l);
ODT.erase(itl,itr);
ODT.insert(node(l,r,x));
}
void sectionadd(int l,int r,int x){
set<node>::iterator itr=spilit(r+1),itl=spilit(l);
for(;itl!=itr; itl++) itl->v+=x,itl->v%=mod;
}
int sum(int l,int r){
int res=0;
set<node>::iterator itr=spilit(r+1),itl=spilit(l);
for(;itl!=itr;itl++){
res+=((itl->r-itl->l+1)*(itl->v))%mod;
res%=mod;
}
return res;
}
struct Kuio{
int l,r,v;
}tmp[maxn];
void Copy(int l1,int r1,int l2,int r2){
set<node>::iterator itr=spilit(r1+1),itl=spilit(l1);
memset(tmp,0,sizeof(tmp));
int cnt=0;
for(;itl!=itr;itl++){
tmp[++cnt].l=itl->l;
tmp[cnt].r=itl->r;
tmp[cnt].v=itl->v;
}
itr=spilit(r2+1),itl=spilit(l2);
ODT.erase(itl,itr);
for(int i=1;i<=cnt;i++) ODT.insert(node(tmp[i].l-l1+l2,tmp[i].r-l1+l2,tmp[i].v));
}
void Swap(int l1,int r1,int l2,int r2){
Copy(l1,r1,n+1,n+r1-l1+1);
Copy(l2,r2,l1,r1);
Copy(n+1,n+r1-l1+1,l2,r2);
}
void Reverse(int l,int r){
set<node>::iterator itr=spilit(r+1),itl=spilit(l);
memset(tmp,0,sizeof(tmp));
int cnt=0;
for(;itl!=itr;itl++){
tmp[++cnt].l=itl->l;
tmp[cnt].r=itl->r;
tmp[cnt].v=itl->v;
}
ODT.erase(itl,itr);
for(int i=1;i<=cnt;i++) ODT.insert(node(r-tmp[i].r+l,r-tmp[i].l+l,tmp[i].v));
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
ODT.insert(node(i,i,a[i]));
}
ODT.insert(node(n+1,n+1,0));
while(m--){
int op,l,r,k,x,y;
cin>>op>>l>>r;
if(op==1) cout<<sum(l,r)<<endl;
if(op==2){
cin>>k;
bulldoze(l,r,k);
}
if(op==3){
cin>>k;
sectionadd(l,r,k);
}
if(op==4){
cin>>x>>y;
Copy(l,r,x,y);
}
if(op==5){
cin>>x>>y;
Swap(l,r,x,y);
}
if(op==6) Reverse(l,r);
}
for(set<node>::iterator it=ODT.begin();it!=ODT.end() && it->r<=n;it++){
for(int i=it->l;i<=it->r;i++) cout<<it->v<<" ";
}
return 0;
}