#include<cstdio>
#include<algorithm>
const int Q=200005;
typedef long long ll;
#define rg register int
//char buf[1<<21],*p1=buf,*p2=buf;
//#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#define gc() getchar()
inline bool ig(char c){return c>=48&&c<=57;}
inline void read(int &oi){char c;int f=1,res=0;while(c=gc(),(!ig(c))&&c^'-');c^'-'?res=(c^48):f=-1;while(c=gc(),ig(c))res=res*10+(c^48);oi=f*res;}
inline void print(int oi){if(oi<0)putchar('-'),oi=~oi+1;if(oi>9)print(oi/10);putchar(oi%10+48);}
inline void write(int oi,char c){print(oi);putchar(c);}
int n,m,col[Q],prt[Q],rt[Q];
namespace VSgt{
	struct sgt{int ls,rs,sze;}t[Q<<5];int tot;
	inline void update(int x){t[x].sze=t[t[x].ls].sze+t[t[x].rs].sze;}
	inline void modify(int l,int r,int q,int &x){
		if(q>r||l>q)return;if(!x)x=++tot;if(l==r)return void(++t[x].sze);int mid=l+r>>1;
		modify(l,mid,q,t[x].ls);modify(mid+1,r,q,t[x].rs);update(x);
	}
	inline int merge(int x,int y,int l,int r){
		if(!x||!y)return x|y;if(l==r){t[x].sze+=t[y].sze;return x;}
		int mid=l+r>>1;t[x].ls=merge(t[x].ls,t[y].ls,l,mid);
		t[x].rs=merge(t[x].rs,t[y].rs,mid+1,r);update(x);return x;
	}
	inline int query(int l,int r,int q,int x){
		if(q>r||l>q||!x)return 0;if(l==r)return t[x].sze;int mid=l+r>>1;
		return query(l,mid,q,t[x].ls)+query(mid+1,r,q,t[x].rs);
	}
}using namespace VSgt;
inline int gfa(int x){return x^prt[x]?prt[x]=gfa(prt[x]):x;}
inline void merge(int x,int y){
	x=gfa(x);y=gfa(y);if(x==y)return;prt[x]=y;rt[y]=merge(rt[y],rt[x],1,n);
}
inline int query(int x,int y){
	x=gfa(x);return query(1,n,y,rt[x]);
}
int main(){
	read(n);read(m);
	for(rg i=1;i<=n;++i)read(col[i]);
	for(rg i=1;i<=n;++i)prt[i]=i,modify(1,n,col[i],rt[i]);
	for(rg i=1;i<=m;++i){
		int opt,x,y;read(opt);read(x);read(y);
		if(opt==1)merge(x,y);else write(query(x,y),'\n');
	}
	return 0;
}
#line 2 "/home/defineprogram/Desktop/Library/template/template.cpp"
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for(ll i=0;i<n;i++)
#define REP(i,n) for(ll i=1;i<n;i++)
#define rev(i,n) for(ll i=n-1;i>=0;i--)
#define all(v) v.begin(),v.end()
#define P pair<ll,ll>
#define len(s) (ll)s.size()
 
template<class T,class U> inline bool chmin(T &a, U b){
	if(a>b){a=b;return true;}
	return false;
}
template<class T,class U> inline bool chmax(T &a, U b){
	if(a<b){a=b;return true;}
	return false;
}
constexpr ll inf = 3e18;
#line 3 "/home/defineprogram/Desktop/Library/math/modint.cpp"

template<int MOD>
struct mint{
	int32_t n;
	mint():n(0){}
	mint(ll x):n(x>=0?x%MOD:(MOD-(-x)%MOD)%MOD){}

	mint &operator+=(const mint &p){
		if((n+=p.n)>=MOD)n-=MOD;
		return *this;
	}
	mint &operator-=(const mint &p){
		if((n+=MOD-p.n)>=MOD)n-=MOD;
		return *this;
	}
	mint &operator*=(const mint &p){
		n=1ll*n*p.n%MOD;
		return *this;
	}
	mint &operator/=(const mint &p){
		*this*=p.inverse();
		return *this;
	}
	mint operator-()const{return mint(-n);}
	mint operator+(const mint &p)const{return mint(*this)+=p;}
	mint operator-(const mint &p)const{return mint(*this)-=p;}
	mint operator*(const mint &p)const{return mint(*this)*=p;}
	mint operator/(const mint &p)const{return mint(*this)/=p;}
	bool operator==(const mint &p)const{return n==p.n;}
	bool operator!=(const mint &p)const{return n!=p.n;}

	friend ostream &operator<<(ostream &os,const mint &p){
		return os<<p.n;
	}
	friend istream &operator>>(istream &is,mint &p){
		int x;is>>x;
		p=mint(x);
		return is;
	}
	mint pow(int64_t x)const{
		mint res(1),mul(n);
		while(x>0){
			if(x&1)res*=mul;
			mul*=mul;
			x>>=1;
		}
		return res;
	}
	mint inverse()const{
		return pow(MOD-2);
	}
};
/*
@brief mod int
@docs docs/modint.md
*/
#line 3 "main.cpp"

int par[200005],siz[200005];
map<int,int>mp[200005];
int find(int x){
    if(par[x]==x)return x;
    return par[x]=find(par[x]);
}
void merge(int x,int y){
    x=find(x),y=find(y);
    if(x==y)return;
    if(siz[x]<siz[y])swap(x,y);
    for(auto i:mp[y])mp[x][i.first]+=i.second;
    siz[x]+=siz[y];par[y]=x;
}
int N,Q;
int main(){
    cin.tie(0);ios::sync_with_stdio(false);
    cin>>N>>Q;
    rep(i,N){
        int a;cin>>a;mp[i][a]++;par[i]=i;siz[i]=1;
    }
    while(Q--){
        int t;cin>>t;
        if(t==1){
            int a,b;cin>>a>>b;a--;b--;
            merge(a,b);
        }else {
            int a,b;cin>>a>>b;a--;
            cout<<mp[find(a)][b]<<"\n";
        }
    }
}
