#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
typedef pair<ll, ll> pll;

#define FOR(i, n, m) for(ll (i)=(m);(i)<(n);++(i))
#define REP(i, n) FOR(i,n,0)
#define OF64 std::setprecision(40)

const ll MOD = 1000000007;
const ll INF = (ll) 1e15;

ll A[300005];

template<typename T>
struct SegmentTree {
    using F = function<T(T, T)>;

    SegmentTree(F func, T id)
            : merge(func), identity(id) {}

    void init(ll n) {
        offset = 1;
        while (offset < n)
            offset <<= 1;
        node.assign(offset << 1, identity);
    }

    void build(const vector<T> &v) {
        int n = static_cast<int>(v.size());
        init(n);
        for (int i = 0; i < n; ++i) {
            node[offset + i] = v[i];
        }
        for (int i = offset - 1; i >= 0; --i) {
            node[i] = merge(node[(i << 1) | 0], node[(i << 1) | 1]);
        }
    }

    void set(int index, T value) {
        index += offset;
        node[index] = value;
        while (index >>= 1) {
            node[index] = merge(node[(index << 1) | 0], node[(index << 1) | 1]);
        }
    }

    //! [left, right]
    T get(int left, int right) {
        left += offset;
        right += offset + 1;

        T val = identity;
        while (left < right) {
            if (left & 1)
                val = merge(val, node[left++]);
            if (right & 1)
                val = merge(val, node[--right]);

            left >>= 1;
            right >>= 1;
        }
        return val;
    }

    T identity;
    F merge;
    vector<T> node;
    int offset;
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll N, Q;
    cin >> N >> Q;

    SegmentTree<ll> seg([](ll a, ll b) { return a ^ b; }, 0);
    seg.init(N);
    REP(i, N) {
        ll a;
        cin >> a;
        seg.set(i, a);
    }

    REP(_, Q) {
        ll t, a, b;
        cin >> t >> a >> b;
        a--;
        if (t == 1) {
            ll p = seg.get(a, a);
            seg.set(a, (p ^ b));
        }
        else {
            b--;
            cout << seg.get(a, b) << endl;
        }
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ll  long long
#define endl '\n'
#define FASTINOUT ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
const int N=3e5+9;
ll a[N],tree[4*N];
void build(int node, int start, int end)
{

    if (start == end)
    {
        tree[node] = a[start];
    }
    else
    {
        int mid = (start + end) / 2;

        build(2 * node, start, mid);

        build(2 * node + 1, mid + 1, end);

        tree[node] = (tree[2 * node]^tree[2 * node + 1]);
    }

}
long long query_range(int node, int start, int end, int l, int r)
{

    if (start > r or end < l)
        return 0;
    if (start >= l and end <=r)
        return tree[node];
    int mid = (start + end) / 2;
    long long p1 = query_range(node * 2, start, mid, l, r);
    long long p2 = query_range(node * 2 + 1, mid + 1, end, l, r);
    return (p1^p2);

}

void update(int node, int start, int end, int position, long long val)
{

    if (start > position or end < position)
        return;
    if (start==end)
    {
        a[start]=val^a[start];
        tree[node]=a[start];
        return;
    }
    int mid = (start + end) / 2;
    update(node * 2, start, mid, position, val);
    update(node * 2 + 1, mid + 1, end, position, val);
    tree[node] =  (tree[node * 2] ^ tree[node * 2 + 1]);

}
int main()
{
    FASTINOUT;
    int x,q;
    cin>>x>>q;
    for (int i=1; i<=x; i++)
        cin>>a[i];
    build(1,1,x);
    while (q--)
    {
        ll type,l,r;
        cin>>type>>l>>r;
        if (type==1)
        {
            update(1,1,x,l,r);
        }
        else
        {
            cout<<query_range(1,1,x,l,r)<<endl;
        }
    }
    return 0;
}
