//#pragma GCC optimize("fast-math")
//#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
#define all(x) (x).begin(),(x).end()
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
//#define int ll
#define sz(x) ((int)(x).size())
using pii = pair<ull,ull>;
using tii = tuple<int,int,int>;
const int bmax = 64;
namespace Basis {
ull pivot[bmax];
ull contrmsk[bmax];
ull control = 0;
ull flippers = 0;
int upd = -1;
bool add(ull x) {
upd = -1;
for(int i = bmax - 1; i >= 0; i--) {
if(pivot[i] == 0 && ((1ull << i) & x)) {
pivot[i] = x;
upd = i;
break;
}
else if(pivot[i] != 0 && ((1ull << i) & x))
x ^= pivot[i];
}
if(x == 0) return 0;
for(int i = 0; i < bmax; i++) {
if(pivot[i] == 0) continue;
for(int j = i + 1; j < bmax; j++) {
if(pivot[j] & (1ull << i))
pivot[j] ^= pivot[i];
}
}
control = 0;
flippers = 0;
for(int contra = 0; contra < bmax; contra++) {
contrmsk[contra] = 0;
if(pivot[contra] != 0) {
control |= (1ull << contra);
continue;
}
for(int i = contra + 1; i < bmax; i++)
if(pivot[i] & (1ull << contra)) contrmsk[contra] |= (1ull << i);
if(__builtin_popcountll(contrmsk[contra]) % 2 == 1)
flippers |= (1ull << contra);
}
return 1;
}
ull get_val(ull a) {
ull R = 0;
for(int i = 0; i < bmax; i++) {
if(pivot[i] != 0) continue;
R |= ((ull)((__builtin_popcountll(a & contrmsk[i]) & 1)
^ ((a & (1ull << i))? 1 : 0))) << i;
}
return R;
}
}
const int nmax = 5e5 + 5;
int biti[nmax];
struct Node {
vector<pii> cnt;
ull txor;
int len;
Node() {
cnt.assign(1, pii{~0ull, 0ull});
txor = 0;
len = 1;
}
Node(ull a) {
cnt.assign(1, pii{0ull, 0ull});
txor = a;
len = 0;
}
void pull(Node L, Node R) {
len = L.len + R.len;
cnt.clear();
cnt.reserve(biti[len]);
pii carry = {0, 0};
auto std = [&](int i) -> ull { if(i >= sz(R.cnt)) return 0; return (R.cnt[i].first & (~L.txor)) | (R.cnt[i].second & (L.txor)); };
//auto inv = [&](int i) -> ull { if(i >= sz(R.cnt)) return 0; return (R.cnt[i].first & (L.txor)) | (R.cnt[i].second & (~L.txor)); };
for(int i = 0; i < max(sz(L.cnt), sz(R.cnt)) || carry.first || carry.second; i++) {
ull A, B;
if(i >= sz(L.cnt)) A = B = 0;
else tie(A, B) = L.cnt[i];
ull C = std(i), D = 0;
if(i < sz(R.cnt)) D = R.cnt[i].first ^ R.cnt[i].second ^ C;
cnt.emplace_back((A ^ carry.first ^ C), (B ^ carry.second ^ D);
carry = pii((A & carry.first) | (C & (A | carry.first)), (B & carry.second) | ((D & (B | carry.second)));
}
txor = L.txor ^ R.txor;
}
};
const int N = (1 << 19) + 5;
template<typename Node>
struct AINT {
int n; // array size
Node t[2 * N];
void init(int n_) {
//int p = 1;
//while(p < n_) p *= 2;
n = n_;
}
void build() { // build the tree
for (int i = n - 1; i > 0; --i) t[i].pull(t[i<<1], t[i<<1|1]);
}
void modify(int p, Node value) { // set value at position p
p--;
for (t[p += n] = value; p > 1; p >>= 1) t[p>>1].pull(t[min(p, p^1)], t[max(p, p^1)]);
}
Node query(int l, int r) { // sum on interval [l, r)
--l;
Node resL(0), resR(0);
for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
if (l&1) resL.pull(resL, t[l++]);
if (r&1) resR.pull(t[--r], resR);
}
resL.pull(resL, resR);
return resL;
}
};
signed main() {
biti[1] = 1;
for(int i = 2; i < nmax; i++) biti[i] = biti[i >> 1] + 1;
cin.tie(0) -> sync_with_stdio(0);
int n, q;
cin >> n >> q;
AINT<Node> aint;
aint.init(n);
vector<ull> v(n + 1), real(n + 1);
for(auto &x : v | views::drop(1)) cin >> x;
real = v;
auto update = [&](int p, ull x) {
v[p] ^= Basis::get_val(x);
real[p] ^= x;
Node kek;
kek.pull(Node(v[p]), Node());
aint.modify(p, kek);
};
auto reformat = [&]() {
if(Basis::upd != -1) {
ull A = Basis::pivot[Basis::upd];
ull msb = A, T = msb;
while(msb > 0) T = msb, msb &= (msb - 1);
msb = T;
for(int i = 1; i <= n; i++) {
if(v[i] & msb)
v[i] ^= A;
}
}
for(int i = 1; i <= n; i++)
aint.t[aint.n + i - 1].pull(Node(v[i]), Node());
aint.build();
return;
};
auto query = [&](int l, int r) -> ull {
ull rez = 0;
Node elem;
elem.pull(Basis::flippers, aint.query(l, r));
//elem.txor = Basis::flippers;
ull p = 1;
for(auto x : elem.cnt) rez += x.second * p, p <<= 1;
return rez;
};
reformat();
for(int i = 0; i < q; i++) {
int T;
cin >> T;
if(T == 1) {
int p;
ull x;
cin >> p >> x;
update(p, x);
}
else if(T == 2) {
ull x;
cin >> x;
if(Basis::add(x)) {
reformat();
}
}
else {
int l, r;
cin >> l >> r;
cout << query(l, r) + Basis::control * (ull)(r - l + 1) << '\n';
}
}
}
/**
Anul asta nu se da centroid
-- Rugaciunile mele
*/