#include <bits/stdc++.h>
const int N = 3e5+5;
int n, q, t[N], a[N];
int ask(int x)
{
    int y = 0;
    for( ; x; x -= x&-x) y ^= t[x];
    return y;
}
void add(int x, int y)
{
    for( ; x <= n; x += x&-x) t[x] ^= y;
}
int main()
{
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; ++i) scanf("%d", a+i), a[i] ^= a[i-1];
    while(q--)
    {
        int op, x, y; scanf("%d%d%d", &op, &x, &y);
        if(op == 1) add(x, y);
        else printf("%d\n", a[y]^a[x-1]^ask(y)^ask(x-1));
    }
    return 0;
}
#include <bits/stdc++.h>
#define ll long long int
#define ld long double
#define f first
#define s second
#define pb push_back
#define eb emplace_back
#define mk make_pair
#define mt make_tuple
#define MOD 1000000007
#define fo(i,a,b) for(i=a;i<b;i++)
#define foe(i,a,b) for(i=a;i<=b;i++)
#define all(x) x.begin(), x.end()
#define vi vector<int>
#define vl vector <long long int>
#define pii pair <int,int>
#define pll pair <long long int, long long int>
#define vpii vector< pair<int,int> >
#define vpll vector < pair <long long int,long long int> >
#define boost ios::sync_with_stdio(false); cin.tie(0)
using namespace std;
const int inf = 1e9 + 5;
const ll inf64 = 1e18 + 5;

template <typename T>
class segtree {
private:
	vector<T> value;
	int size;
	
public:
	const T INITIAL_VALUE = 0;
	const T NEUTRAL = 0;
	
	segtree (int n) {
		size = 1;
		while(size < n) size *= 2;
		value.assign(2 * size, INITIAL_VALUE);
	}
	
	T calc_op(T a, T b) {
		return (a ^ b);
	}
	
	void build(vector<T> &v, int x, int lx, int rx) {
		if(rx - lx == 1) {
			if(lx < (int)v.size()) value[x] = v[lx];
			return;
		}	
		
		int m = (lx + rx) / 2;
		build(v, 2 * x + 1, lx, m);
		build(v, 2 * x + 2, m, rx);
		value[x] = calc_op(value[2 * x + 1], value[2 * x + 2]);
	}
	
	void upd(int i, T v, int x, int lx, int rx) {
		if(rx - lx == 1) {
			value[x] = v;
			return;
		} 
		
		int m = (lx + rx) / 2;
		if(i < m) upd(i, v, 2 * x + 1, lx, m);
		else upd(i, v, 2 * x + 2, m, rx);
		value[x] = calc_op(value[2 * x + 1], value[2 * x + 2]);
	}
	
	T qry(int l, int r, int x, int lx, int rx) {
		if(l >= rx || lx >= r) return NEUTRAL;
		if(l <= lx && rx <= r) return value[x];
		
		int m = (lx + rx) / 2;
		T s1 = qry(l, r, 2 * x + 1, lx, m);
		T s2 = qry(l, r, 2 * x + 2, m, rx);
		return calc_op(s1, s2);
	}

	void build(vector<T> &v) {
		build(v, 0, 0, size);	
	}
	
	void upd(int i, T v) {
		upd(i, v, 0, 0, size);
	}
	
	T qry(int l, int r) {
		return qry(l, r, 0, 0, size);
	}
};

int main()
{
	boost;
	int n, q;
	cin >> n >> q;
	
	vector <int> a(n);
	for(int i = 0; i < n; i++)
	cin >> a[i];
	
	segtree<int> st(n);
	st.build(a);
	
	while(q--) {
		int t;
		cin >> t;
		if(t == 1) {
			int x, y;
			cin >> x >> y; --x;
			st.upd(x, (a[x] ^ y));
			a[x] ^= y;
		}
		else {
			int l, r;
			cin >> l >> r; --l;
			cout << st.qry(l, r) << '\n';
		}
	}
}
