#include <bits/extc++.h>
#include<ext/rope>
using namespace __gnu_cxx;
using namespace std;
#define ll long long
#define ull unsigned ll
#define ui unsigned int
#define i128 __int128
#define lid (id << 1)
#define rid (id << 1 | 1)
const int N = 5e5+5;
#ifdef ONLINE_JUDGE
#define cin IO::InputHelper::get_instance()
#define cout IO::OutputHelper::get_instance()
#define INPUT_FILE ""
#define OUTPUT_FILE ""
namespace IO {
using size_type = size_t;
static constexpr size_type INPUT_BUFFER_SIZE = 1 << 16, OUTPUT_BUFFER_SIZE = 1 << 16, MAX_INTEGER_SIZE = 20, MAX_FLOAT_SIZE = 50;static constexpr char input_file[] = INPUT_FILE, output_file[] = OUTPUT_FILE;
struct InputHelper {
FILE *m_file_ptr;char m_buf[INPUT_BUFFER_SIZE], *m_end, *m_cursor;bool m_ok;
InputHelper &set_bad() { return m_ok = false, *this; }
template <size_type BlockSize>
void _reserve() {size_type a = m_end - m_cursor;if (a >= BlockSize) return;memmove(m_buf, m_cursor, a), m_cursor = m_buf;size_type b = a + fread(m_buf + a, 1, INPUT_BUFFER_SIZE - a, m_file_ptr);if (b < INPUT_BUFFER_SIZE) m_end = m_buf + b, *m_end = EOF;}
template <typename Tp, typename BinaryOperation>
InputHelper &fill_integer(Tp &ret, BinaryOperation op) {if (!isdigit(*m_cursor)) return set_bad();ret = op(Tp(0), *m_cursor - '0');size_type len = 1;while (isdigit(*(m_cursor + len))) ret = op(ret * 10, *(m_cursor + len++) - '0');m_cursor += len;return *this;}
explicit InputHelper(const char *inputFileName) : m_ok(true), m_cursor(m_buf + INPUT_BUFFER_SIZE), m_end(m_buf + INPUT_BUFFER_SIZE) { m_file_ptr = *inputFileName ? fopen(inputFileName, "rt") : stdin; }
~InputHelper() { fclose(m_file_ptr); }
static InputHelper &get_instance() {static InputHelper s_obj(input_file);return s_obj;}
static bool is_blank(char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r'; }static bool is_endline(char c) { return c == '\n' || c == EOF; }
const char &getchar_checked() {_reserve<1>();return *m_cursor;}const char &getchar_unchecked() const { return *m_cursor; }
void next() { ++m_cursor; }
template <typename Tp, typename std::enable_if<std::is_signed<Tp>::value & std::is_integral<Tp>::value>::type * = nullptr>
InputHelper &operator>>(Tp &num) {while (is_blank(getchar_checked())) next();_reserve<MAX_INTEGER_SIZE>();if (getchar_unchecked() != '-') return fill_integer(num, std::plus<Tp>());next();return fill_integer(num, std::minus<Tp>());}
template <typename Tp, typename std::enable_if<std::is_unsigned<Tp>::value & std::is_integral<Tp>::value>::type * = nullptr>
InputHelper &operator>>(Tp &num) {while (is_blank(getchar_checked())) next();_reserve<MAX_INTEGER_SIZE>();return fill_integer(num, std::plus<Tp>());}
template <typename Tp, typename std::enable_if<std::is_floating_point<Tp>::value>::type * = nullptr>
InputHelper &operator>>(Tp &num) {
bool neg = false, integer = false, decimal = false;while (is_blank(getchar_checked())) next();_reserve<MAX_FLOAT_SIZE>();
if (getchar_unchecked() == '-') {neg = true;next();}if (!isdigit(getchar_unchecked()) && getchar_unchecked() != '.') return set_bad();
if (isdigit(getchar_unchecked())) {integer = true;num = getchar_unchecked() - '0';while (next(), isdigit(getchar_unchecked())) num = num * 10 + (getchar_unchecked() - '0');}
if (getchar_unchecked() == '.') if (next(), isdigit(getchar_unchecked())) {if (!integer) num = 0;decimal = true;Tp unit = 0.1;num += unit * (getchar_unchecked() - '0');while (next(), isdigit(getchar_unchecked())) num += (unit *= 0.1) * (getchar_unchecked() - '0');}
if (!integer && !decimal) return set_bad();if (neg) num = -num;return *this;
}
InputHelper &operator>>(char &c) {while (is_blank(getchar_checked())) next();if (getchar_checked() == EOF) return set_bad();c = getchar_checked(), next();return *this;}
InputHelper &operator>>(std::string &s) {while (is_blank(getchar_checked())) next();if (getchar_checked() == EOF) return set_bad();s.clear();do {s += getchar_checked();next();} while (!is_blank(getchar_checked()) && getchar_unchecked() != EOF);return *this;}
explicit operator bool() { return m_ok; }
};
struct OutputHelper {
FILE *m_file_ptr = nullptr;char m_buf[OUTPUT_BUFFER_SIZE], *m_end, *m_cursor;char m_temp_buf[MAX_FLOAT_SIZE], *m_temp_buf_cursor, *m_temp_buf_dot;uint64_t m_float_reserve, m_float_ratio;
void _write() { fwrite(m_buf, 1, m_cursor - m_buf, m_file_ptr), m_cursor = m_buf; }
template <size_type BlockSize> void _reserve() {size_type a = m_end - m_cursor;if (a >= BlockSize) return;_write();}
OutputHelper(const char *outputFileName, size_type prec = 6) : m_cursor(m_buf), m_end(m_buf + OUTPUT_BUFFER_SIZE), m_temp_buf_cursor(m_temp_buf) { m_file_ptr = *outputFileName ? fopen(outputFileName, "wt") : stdout, precision(prec); }
static OutputHelper &get_instance() {static OutputHelper s_obj(output_file);return s_obj;}
~OutputHelper() { flush(), fclose(m_file_ptr); }
void precision(size_type prec) { m_float_reserve = prec, m_float_ratio = uint64_t(std::pow(10, prec)), m_temp_buf_dot = m_temp_buf + prec; }
OutputHelper &flush() { return _write(), fflush(m_file_ptr), *this; }
void putchar(const char &c) {if (m_cursor == m_end) _write();*m_cursor++ = c;}
template <typename Tp, typename std::enable_if<std::is_signed<Tp>::value & std::is_integral<Tp>::value>::type * = nullptr>
OutputHelper &operator<<(Tp ret) {_reserve<MAX_INTEGER_SIZE>();size_type len = 0;if (ret >= 0) do *(m_cursor + len++) = '0' + ret % 10, ret /= 10;while (ret);else {putchar('-');do *(m_cursor + len++) = '0' - ret % 10, ret /= 10;while (ret);}for (size_type i = 0, j = len - 1; i < j;) std::swap(*(m_cursor + i++), *(m_cursor + j--));m_cursor += len;return *this;}
template <typename Tp, typename std::enable_if<std::is_unsigned<Tp>::value & std::is_integral<Tp>::value>::type * = nullptr>
OutputHelper &operator<<(Tp ret) {_reserve<MAX_INTEGER_SIZE>();size_type len = 0;do *(m_cursor + len++) = '0' + ret % 10, ret /= 10;while (ret);for (size_type i = 0, j = len - 1; i < j;) std::swap(*(m_cursor + i++), *(m_cursor + j--));m_cursor += len;return *this;}
template <typename Tp, typename std::enable_if<std::is_floating_point<Tp>::value>::type * = nullptr>
OutputHelper &operator<<(Tp ret) {
if (ret < 0) {putchar('-');return *this << -ret;}ret *= m_float_ratio;uint64_t integer = ret;if (ret - integer >= 0.4999999999) integer++;do {*m_temp_buf_cursor++ = '0' + integer % 10;integer /= 10;} while (integer);
if (m_temp_buf_cursor > m_temp_buf_dot) {do putchar(*--m_temp_buf_cursor);while (m_temp_buf_cursor > m_temp_buf_dot);putchar('.');}else {putchar('0'), putchar('.');for (size_type i = m_temp_buf_dot - m_temp_buf_cursor; i--;) putchar('0');}
do putchar(*--m_temp_buf_cursor);while (m_temp_buf_cursor > m_temp_buf);
return *this;
}
OutputHelper &operator<<(const char &ret) {putchar(ret);return *this;}
OutputHelper &operator<<(const char *ret) {while (*ret) putchar(*ret++);return *this;}
OutputHelper &operator<<(const std::string &ret) { return *this << ret.data(); }
};
InputHelper &getline(InputHelper &ih, std::string &line) {line.clear();if (ih.getchar_checked() == EOF) return ih.set_bad();while (!InputHelper::is_endline(ih.getchar_checked())) line += ih.getchar_unchecked(), ih.next();if (ih.getchar_unchecked() != EOF) ih.next();return ih;}
}using IO::getline;
#endif
template<uint32_t P>
struct ModInt32{
using mod_type = uint32_t;
using mint = ModInt32;
mod_type val;
ModInt32(mod_type vala = 0) : val(vala) {}
static inline mint raw(mod_type val){mint res;res.val = val;return res;}
inline mint pow(uint64_t b){mod_type res = 1, a = val;while (b){if (b & 1) res = uint64_t(res) * a % P;a = uint64_t(a) * a % P;b >>= 1;}return res;}
inline mint inv(){return pow(P - 2);}
inline mint &operator ++(){if (++val == P) val = 0;return *this;}
inline mint &operator --(){if (!val) val = P;return *this;}
inline mint &operator +=(const mint &b){if ((val += b.val) >= P) val -= P;return *this;}
inline mint &operator -=(const mint &b){if ((val += P - b.val) >= P) val -= P;return *this;}
inline mint &operator *=(const mint &b){val = uint64_t(val) * b.val % P;return *this;}
inline mint operator +(const mint &b){return mint(*this) += b;}
inline mint operator -(const mint &b){return mint(*this) -= b;}
inline mint operator *(const mint &b){return mint(*this) *= b;}
inline bool operator ==(const mint &b){return val == b.val;}
inline bool operator !=(const mint &b){return val != b.val;}
inline bool operator <(const mint &b){return val < b.val;}
inline bool operator <=(const mint &b){return val <= b.val;}
inline bool operator >(const mint &b){return val > b.bal;}
inline bool operator >=(const mint &b){return val >= b.val;}
};
template <typename Istream, uint32_t P>
Istream &operator>>(Istream &is, ModInt32<P> &x) { return is >> x.val; }
template <typename Ostream, uint32_t P>
Ostream &operator<<(Ostream &os, const ModInt32<P> &x) { return os << x.val; }
random_device seed;
mt19937 rnd(seed());
mt19937_64 rnd_64(seed());
namespace tianyu{
using mint = ModInt32<1000000007>;
struct node{
int l, r;mutable mint v;
node(int L = 0, int R = 0, mint V = 0) : l(L), r(R), v(V) {}
inline bool operator <(const node &b)const{return l < b.l;}
};set<node>odt;
auto split(int x){
auto pos = odt.lower_bound({x, 0, 0});
if (pos != odt.end() && pos->l == x) return pos;
--pos;
int l = pos->l, r = pos->r;mint v = pos->v;
odt.erase(pos), odt.insert({l, x - 1, v});
return odt.insert({x, r, v}).first;
}
void assign(int l, int r, mint v){
auto pr = split(r + 1), pl = split(l);
odt.erase(pl, pr), odt.insert({l, r, v});
}
mint query(int l, int r){
auto pr = split(r + 1), pl = split(l);mint res = 0;
for (;pl != pr;++pl) res += pl->v * (pl->r - pl->l + 1);
return res;
}
void add(int l, int r, mint v){
auto pr = split(r + 1), pl = split(l);
for (;pl != pr;++pl) pl->v += v;
}
node a[N], b[N];
void copy(int l1, int r1, int l2, int r2){
auto pr2 = split(r2 + 1), pl2 = split(l2);
odt.erase(pl2, pr2);
auto pr1 = split(r1 + 1), pl1 = split(l1);
int d = l2 - l1;
for (;pl1 != pr1;++pl1) odt.insert({pl1->l + d, pl1->r + d, pl1->v});
}
void reverse(int l, int r){
auto pr = split(r + 1), pl = split(l);
int len = 0;
for (auto i = pl;i != pr;++i) a[++len] = *i;
odt.erase(pl, pr);
for (;len;--len) odt.insert({r - a[len].r + l, r - a[len].l + l, a[len].v});
}
void swap1(int l1, int r1, int l2, int r2){
if (l1 > l2) swap(l1, l2), swap(r1, r2);
int len1 = 0, len2 = 0;
auto pr = split(r1 + 1), pl = split(l1);
for (auto i = pl;i != pr;++i) a[++len1] = *i;
odt.erase(pl, pr);
pr = split(r2 + 1), pl = split(l2);
for (auto i = pl;i != pr;++i) b[++len2] = *i;
odt.erase(pl, pr);
int d = l2 - l1;
for (;len1;--len1) odt.insert({a[len1].l + d, a[len1].r + d, a[len1].v});
for (;len2;--len2) odt.insert({b[len2].l - d, b[len2].r - d, b[len2].v});
}
int n, q;
void print(){
for (auto i : odt){
if (i.l == n + 1) break;
for (int j = i.l;j <= i.r;j++) cout << i.v << ' ';
}cout << '\n';
}
void awa(){
cin >> n >> q;
for (int i = 1;i <= n;i++){
int x;
cin >> x;
odt.insert({i, i, mint(x)});
}
odt.insert({n + 1, n + 1, mint(0)});
while (q--){
int op, l, r;
cin >> op >> l >> r;
if (l > r) swap(l, r);
if (op == 1){
cout << query(l, r) << '\n';
}
if (op == 2){
mint v;
cin >> v;
assign(l, r, v);
}
if (op == 3){
mint v;
cin >> v;
add(l, r, v);
}
if (op == 4){
int l2, r2;
cin >> l2 >> r2;
if (l2 > r2) swap(l2, r2);
copy(l, r, l2, r2);
}
if (op == 5){
int l2, r2;
cin >> l2 >> r2;
if (l2 > r2) swap(l2, r2);
swap1(l, r, l2, r2);
}
if (op == 6){
reverse(l, r);
}
}
print();
}
}
signed main(){
int T = 1;
while (T--) tianyu::awa();
return 0;
}