#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define MTP make_tuple
typedef long long int ll;
constexpr int kN = int(2E5 + 10);

struct BIT {
	int val[kN];
	BIT () {memset(val, 0, sizeof(val));}
	void add(int pos, int x) {
		while (pos < kN) {
			val[pos] += x;
			pos += pos & -pos;
		}
		return ;
	}
	int ask(int pos) {
		int ans = 0;
		while (pos) {
			ans += val[pos];
			pos ^= pos & -pos;
		}
		return ans;
	}
};

BIT bit;
vector<int> v[kN];
vector<tuple<int, int, int, int>> que[kN];
int p[kN], sz[kN], a[kN], b[kN], c[kN], k[kN], ans[kN], pos[kN];
int Find(int n) {return n == p[n] ? n : p[n] = Find(p[n]);}
void Merge(int l, int r) {
	l = Find(l), r = Find(r);
	if (l != r) {
		if (sz[l] < sz[r]) swap(l, r);
		for (int i : v[r]) v[l].PB(i);
		for (tuple<int, int, int, int> i : que[r]) 
			que[l].PB(MTP(get<0>(i) + sz[l], get<1>(i) + sz[l], get<2>(i), get<3>(i)));
		sz[l] += sz[r];
		p[r] = l;
	}
	return ;
}

int main() {
	int n, q, idx;
	vector<tuple<int, int, int, int>> events;
	scanf("%d%d", &n, &q);
	for (int i = 1; i <= n; i++) scanf("%d", &c[i]);
	for (int i = 1; i <= q; i++) scanf("%d%d%d", &k[i], &a[i], &b[i]);
	for (int i = 1; i <= n; i++) p[i] = i;
	for (int i = 1; i <= n; i++) sz[i] = 1;
	for (int i = 1; i <= n; i++) v[i].PB(i);
	for (int i = 1; i <= q; i++) {
		if (k[i] == 1) Merge(a[i], b[i]);
		else {
			idx = Find(a[i]);
			que[idx].PB(MTP(1, sz[idx], b[i], i));
		}
	}
	for (int i = 1; i <= n; i++) Merge(1, i);
	idx = Find(1);
	//v[idx].push_front(0);
	for (int i = 0; i < n; i++) pos[v[idx][i]] = i + 1;
	for (int i = 1; i <= n; i++) events.PB(MTP(c[i], -1, pos[i], 1));
	for (int i = 1; i <= n; i++) events.PB(MTP(c[i] + 1, -1, pos[i], -1));
	for (tuple<int, int, int, int> i : que[idx]) events.PB(MTP(get<2>(i), get<0>(i), get<1>(i), get<3>(i)));
	sort(events.begin(), events.end());
	for (tuple<int, int, int, int> i : events) {
		//printf("i = (%d, %d, %d, %d)\n", 
		if (get<1>(i) == -1) bit.add(get<2>(i), get<3>(i));
		else ans[get<3>(i)] = bit.ask(get<2>(i)) - bit.ask(get<1>(i) - 1);
	}
	for (int i = 1; i <= q; i++) if (k[i] == 2) printf("%d\n", ans[i]);
}

#include <bits/stdc++.h>

using namespace std;
const int maxn = 2e5 + 5;
int fa[maxn];
unordered_map<int, int> mp[maxn];
int findfa(int x){
    if(fa[x] == x) return x;
    return fa[x] = findfa(fa[x]);
}

void merge(int x, int y){
    int fx = findfa(x), fy = findfa(y);
    if(fx==fy) return;
    if(mp[fx].size() > mp[fy].size()){
        swap(fx, fy);
    }
    for(auto& iter:mp[fx]){
        mp[fy][iter.first] += iter.second;
    }
    fa[fx] = fy;
}
int main() {
    int n, q;
    scanf("%d%d", &n, &q);
    for(int i=1;i<=n;i++){
        int c;
        scanf("%d", &c);
        fa[i] = i;
        mp[i][c] = 1;
    }
    while(q--){
        int op, a, b;
        scanf("%d%d%d", &op, &a, &b);
        if(op==1){
            merge(a, b);
        }
        else if(op==2){
            int fx = findfa(a);
            printf("%d\n", mp[fx].find(b) == mp[fx].end()?0:mp[fx][b]);
        }
    }
    return 0;
}