#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long LL;
namespace IO_Fast {
#define pb push_back
#define lson rt << 1
#define rson rt << 1 | 1
const int N = 1e3 + 10;
const int Maxn = 2e5 + 10;
const int Mod = 1e9 + 7;
int read() {
int res = 0, f = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) f |= (ch == '-');
for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch - '0');
return f ? -res : res;
}
}
using namespace IO_Fast;
namespace ODT {
struct node {
int l, r;
mutable int v;
node(int L = 0, int R = 0, int V = 0) : l(L), r(R), v(V) {}
bool operator < (const node &x) const {return l < x.l; }
}; set <node> s;
auto split(int pos) {
auto it = s.lower_bound(node(pos));
if(it != s.end() && it -> l == pos) return it;
--it; int L = it->l, R = it->r, V = it->v;
s.erase(it); s.insert(node(L, pos - 1, V));
return s.insert(node(pos, R, V)).first;
}
void Assign(int l, int r, int val) {
auto itr = split(r + 1), itl = split(l);
s.erase(itl, itr); s.insert(node(l, r, val));
}
void Add(int l, int r, int val) {
auto itr = split(r + 1), itl = split(l);
for(auto it = itl; it != itr; ++it) it -> v += val, it->v+=Mod,it->v%=Mod;
}
void Copy(int l, int r, int L, int R) {
vector <node> vec;
auto itr = split(r + 1), itl = split(l);
for(auto it = itl; it != itr; ++it) vec.push_back(node(it->l, it->r, it->v));
auto itR = split(R + 1), itL = split(L);
s.erase(itL, itR);
int Now = L;
for(int i = 0; i < (int)vec.size(); i++) {
int ll = vec[i].l, rr = vec[i].r, vv = vec[i].v;
s.insert(node(Now, Now + rr - ll, vv)), Now = Now + rr - ll + 1;
}
}
void Swap(int l, int r, int L, int R) {
vector <node> vec1, vec2;
auto itr = split(r + 1), itl = split(l);
for(auto it = itl; it != itr; ++it) vec1.push_back(node(it->l, it->r, it->v));
s.erase(itl, itr);
auto itR = split(R + 1), itL = split(L);
for(auto it = itL; it != itR; ++it) vec2.push_back(node(it->l, it->r, it->v));
s.erase(itL, itR);
int Now = L;
for(int i = 0; i < (int)vec1.size(); i++) {
int ll = vec1[i].l, rr = vec1[i].r, vv = vec1[i].v;
s.insert(node(Now, Now + rr - ll, vv)), Now = Now + rr - ll + 1;
}
Now = l;
for(int i = 0; i < (int)vec2.size(); i++) {
int ll = vec2[i].l, rr = vec2[i].r, vv = vec2[i].v;
s.insert(node(Now, Now + rr - ll, vv)), Now = Now + rr - ll + 1;
}
}
void Reverse(int l, int r) {
vector <node> vec;
auto itr = split(r + 1), itl = split(l);
for(auto it = itl; it != itr; ++it) vec.push_back(node(it->l,it->r,it->v));
s.erase(itl, itr);
int Now = r;
for(int i = 0; i < (int)vec.size(); i++) {
int ll = vec[i].l, rr = vec[i].r, vv = vec[i].v;
s.insert(node(Now - rr + ll, Now, vv)), Now = Now - (rr - ll + 1);
}
}
int Query(int l, int r) {
int res = 0;
auto itr = split(r + 1), itl = split(l);
for(auto it = itl; it != itr; ++it) res = (res + Mod + (it->r-it->l+1)*it->v)%Mod;
return res%Mod;
}
}
using namespace ODT;
void Debug(int n) {
for(int i = 1; i <= n; i++) cout << (Query(i,i)+Mod)%Mod<<" ";
cout<<"\n";
}
signed main() {
int n = read(), m = read();
for(int i = 1, x; i <= n; i++) x = read()%Mod, s.insert(node(i,i,x));
s.insert(node(n + 1, n + 5, 0));
while(m--) {
int opt = read();
if(opt == 1) {
int l = read(), r = read();
cout << Query(l, r) << '\n';
}
else if(opt == 2) {
int l = read(), r = read(), val = read();
Assign(l, r, val);
}
else if(opt == 3) {
int l = read(), r = read(), val = read();
Add(l, r, val);
}
else if(opt == 4) {
int l = read(), r = read(), L = read(), R = read();
Copy(l, r, L, R);
}
else if(opt == 5) {
int l = read(), r = read(), L = read(), R = read();
Swap(l, r, L, R);
}
else if(opt == 6) {
int l = read(), r = read();
Reverse(l, r);
}
}
for(int i = 1; i <= n; i++) cout << (Query(i,i)+Mod)%Mod<<" ";
return 0;
}