#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ld=long double;
ll I=1167167167167167167;
ll Q=1e9+7;
#define rep(i,a) for (ll i=0;i<a;i++)
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end());reverse(v.begin(),v.end());}
template<class T> void print(vector<T> v) {rep(i,v.size()) cout<<v[i]<<endl;}

using F=long long;
F e=0;
int MAX_N=131072*4;
std::vector<F> segment(MAX_N*2-1,e);

F segment_function(F a,F b){
    return a^b;
}
void pu_fanction(F &a,F b){
    a^=b;
}

namespace po167{
F get(int k){return segment[k+MAX_N-1];}
F qu_sub(int a,int b,int l,int r,int k){
    if(b<=l||r<=a) return e;
    if(a<=l&&r<=b) return segment[k];
    else{
        F X=qu_sub(a,b,l,(r+l)/2,k*2+1);
        F Y=qu_sub(a,b,(l+r)/2,r,k*2+2);
        return segment_function(X,Y);
    }
}
F qu(int a,int b){return qu_sub(a,b,0,MAX_N,0);}
// get(k)=a
void replace(int k,F a){
    k+=(MAX_N-1);
    segment[k]=a;
    while(k>0){
        k--;
        k/=2;
        segment[k]=segment_function(segment[k*2+1],segment[k*2+2]);
    } 
}
//get(k) ◯ a
void pu(int k,F a){
    k+=(MAX_N-1);
    pu_fanction(segment[k],a);
    while(k>0){
        k--;
        k/=2;
        segment[k]=segment_function(segment[k*2+1],segment[k*2+2]);
    }
}
};
using namespace po167;

//main関数だよーーー
int main(){
    ll N,q;
    cin>>N>>q;
    rep(i,N){
        ll a;
        cin>>a;
        replace(i,a);
    }
    vector<F> ans;
    rep(i,q){
        ll t,x,y;
        cin>>t>>x>>y;
        x--;
        if(t==1) pu(x,y);
        else ans.push_back(qu(x,y));
    }
    print(ans);
}
#include <bits/stdc++.h>

using namespace std;

typedef signed char i8;
typedef signed short i16;
typedef signed int i32;
typedef signed long long i64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef float f32;
typedef double f64;

u32 XOR(u32 a,u32 b) {
    return a ^ b;
}

template <typename T>
struct seg {
    vector<T> tree;
    u64 B;
	T (*fn)(T,T);
    seg(u64 n,T (*func)(T,T)) {
        fn = func;
        B = 1;
        while (B < n)
            B *= 2;
        tree.resize(2 * B, (T)0);
    }

    void add(u64 k, T x) {
        u64 p = B + k;
        tree[p] = fn(tree[p], x);
        while (p > 1) {
            p = p / 2, tree[p] = fn(tree[2 * p], tree[2 * p + 1]);
        }
    }

    T query(u64 l, u64 r) {
        l += B, r += B;
        T res = (T)0;
        while (l <= r) {
            if (l % 2 == 1)
                res = fn(res, tree[l++]);
            if (r % 2 == 0)
                res = fn(res, tree[r--]);
            l /= 2, r /= 2;
        }
        return res;
    }
};

i32 main() {
#ifdef LOCAL
    freopen("output.txt", "w", stdout);
    freopen("input.txt", "r", stdin);
#endif

    ios::sync_with_stdio(false);
    cin.tie(nullptr);

	u32 n, q;
	cin >> n >> q;
    seg<u32> a(n, &XOR);

    for (u32 i = 0; i < n; i++) {
		u32 e;
		cin >> e;
		a.add(i, e);
	}

	for (u32 i = 0; i < q; i++) {
		u32 ty, x, y;
		cin >> ty >> x >> y;

		if(ty == 1) {
			a.add(x -1, y);
		}

		else
			cout << a.query(x - 1, y - 1) << "\n";
	}

	return 0;
}
