#include <bits/stdc++.h>
using namespace std;
struct node
{
int l, r;
mutable long long v;
node(int L, int R = 0, long long V = 0) : l(L), r(R), v(V) {}
bool operator < (const node& o) const
{
return l < o.l;
}
};
const long long mod = 1e9 + 7;
int n, m;
long long a[100005];
set<node> s;
vector<node> tmp, tmp2;
set<node>::iterator split(int pos)
{
set<node>::iterator it = s.lower_bound(node(pos));
if (it != s.end() && it -> l == pos)
{
return it;
}
it --;
if (it -> r < pos)
{
return s.end();
}
int l = it -> l;
int r = it -> r;
long long v = it -> v;
s.erase(it);
s.insert(node(l, pos - 1, v));
return s.insert(node(pos, r, v)).first;
}
void add(int l, int r, long long val)
{
set<node>::iterator it2 = split(r + 1), it1 = split(l);
for ( ; it1 != it2 ; it1 ++)
{
it1 -> v += val;
}
}
void assign(int l, int r, long long val)
{
set<node>::iterator it2 = split(r + 1), it1 = split(l);
s.erase(it1, it2);
s.insert(node(l, r, val));
}
long long sum(int l, int r)
{
set<node>::iterator it2 = split(r + 1), it1 = split(l);
long long ans = 0;
for ( ; it1 != it2 ; it1 ++)
{
ans = (ans % mod + (it1 -> r - it1 -> l + 1) * it1 -> v % mod) % mod;
}
return ans;
}
void cpy(int l, int r, int l2, int r2)
{
set<node>::iterator it2 = split(r + 1), it1 = split(l);
for ( ; it1 != it2 ; it1 ++)
{
tmp.push_back(node(it1 -> l, it1 -> r, it1 -> v));
}
set<node>::iterator it4 = split(r2 + 1), it3 = split(l2);
s.erase(it3, it4);
for (int i = 0 ; i < tmp.size() ; i ++)
{
s.insert(node(tmp[i].l - l + l2, tmp[i].r - r + r2, tmp[i].v));
}
tmp.clear();
}
void exc(int l, int r, int l2, int r2)
{
set<node>::iterator it2 = split(r + 1), it1 = split(l);
for (set<node>::iterator it = it1 ; it != it2 ; it ++)
{
tmp.push_back(node(it -> l, it -> r, it -> v));
}
set<node>::iterator it4 = split(r2 + 1), it3 = split(l2 + 1);
for (set<node>::iterator it = it3 ; it != it4 ; it ++)
{
tmp2.push_back(node(it -> l, it -> r, it -> v));
}
s.erase(it1, it2);
s.erase(it3, it4);
for (int i = 0 ; i < tmp.size() ; i ++)
{
s.insert(node(tmp[i].l + l - l2, tmp[i].r + l - l2, tmp[i].v));
}
for (int i = 0 ; i < tmp2.size() ; i ++)
{
s.insert(node(tmp2[i].l + l2 - l, tmp2[i].r + r2 - r, tmp2[i].v));
}
tmp.clear();
tmp2.clear();
}
void rev(int l, int r)
{
set<node>::iterator it2 = split(r + 1), it1 = split(l);
for (set<node>::iterator it = it1 ; it != it2 ; it ++)
{
tmp.push_back(node(it -> l, it -> r, it -> v));
}
s.erase(it1, it2);
for (int i = 0 ; i < tmp.size() ; i ++)
{
s.insert(node(l + r - tmp[i].r, l + r - tmp[i].l, tmp[i].v));
}
tmp.clear();
}
int main()
{
cin >> n >> m;
for (int i = 1 ; i <= n ; i ++)
{
cin >> a[i];
s.insert(node(i, i, a[i]));
}
while (m --)
{
int opt, l, r;
cin >> opt >> l >> r;
if (opt == 1)
{
cout << sum(l, r) << endl;
}
else if (opt == 2)
{
long long x;
cin >> x;
assign(l, r, x);
}
else if (opt == 3)
{
long long x;
cin >> x;
add(l, r, x);
}
else if (opt == 4)
{
int l2, r2;
cin >> l2 >> r2;
cpy(l, r, l2, r2);
}
else if (opt == 5)
{
int l2, r2;
cin >> l2 >> r2;
exc(l, r, l2, r2);
}
else if (opt == 6)
{
rev(l, r);
}
}
set<node>::iterator it2 = split(n + 1), it1 = split(1);
for ( ; it1 != it2 ; it1 ++)
{
for (int i = 1 ; i <= it1 -> r - it1 -> l + 1 ; i ++)
{
cout << it1 -> v << " ";
}
}
}