#include<iostream>
#include<vector>
using namespace std;
struct node {
int reverse_pos_sum = 0;
int pos_sum = 0;
int ans = 0;
int sz = 1;
void single(int x) {
reverse_pos_sum = x;
pos_sum = x;
ans = x;
sz = 1;
}
};
struct segtree {
int n;
vector<node> arr;
node def = {0,0,0,0};
segtree(int sizex) {
n = 1; while (n < sizex) n<<=1;
arr.resize(2*n);
}
node merge(node a, node b) {
node c;
c.sz = a.sz+b.sz;
c.pos_sum = a.pos_sum ^ b.pos_sum ;
c.reverse_pos_sum = a.reverse_pos_sum ^ b.reverse_pos_sum;
if (a.sz & 1) {
c.pos_sum ^= b.pos_sum;
}
if (b.sz & 1) {
c.reverse_pos_sum ^= a.reverse_pos_sum;
}
c.ans = a.ans ^ b.ans;
if (b.sz & 1) {
c.ans ^= a.pos_sum;
}
if (a.sz & 1) {
c.ans ^= b.reverse_pos_sum;
}
return c;
}
void build(vector<int> &init, int x, int lx, int rx) {
if (rx - lx == 1) {
if (lx < init.size()) arr[x].single(init[lx]);
return;
}
int m = (lx+rx)>>1; build(init,2*x+1,lx,m); build(init,2*x+2,m,rx); arr[x] = merge(arr[2*x+1],arr[2*x+2]);
}
void update(int i, int v, int x, int lx, int rx) {
if (rx - lx == 1) {
arr[x] .single(v);
return;
}
if (lx <= i and i < rx) {
int m = (lx+rx)>>1;
if (i < m) update(i,v,2*x+1,lx,m); else update(i,v,2*x+2,m,rx);
arr[x] = merge(arr[2*x+1],arr[2*x+2]);
}
}
node query(int i, int j, int x, int lx, int rx) {
if (i <= lx and rx <= j) return arr[x];
if (i >= rx or j <= lx) return def;
return merge(query(i,j,2*x+1,lx,(lx+rx)>>1) , query(i,j,2*x+2,(lx+rx)>>1,rx));
}
void update(int i, int v){update(i,v,0,0,n);}
int query(int i, int j){return query(i,j,0,0,n).ans;}
void build(vector<int> &init){build(init,0,0,n);}
void debug() {
cerr<<"( ";
for (auto &x : arr) cerr<<x.ans<<", ";
cerr<<"NULL )"<<endl;
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int n,q; cin>>n>>q;
vector<int> a(n);
for (auto &x : a) cin>>x;
segtree seg(n);
seg.build(a);
while (q--) {
int t; cin>>t;
if (t == 1) {
int i, j; cin>>i>>j; i--; seg.update(i,j);
}
else {
int i,j; cin>>i>>j; i--; j--; cout<<seg.query(i,j+1)<<endl;
}
}
}