rt.
#include<bits/stdc++.h>
using namespace std;
int read()
{
int s = 0,w = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-') w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
s = (s << 1) + (s << 3) + (ch ^ 48);
ch = getchar();
}
return s * w;
}
void write(int a)
{
if(a < 0) putchar('-'),a = -a;
if(a > 9) write(a / 10);
putchar(a % 10 + '0');
}
const int N = 3e5 + 10,M = 6e6,mod = 1e9 + 7;
long long n,q,cnt,tmp[N];
long long x,y,z;
long long opt,l,r,l1,r1,l2,r2,k,ans;
struct FHQ
{
long long tot,root;
long long son[M][2],size[M],dat[M],val[M];
long long sum[M],add[M],cov[M];
bool tag[M];
long long New(long long x)
{
tot++;
dat[tot] = rand();
tag[tot] = add[tot] = son[tot][0] = son[tot][1] = 0;
size[tot] = 1,cov[tot] = -1;
sum[tot] = val[tot] = x;
return tot;
}
long long clone(long long p)
{
tot++;
son[tot][0] = son[p][0];
son[tot][1] = son[p][1];
size[tot] = size[p],dat[tot] = dat[p];
val[tot] = val[p],sum[tot] = sum[p];
add[tot] = add[p],cov[tot] = cov[p];
tag[tot] = tag[p];
return tot;
}
void dosth_1(long long p,long long x)
{
val[p] = x;
sum[p] = size[p] * x % mod;
cov[p] = x % mod;
add[p] = 0;
}
void dosth_2(long long p,long long x)
{
val[p] = (val[p] + x) % mod;
sum[p] = (sum[p] + x * size[p] % mod) % mod;
add[p] = (add[p] + x) % mod;
}
void pushup(long long p)
{
size[p] = size[son[p][0]] + size[son[p][1]] + 1;
sum[p] = ((sum[son[p][0]] + sum[son[p][1]]) % mod + val[p]) % mod;
}
void pushdown(long long p)
{
if(tag[p] == 0 && cov[p] == -1 && add[p] == 0) return;
if(son[p][0]) son[p][0] = clone(son[p][0]);
if(son[p][1]) son[p][1] = clone(son[p][1]);
if(tag[p])
{
if(son[p][0]) tag[son[p][0]] ^= 1;
if(son[p][1]) tag[son[p][1]] ^= 1;
swap(son[p][0],son[p][1]),tag[p] = 0;
}
if(cov[p] != -1)
{
if(son[p][0]) dosth_1(son[p][0],cov[p]);
if(son[p][1]) dosth_1(son[p][1],cov[p]);
cov[p] = -1;
}
if(add[p])
{
if(son[p][0]) dosth_2(son[p][0],add[p]);
if(son[p][1]) dosth_2(son[p][1],add[p]);
add[p] = 0;
}
}
void split(long long p,long long k,long long &x,long long &y)
{
if(p == 0){x = y = 0;return;}
pushdown(p);
if(size[son[p][0]] >= k)
{
y = clone(p);
split(son[p][0],k,x,son[y][0]);
pushup(y);
}
else
{
x = clone(p);
split(son[p][1],k - 1 - size[son[p][0]],son[x][1],y);
pushup(x);
}
}
int merge(int x,int y)
{
if(x == 0 || y == 0) return x + y;
if(dat[x] < dat[y])
{
x = clone(x);
pushdown(x);
son[x][1] = merge(son[x][1],y);
pushup(x);
return x;
}
else
{
y = clone(y);
pushdown(y);
son[y][0] = merge(x,son[y][0]);
pushup(y);
return y;
}
}
long long build(long long l,long long r)
{
if(l > r) return 0;
long long mid = l + r >> 1;
long long k = New(tmp[mid]);
son[k][0] = build(l,mid - 1);
son[k][1] = build(mid + 1,r);
pushup(k);
return k;
}
void dfs(long long p)
{
pushdown(p);
if(son[p][0]) dfs(son[p][0]);
tmp[++cnt] = val[p];
if(son[p][1]) dfs(son[p][1]);
}
long long Query_Sum(long long l,long long r)
{
split(root,r,x,z);
split(x,l - 1,x,y);
long long ans = sum[y];
root = merge(merge(x,y),z);
return ans;
}
long long Cover(long long l,long long r,long long k)
{
split(root,r,x,z);
split(x,l - 1,x,y);
y = clone(y);
dosth_1(y,k);
root = merge(merge(x,y),z);
}
long long Add(long long l,long long r,long long k)
{
split(root,r,x,z);
split(x,l - 1,x,y);
y = clone(y);
dosth_2(y,k);
root = merge(merge(x,y),z);
}
void Copy(long long l1,long long r1,long long l2,long long r2)
{
bool flag = 0;
if(l1 > l2) swap(l1,l2),swap(r1,r2),flag = 1;
long long x,y,z,u,v;
split(root,r2,x,v);
split(x,l2 - 1,x,u);
split(x,r1,x,z);
split(x,l1 - 1,x,y);
if(flag) y = clone(u);
else u = clone(y);
root = merge(merge(merge(merge(x,y),z),u),v);
}
void Swap(long long l1,long long r1,long long l2,long long r2)
{
if(l1 > l2) swap(l1,l2),swap(r1,r2);
long long x,y,z,u,v;
split(root,r2,x,v);
split(x,l2 - 1,x,u);
split(x,r1,x,z);
split(x,l1 - 1,x,y);
y = clone(y),u = clone(u);
swap(y,u);
root = merge(merge(merge(merge(x,y),z),u),v);
}
void Reverse(long long l,long long r)
{
split(root,r,x,z);
split(x,l - 1,x,y);
y = clone(y);
tag[y] ^= 1;
root = merge(merge(x,y),z);
}
}tree;
int main()
{
// freopen("input.in","r",stdin);
n = read(),q = read();
for(int i = 1;i <= n;i++) tmp[i] = read();
tree.root = tree.build(1,n);
cnt = 0,tree.dfs(tree.root);
while(q--)
{
opt = read();
if(opt == 1)
{
l = read() ^ ans,r = read() ^ ans;
ans = tree.Query_Sum(l,r);
cout << ans << endl;
}
if(opt == 2)
{
l = read() ^ ans,r = read() ^ ans,k = read() ^ ans;
tree.Cover(l,r,k);
}
if(opt == 3)
{
l = read() ^ ans,r = read() ^ ans,k = read() ^ ans;
tree.Add(l,r,k);
}
if(opt == 4)
{
l1 = read() ^ ans,r1 = read() ^ ans,l2 = read() ^ ans,r2 = read() ^ ans;
tree.Copy(l1,r1,l2,r2);
}
if(opt == 5)
{
l1 = read() ^ ans,r1 = read() ^ ans,l2 = read() ^ ans,r2 = read() ^ ans;
tree.Swap(l1,r1,l2,r2);
}
if(opt == 6)
{
l = read() ^ ans,r = read() ^ ans;
tree.Reverse(l,r);
}
if(tree.tot + 4e5 >= M)
{
cnt = 0,tree.dfs(tree.root);
tree.root = tree.tot = 0;
tree.root = tree.build(1,n);
}
}
cnt = 0;
tree.dfs(tree.root);
for(int i = 1;i <= n;i++) cout << tmp[i] << " ";cout << endl;
return 0;
}