#include<bits/stdc++.h>
#define rep(i,n) for (int i=0; i<n; i++)
#define REP(i,x,n) for (int i=x; i<n; i++)
using namespace std;
using vi = vector<int>;
using vvi = vector<vi>;
using ll = long long;
using T = tuple<int,int,int>;
using P = pair<int,int>;

const ll SEG_LEN = (1 << 20);

ll seg[SEG_LEN * 2];

void update(ll ind, ll val){
    ind += SEG_LEN;
    bitset<30> VAL(val);
    bitset<30> leaf(seg[ind]);
    auto nleaf = VAL ^ leaf;
    seg[ind] = nleaf.to_ullong();
    while (1){
        //cout << seg[ind] << " ";
        ind /= 2;
        if (ind == 0) break;
        bitset<30> r(seg[ind * 2]);
        bitset<30> l(seg[ind * 2 + 1]);
        auto cur = r ^ l;
        seg[ind] = cur.to_ullong();
    }
    // cout << endl;
}

ll XOR(int ql, int qr, int sl = 0, int sr = 1 << 20, int pos = 1){
    //被らない
    if (qr <= sl || sr <= ql) return 0;
    //完全に包まれる
    if (ql <= sl && sr <= qr) return seg[pos];
    //部分的に被る
    int sm = (sl + sr) / 2;
    ll left = XOR(ql, qr, sl, sm, pos * 2);
    ll right = XOR(ql, qr, sm, sr, pos * 2 + 1);
    bitset<30> L(left);
    bitset<30> R(right);
    auto x = L ^ R;
    return x.to_ullong();
}

int main(){
    int n, q;
    cin >> n >> q;
    rep(i,n) {
        ll ai;
        cin >> ai;
        update(i, ai);
    }

    // for (auto ele : seg){
    //     cout << ele << endl;
    // }

    rep(i,q){
        int ti, xi, yi;
        cin >> ti >> xi >> yi;
        if (ti == 1) update(xi-1, yi);
        if (ti == 2) {
            ll ans = XOR(xi-1, yi);
            cout << ans << endl;
        }
    }

    // for (auto ele : seg){
    //     cout << ele << endl;
    // }
}

#include <bits/stdc++.h>
using namespace std;
int PREP = (cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(12), 0);
//int SEGV = getenv("D") || (exit(system("D= SEGFAULT_SIGNALS=all catchsegv ./prog.exe") >> 8), 0);
using Int = long long;
struct SegTree {
    int N;
    vector<int> A;
    SegTree(int n) {
        N = 1;
        while (N < n) N *= 2;
        A.resize(2 * N);
    }
    void add(int idx, int val) {
        idx += N;
        A[idx] ^= val;
        idx >>= 1;
        while (idx > 0) {
            A[idx] = A[2*idx+0] ^ A[2*idx+1];
            idx >>= 1;
        }
    }
    int get(int L, int R) {
        int ans = 0;
        L += N, R += N;
        while (L < R) {
            if (L & 1) ans ^= A[L++];
            if (R & 1) ans ^= A[--R];
            L >>= 1;
            R >>= 1;
        }
        return ans;
    }
};
int main() {
    int N, Q; cin >> N >> Q;
    vector<int> A(N); for (auto &a : A) cin >> a;
    SegTree st(N);
    for (int i = 0; i < N; i++) {
        st.add(i, A[i]);
    }
    for (int i = 0; i < Q; i++) {
        int T, X, Y; cin >> T >> X >> Y;
        if (T == 1) {
            st.add(X - 1, Y);
        } else {
            cout << st.get(X - 1, Y) << '\n';
        }
    }
    return 0;
}
