#include<bits/stdc++.h>
using namespace std;

#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 

#define ll long long
#define db double
#define el "\n"
#define ld long double
#define rep(i,n) for(int i=0;i<n;i++)
#define rev(i,n) for(int i=n;i>=0;i--)
#define rep_a(i,a,n) for(int i=a;i<n;i++)
#define all(ds) ds.begin(), ds.end()
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
typedef vector< long long > vi;
typedef pair<long long, long long> ii;
typedef priority_queue <ll> pq;
#define o_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update> 
#define graph vector<vi>

const ll mod = 1000000007;
const ll INF = (ll)1e18;
const ll MAXN = 1000006;

ll po(ll x, ll n ){ 
    ll ans=1;
     while(n>0){
         if(n&1) ans=(ans*x)%mod;
         x=(x*x)%mod;
         n/=2;
     }
     return ans;
}

vi par(200005);
vector<map<ll, ll> > v;

ll getP(ll s){
    if(par[s]==s) return s;
    else return (par[s]=getP(par[s]));
}

void unite(ll x, ll y){
    ll a=getP(x);
    ll b=getP(y);

    if(a==b) return;

    if(v[a].size()<v[b].size()) swap(a,b);
    par[b]=a;

    for(auto h:v[b]){
        if(v[a].find(h.ff)==v[a].end()) v[a].insert(mp(h.ff,0ll));
        v[a][h.ff]+=h.ss;
    }

    v[b].clear();

}


int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
   
    int T=1;
    //cin >> T;
    while(T--){
        ll n,q;
        cin>>n>>q;

        ll c[n+1];
        rep(i,n) cin>>c[i+1];

        rep(i,200005) par[i]=i;
        v.assign(n+1, map<ll,ll>());

        rep_a(i,1,n+1) v[i].insert(mp(c[i],1ll));

        ll t,x,y;

        rep(i,q){
            cin>>t>>x>>y;
            if(t==1) unite(x,y);
            else{
                t = getP(x);
                if(v[t].find(y)==v[t].end()) cout<<0<<el;
                else cout<<v[t][y]<<el;
            }
        }

    
    }
    cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define mp make_pair
#define ll long long
#define pb push_back
#define hell 998244353

void update(vector<int>&bit, int id, int val, int n)
{
    id++;
    while(id<=n)
    {
        bit[id] = bit[id]^val;
        id += id&(-id);
    }
}

int getxor(vector<int>&bit, int id)
{
    id++;
    int ans = 0;
    while(id>0)
    {
        ans = ans^bit[id];
        id -= id&(-id);
    }
    return ans;
}



void solve(int test)
{
   int n,q;
   cin>>n>>q;
   int i,j;
   vector<int>v(n);

   for(i=0;i<n;i++)cin>>v[i];

   vector<int>bit(n+10,0);

   for(i=0;i<n;i++)
   {
       update(bit, i, v[i], n);
   }

   while(q--)
   {
       int t,x,y;
       cin>>t>>x>>y;
       if(t==1)
       {
           x--;
           v[x] = v[x]^y;
           update(bit,x,y, n);
       }
       else
       {
           x--;y--;
           int x1 = getxor(bit,y);
           int x2 = getxor(bit,x-1);
           int ans = x1^x2;
           cout<<ans<<endl;
       }
   }
   return;


}

int main()
{

  int t = 1;
  //cin>>t;

  for(int x = 1;x<=t;x++)
  {
      solve(x);
  }
  return 0;
}
