#include <iostream>
#include <vector>
using namespace std;
class fastIO{private:char ibuf[50007],*p1=ibuf,*p2=ibuf,obuf[50007],*p3=obuf,sta[50];bool file_end=false;char get(){return p1==p2&&(p2=(p1=ibuf)+fread(ibuf,1,50007,stdin),p1==p2)?(file_end=true),char(EOF):*p1++;}void put(const char x){p3-obuf<50007?*p3++=x:(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x);}public:explicit operator bool(){return!file_end;}size_t flush(){size_t f=fwrite(obuf,p3-obuf,1,stdout);p3=obuf;*p3=0;return f;}fastIO&operator>>(char&t){for(t=get();!isgraph(t);t=get()){;}return*this;}template<typename any>typename std::enable_if<std::is_same<any,char>::value,any>::type tpval(){char t;for(t=get();!isgraph(t);t=get()){;}return t;}fastIO&operator>>(char*t){char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())*t=c,t++;*t=0;return*this;}fastIO&operator>>(std::string&t){t.clear();char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())t+=c;return*this;}template<typename any>typename std::enable_if<std::is_same<any,std::string>::value,any>::type tpval(){std::string t;char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())t+=c;return t;}template<typename any>typename std::enable_if<(std::is_signed<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__int128_t>::value,fastIO>::type&operator>>(any&t){t=0;bool y=0;char c=get();for(;!isdigit(c);c=get())if(c==45)y=true;for(;isdigit(c);c=get())t=t*10+c-48;if(y==1)t=-t;return*this;}template<typename any>typename std::enable_if<(std::is_signed<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__int128_t>::value,any>::type tpval(){any t=0;bool y=0;char c=get();for(;!isdigit(c);c=get())if(c==45)y=true;for(;isdigit(c);c=get())t=t*10+c-48;if(y==1)t=-t;return t;}template<typename any>typename std::enable_if<(std::is_unsigned<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__uint128_t>::value,fastIO>::type&operator>>(any&t){t=0;char c=get();for(;!isdigit(c);c=get()){;}for(;isdigit(c);c=get())t=t*10+c-48;return*this;}template<typename any>typename std::enable_if<(std::is_unsigned<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__uint128_t>::value,any>::type tpval(){any t=0;char c=get();for(;!isdigit(c);c=get()){;}for(;isdigit(c);c=get())t=t*10+c-48;return t;}template<typename any1,typename any2>fastIO&operator>>(std::pair<any1,any2>&t){return*this>>t.first>>t.second;}template<typename any1,typename any2>std::pair<any1,any2>tpval(){return std::pair<any1,any2>(tpval<any1>(),tpval<any2>());}template<typename any>fastIO&read(any&t){return*this>>t;}fastIO&read(char*t){char c;for(c=get();!isgraph(c);c=get()){;}for(;isgraph(c);c=get())*t=c,t++;*t=0;return*this;}template<typename any,typename...args>fastIO&read(any&t1,args&...t2){return(*this>>t1).read(t2...);}fastIO&operator<<(const char t){put(t);return*this;}fastIO&operator<<(const char*t){for(;*t;t++)put(*t);return*this;}fastIO&operator<<(const std::string&t){for(const char it:t)put(it);return*this;}template<typename any>typename std::enable_if<(std::is_signed<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__int128_t>::value,fastIO>::type&operator<<(any t){if(!t){put(48);return*this;}int len=0;if(t<0)t=-t,put(45);while(t)sta[len++]=char(t%10+48),t/=10;while(len--)put(sta[len]);return*this;}template<typename any>typename std::enable_if<(std::is_unsigned<any>::value&&std::is_integral<any>::value&&!std::is_same<any,char>::value)||std::is_same<any,__uint128_t>::value,fastIO>::type&operator<<(any t){if(!t){put(48);return*this;}int len=0;while(t)sta[len++]=char(t%10+48),t/=10;while(len--)put(sta[len]);return*this;}template<typename any1,typename any2>fastIO&operator<<(const std::pair<any1,any2>&t){return*this<<t.first<<' '<<t.second;}template<typename any>fastIO&write(const any&t){return*this<<t;}template<typename any,typename...args>fastIO&write(const any&t1,const args&...t2){return(*this<<t1).write(t2...);}~fastIO(){fwrite(obuf,p3-obuf,1,stdout);}}fio;
class SegmentTree {
private:
struct Node {
int sum;
int toAssign;
bool flip;
};
vector<Node> tree;
int n;
inline void push(int node, int start, int end) {
if (tree[node].toAssign != -1) {
tree[node].sum = (end - start + 1) * tree[node].toAssign;
if (start != end) {
tree[(node << 1) + 1].toAssign = tree[node].toAssign;
tree[(node << 1) + 2].toAssign = tree[node].toAssign;
tree[(node << 1) + 1].flip = false;
tree[(node << 1) + 2].flip = false;
}
tree[node].toAssign = -1;
}
if (tree[node].flip) {
tree[node].sum = (end - start + 1) - tree[node].sum;
if (start != end) {
if (tree[(node << 1) + 1].toAssign == -1) {
tree[(node << 1) + 1].flip = !tree[(node << 1) + 1].flip;
} else {
tree[(node << 1) + 1].toAssign = 1 - tree[(node << 1) + 1].toAssign;
}
if (tree[(node << 1) + 2].toAssign == -1) {
tree[(node << 1) + 2].flip = !tree[(node << 1) + 2].flip;
} else {
tree[(node << 1) + 2].toAssign = 1 - tree[(node << 1) + 2].toAssign;
}
}
tree[node].flip = false;
}
}
void build(const vector<int>& arr, int node, int start, int end) {
if (start == end) {
tree[node].sum = arr[start];
tree[node].toAssign = -1;
tree[node].flip = false;
return;
}
int mid = (start + end) >> 1;
build(arr, (node << 1) + 1, start, mid);
build(arr, (node << 1) + 2, mid + 1, end);
tree[node].sum = tree[(node << 1) + 1].sum + tree[(node << 1) + 2].sum;
tree[node].toAssign = -1;
tree[node].flip = false;
}
void updateAssign(int node, int start, int end, int l, int r, int value) {
push(node, start, end);
if (start > r || end < l) return;
if (start >= l && end <= r) {
tree[node].toAssign = value;
push(node, start, end);
return;
}
int mid = (start + end) >> 1;
updateAssign((node << 1) + 1, start, mid, l, r, value);
updateAssign((node << 1) + 2, mid + 1, end, l, r, value);
tree[node].sum = tree[(node << 1) + 1].sum + tree[(node << 1) + 2].sum;
}
void updateFlip(int node, int start, int end, int l, int r) {
push(node, start, end);
if (start > r || end < l) return;
if (start >= l && end <= r) {
tree[node].flip = true;
push(node, start, end);
return;
}
int mid = (start + end) >> 1;
updateFlip((node << 1) + 1, start, mid, l, r);
updateFlip((node << 1) + 2, mid + 1, end, l, r);
tree[node].sum = tree[(node << 1) + 1].sum + tree[(node << 1) + 2].sum;
}
int querySum(int node, int start, int end, int l, int r) {
push(node, start, end);
if (start > r || end < l) return 0;
if (start >= l && end <= r) {
return tree[node].sum;
}
int mid = (start + end) >> 1;
int leftSum = querySum((node << 1) + 1, start, mid, l, r);
int rightSum = querySum((node << 1) + 2, mid + 1, end, l, r);
return leftSum + rightSum;
}
public:
SegmentTree(const vector<int>& arr) {
n = arr.size();
tree.resize(4 * n);
build(arr, 0, 0, n - 1);
}
inline void updateAssign(int l, int r, int value) {
updateAssign(0, 0, n - 1, l, r, value);
}
inline void updateFlip(int l, int r) {
updateFlip(0, 0, n - 1, l, r);
}
inline int querySum(int l, int r) {
return querySum(0, 0, n - 1, l, r);
}
};
vector<int> g[20];
vector<SegmentTree> st;
int main() {
int n, m;
fio>> n >> m;
for (register int i = 1; i <= n; i++) {
int tmp;
fio >> tmp;
for (register int j = 0; j <= 19; j++, tmp /= 2) {
g[j].push_back(tmp & 1);
}
}
for (register int i = 0; i <= 19; i++) {
SegmentTree tmp(g[i]);
st.push_back(tmp);
}
while (m--) {
int op, l, r;
fio >> op >> l >> r;
l--;
r--;
if (op == 1) {
int tmp;
fio >> tmp;
for (register int j = 0; j <= 19; j++, tmp /= 2) {
st[j].updateAssign(l, r, (tmp & 1));
}
} else if (op == 2) {
int tmp;
fio >> tmp;
for (register int j = 0; j <= 19; j++, tmp /= 2) {
if (tmp & 1) {
st[j].updateFlip(l, r);
}
}
} else if (op == 3) {
long long ans = 0;
for (register int j = 0, x = 1; j <= 19; j++, (x *= 2)) {
ans = ans + (long long) st[j].querySum(l, r) * x;
}
fio << ans << "\n";
}else if (op == 4) {
long long ans = 0;
for (register int j = 0, x = 1; j <= 19; j++, (x *= 2)) {
int tmp = st[j].querySum(l, r);
ans = ans + (long long) tmp * (r - l + 1 - tmp) * x;
}
fio << ans << "\n";
}
}
return 0;
}