#include <bits/stdc++.h>
#include <math.h>

using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep2(i, s, n) for (int i = (s); i < (int)(n); i++)
typedef long long ll;
using Graph = vector<vector<int>>;
typedef long long ll;
typedef pair<int, int> P;

const int MOD = 1000000007;
const int INF_32 = 1LL << 30;
const int64_t INF_64 = 1LL << 60;

struct UnionFind {
    vector<int> par;
    vector<int> siz;
    vector<map<int, int>> mp;

    UnionFind(int n, vector<int>& C)
        : par(n, -1)
        , siz(n, 1)
    {
        rep(i, n)
        {
            map<int, int> tmp;
            tmp[C[i]] = 1;
            mp.push_back(tmp);
        }
    }

    bool merge(int x, int y)
    {
        int rx = root(x), ry = root(y);
        if (rx == ry)
            return false; //既にmerge済み
        if (siz[rx] < siz[ry])
            swap(rx, ry);

        par[ry] = rx;
        siz[rx] += siz[ry];
        for (auto p : mp[ry]) {
            mp[rx][p.first] += p.second;
        }
        return true;
    }

    int query2(int x, int y)
    {
        int rx = root(x);
        if (mp[rx].count(y))
            return mp[rx][y];
        else
            return 0;
    }

    int size(int x)
    {
        return siz[root(x)];
    }

    int root(int x)
    {
        if (par[x] == -1)
            return x;
        else
            return par[x] = root(par[x]);
    }
};

int main()
{
    int N, Q;
    cin >> N >> Q;
    vector<int> C(N);
    rep(i, N)
    {
        cin >> C[i];
    }
    UnionFind uf(N, C);
    rep(i, Q)
    {
        int type, a, b;
        cin >> type >> a >> b;
        if (type == 1) {
            a--, b--;
            uf.merge(a, b);
        } else {
            a--;
            cout << uf.query2(a, b) << endl;
        }
    }
    return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define mod 1000000007
using namespace std;
int n,q;
int C[200005];
map<int,int> vec[200005];
int fa[200005];
int fnd(int x){
	return fa[x]==x?fa[x]:fa[x]=fnd(fa[x]);
}
void merge(int x,int y){
	x=fnd(x);y=fnd(y);
	if(x==y) return;
	if(vec[x].size()<vec[y].size()) swap(x,y);
	for(map<int,int>::iterator it=vec[y].begin();it!=vec[y].end();it++)
		vec[x][it->fi]+=it->se;
	vec[y].clear();
	fa[y]=x;
}
int main(){
	scanf("%d %d",&n,&q);
	for(int i=1;i<=n;i++) scanf("%d",&C[i]),fa[i]=i,vec[i][C[i]]=1;
	for(int i=1;i<=q;i++){
		int a,b,c;
		scanf("%d %d %d",&a,&b,&c);
		if(a==1){
			merge(b,c);
		}
		else{
			b=fnd(b);
			if(vec[b].find(c)==vec[b].end()) puts("0");
			else printf("%d\n",vec[b][c]);
		}
	}
	return 0;
}
