#include<bits/stdc++.h>
#define int long long
#define It set<odt>::iterator
using namespace std;
const int mod=1e9+7;
int n,m,op,l,r,x,y,tot,Tot;
struct odt{
int l,r;
mutable int val;
bool operator <(const odt &n)const{
return l<n.l;
}
odt(int a,int b,int c){
l=a,r=b,val=c;
}
odt(int a){l=a;}
};
struct node{
int len,x;
}cnt[300010],Cnt[300010];
set<odt>tree;
It split(int x){
It it=tree.lower_bound(odt(x));
if(it!=tree.end()&&it->l==x)return it;
it--;
int l=it->l,r=it->r,val=it->val;
tree.erase(it);
tree.insert(odt(l,x-1,val));
return tree.insert(odt(x,r,val)).first;
}
void rvs(int l,int r,int x){
It it2=split(r+1),it1=split(l);
tree.erase(it1,it2);
tree.insert(odt(l,r,x));
}
void add(int l,int r,int x){
It it2=split(r+1),it1=split(l);
for(It it=it1;it!=it2;it++)
it->val=(it->val+x)%mod;
}
int Qry(int l,int r){
It it2=split(r+1),it1=split(l);
int ans=0;
for(It it=it1;it!=it2;it++)
ans=(it->val*(it->r-it->l+1)%mod+ans)%mod;
return ans;
}
void cvr(int l,int r,int x,int y){
It it2=split(r+1),it1=split(l);
tot=0;
for(It it=it1;it!=it2;it++)
++tot,cnt[tot].len=it->r-it->l+1,cnt[tot].x=it->val;
It it4=split(y+1),it3=split(x);
tree.erase(it3,it4);
for(int i=1,L=x;i<=tot;L+=cnt[i].len,i++)
tree.insert(odt(L,L+cnt[i].len-1,cnt[i].x));
}
void swp(int l,int r,int x,int y){
It it2=split(r+1),it1=split(l);
tot=0;
for(It it=it1;it!=it2;it++)
++tot,cnt[tot].len=it->r-it->l+1,cnt[tot].x=it->val;
tree.erase(it1,it2);
It it4=split(y+1),it3=split(x);
Tot=0;
for(It it=it3;it!=it4;it++)
++Tot,Cnt[Tot].len=it->r-it->l+1,Cnt[Tot].x=it->val;
tree.erase(it3,it4);
for(int i=1,L=x;i<=tot;L+=cnt[i].len,i++)
tree.insert(odt(L,L+cnt[i].len-1,cnt[i].x));
for(int i=1,L=l;i<=Tot;L+=Cnt[i].len,i++)
tree.insert(odt(L,L+Cnt[i].len-1,Cnt[i].x));
}
void trn(int l,int r){
It it2=split(r+1),it1=split(l);
tot=0;
for(It it=it1;it!=it2;it++)
++tot,cnt[tot].len=it->r-it->l+1,cnt[tot].x=it->val;
tree.erase(it1,it2);
for(int i=tot,L=l;i>=1;L+=cnt[i].len,i--)
tree.insert(odt(L,L+cnt[i].len-1,cnt[i].x));
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&l),tree.insert(odt(i,i,l));
tree.insert(odt(n+1,n+1,-1));
while(m--){
scanf("%lld",&op);
if(op==1){
scanf("%lld%lld",&l,&r);
printf("%lld\n",Qry(l,r));
}
if(op==2){
scanf("%lld%lld%lld",&l,&r,&x);
rvs(l,r,x);
}
if(op==3){
scanf("%lld%lld%lld",&l,&r,&x);
add(l,r,x);
}
if(op==4){
scanf("%lld%lld%lld%lld",&l,&r,&x,&y);
cvr(l,r,x,y);
}
if(op==5){
scanf("%lld%lld%lld%lld",&l,&r,&x,&y);
swp(l,r,x,y);
}
if(op==6){
scanf("%lld%lld",&l,&r);
trn(l,r);
}
}
for(It it=tree.begin();it!=tree.end();it++)
for(int i=it->l;i<=it->r;i++)
if(it->val!=-1)
printf("%lld ",it->val);
return 0;
}