#include<bits/stdc++.h>
typedef long long int ll;
using namespace std;

int n, q;
const int N = 2e5+10;
int p[N], s[N], c[N];
map<int, int>res[N];

int f(int x) {
    return (p[x] == x ? x : p[x] = f(p[x]));
}
void merge(int u, int v) {
    u = f(u), v = f(v);
    if(u == v)
        return;
    if(s[u] < s[v])
        swap(u, v);
    p[v] = u, s[u] += s[v];
    for(auto i:res[v])
        res[u][i.first]+=i.second;
    res[v].clear();
}

void solve(){
    cin >> n >> q;
    for(int i=1;i<=n;++i) {
        cin >> c[i]; p[i] = i, s[i] = 1, res[i][c[i]] = 1;
    }
    while(q--) {
        int t, x, y;
        cin >> t >> x >> y;
        if(t == 1) {
            merge(x, y);
        } else {
            cout << res[f(x)][y] << "\n";
        }
    }
}

int main(){
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int t =1;
    while(t--)
        solve();
    return 0;
}


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

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define range(a) a.begin(), a.end()
#define endl "\n"
#define Yes() cout << "Yes" << endl
#define No() cout << "No" << endl
#define MP make_pair
const unsigned long long mod = 1e9 + 7;
const long long INF = 1LL<<60;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
void chmin(long long &a, long long b) { if (a > b) a = b; }
void chmax(long long &a, long long b) { if (a < b) a = b; }

// UnionFind  ex.)UnionFind uf(N);  という風に定義する
// coding: https://youtu.be/TdR816rqc3s?t=726
// comment: https://youtu.be/TdR816rqc3s?t=6822
struct UnionFind {
  vector<int> d;
  vector<map<int, int>> mp;
  UnionFind(int n = 0) : d(n, -1), mp(n) {} //コンストラクタ(n:頂点数)
  int find(int x) {
    if (d[x] < 0) return x;
    return d[x] = find(d[x]);
  }
  bool unite(int x, int y) {
    x = find(x); y = find(y);
    if (x == y) return false;
    if (d[x] > d[y]) swap(x,y);
    d[x] += d[y];
    d[y] = x;
	for (auto itr = mp[y].begin(); itr != mp[y].end(); ++itr){
		int cnt = itr->second;
		while(cnt--){
			mp[x][itr->first]++;
		}
	}
		return true;
  }
  bool same(int x, int y) { return find(x) == find(y);}
  int size(int x) { return -d[find(x)];}
  void cnt(int x, int y){
	  cout << mp[find(x)][y] << endl;
  }
  void check(int c){
	  cout << c << ":";
	  for (auto itr = mp[c].begin(); itr != mp[c].end(); ++itr){
		  cout << "(" << itr->first << "->" << itr->second << "), ";
	  }
	  cout << endl;
  }
};

int main(void){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int N, Q;
	cin >> N >> Q;
	UnionFind uf(N);
	FOR(i,0,N){
		int c;
		cin >> c;
		--c;
		uf.mp[i][c]++;
	}
	while(Q--){
		int t, a, b;
		cin >> t >> a >> b;
		--a;
		--b;
		if(t==1){
			uf.unite(a, b);
			//uf.check(uf.find(a));
		}else{
			uf.cnt(a, b);
		}
	}

	return 0;
}

