// C++(GCC 9.2.1)
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#define repex(i, a, b, c) for(int i = a; i < b; i += c)
#define repx(i, a, b) repex(i, a, b, 1)
#define rep(i, n) repx(i, 0, n)
#define repr(i, a, b) for(int i = a; i >= b; i--)
LL a[303030];

// ※※※ 以下のライブラリを使用(一部改変) ※※※.
// 遅延評価セグメント木をソラで書きたいあなたに.
// http://tsutaj.hatenablog.com/entry/2017/03/30/224339
// http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2236726
struct LazySegmentTree{
private:
    int n;
    vector<LL> node, lazy;
public:
    LazySegmentTree(vector<LL> v){
        int sz = (int)v.size();
        n = 1; while(n < sz) n *= 2;
        node.resize(2 * n - 1);
        lazy.resize(2 * n - 1, 0);
        // 元配列 の 値 を, セグメント木のノード に 保存.
        rep(i, sz) node[i + n - 1] = v[i];
        repr(i, n - 2, 0) node[i] = node[i * 2 + 1] ^ node[i * 2 + 2];
    }
    void eval(int k, int l, int r){
        if(lazy[k] != 0) {
            node[k] ^= lazy[k];
            if(r - l > 1) {
                lazy[2 * k + 1] ^= lazy[k] / 2;
                lazy[2 * k + 2] ^= lazy[k] / 2;
            }
            lazy[k] = 0;
        }
    }
    void update(int a, int b, LL x, int k = 0, int l = 0, int r = -1){
        if(r < 0) r = n;
        eval(k, l, r);
        if(b <= l || r <= a) return;
        if(a <= l && r <= b){
            lazy[k] += (r - l) * x;
            eval(k, l, r);
        }else{
            update(a, b, x, 2 * k + 1,           l, (l + r) / 2);
            update(a, b, x, 2 * k + 2, (l + r) / 2,           r);
            node[k] = node[2 * k + 1] ^ node[2 * k + 2];
        }
    }
    LL query(int a, int b, int k = 0, int l = 0, int r = -1){
        if(r < 0) r = n;
        eval(k, l, r);
        if(b <= l || r <= a) return 0;
        if(a <= l && r <= b) return node[k];
        LL vl = query(a, b, 2 * k + 1,           l, (l + r) / 2);
        LL vr = query(a, b, 2 * k + 2, (l + r) / 2,           r);
        return vl ^ vr;
    }

};

int main(){
    
    // 1. 入力情報.
    int N, Q;
    scanf("%d %d", &N, &Q);
    rep(i, N) scanf("%lld", &a[i]);
    
    // 2. 遅延評価セグメント木.
    LazySegmentTree seg(vector<LL>(N, 0));
    rep(i, N) seg.update(i, i + 1, a[i]);
    
    // 3. クエリ回答.
    rep(i, Q){
        int t;
        scanf("%d", &t);
        
        // t = 1 の 場合.
        if(t == 1){
            int x;
            LL y;
            scanf("%d %lld", &x, &y);
            x--;
            seg.update(x, x + 1, y);
        }
        
        // t = 2 の 場合.
        if(t == 2){
            int x, y;
            scanf("%d %d", &x, &y);
            x--;
            LL ans = seg.query(x, y);
            printf("%lld\n", ans);
        }
    }
    return 0;
    
}
#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
typedef vector<int> vi;
typedef vector<pair<int, int>> vii;
typedef pair<int, int> pi;
#define MOD 1000000007LL

int N, Q; int n2;
int stree[1200000]={};

void add(int v, int i) {
    i += n2;
    for (; i >= 1; i /= 2) stree[i] ^= v;
}

int sum(int a, int b) {
    a += n2; b += n2;
    int s = 0;
    while (a <= b) {
        if (a%2 == 1) s ^= stree[a++];
        if (b%2 == 0) s ^= stree[b--];
        a /= 2; b /= 2;
    }
    return s;
}

int main() {
    //freopen("feast.in", "r", stdin);
    //freopen("feast.out", "w", stdout);
    //ios_base::sync_with_stdio(false);
    //cin.tie(0);
    
    cin >> N >> Q;
    n2 = 1; while (n2 <= N) n2 *= 2;
    for (int i = 1; i <= N; i++) {
        int x; cin >> x; add(x, i);
    }
    while (Q--) {
        int T, X, Y; cin >> T >> X >> Y;
        if (T==1) {
            add(Y, X);
        } else {
            cout << sum(X, Y) << endl;
        }
    }
}