#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxs = 2e5 + 5;

int PARENT[maxs];
int SIZE[maxs];
vector<int>a;
map<int,int>mp[maxs];
void SET(int V)
{
    SIZE[V] = 1;
    PARENT[V] = V;
}

int FIND_SET(int V)
{
    if(V == PARENT[V])
        return PARENT[V];
    else
        return PARENT[V] = FIND_SET(PARENT[V]);
}

void UNION(int A,int B)
{
    A = FIND_SET(A);
    B = FIND_SET(B);
    
    if(A != B)
    {
        if(SIZE[A] < SIZE[B])
            swap(A,B);
        PARENT[B] = A;
        SIZE[A] += SIZE[B];
        
        for(auto it : mp[B])
            mp[A][it.first] += it.second;
    }
    
    
}



signed main()
{
     int n,q;
     cin >> n >> q;
     a.resize(n + 1);
    
    for(int i = 1;i <= n;++i)
    {
        SET(i);
        cin >> a[i];
        mp[i][a[i]]++;//.push_back(i);
    }
    
    while(q--)
    {
        int type,x,y;
        cin >> type >> x >> y;
        
        if(type & 1)
        {
            UNION(x,y);
        }
        else
        {
            int val = FIND_SET(x);
            
            cout << mp[val][y];
            cout << "\n";
        }
    }
    
   
     
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 

using namespace __gnu_pbds; 
using namespace std;

// #define int           long long
#define S             second
#define F             first
#define pb            push_back
#define all(c)        (c).begin(),(c).end()
#define rall(c)       (c).rbegin(),(c).rend() 
#define lb            lower_bound
#define ub            upper_bound
#define si(c)         (int)((c).size())
#define lcm(a, b)      (a * (b / __gcd(a,b)))  
#define inf           (int)(1e18)
#define endl          '\n'
#define mp            make_pair
#define time(s)       (double(clock()-s)/double(CLOCKS_PER_SEC))
#define debug(args...)    _F(#args, args)
#define vi            std::vector<int>
#define pii           pair<int, int> 
#define vpi           vector<pii>
#define ordered_set   tree<pii, null_type,less<pii>, rb_tree_tag,tree_order_statistics_node_update> 

clock_t start;
mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());

template<typename T> void _F(const char *name, T arg1){ cerr << name << " = " << arg1 << endl;}
template<typename T, typename... Args> void _F(const char *names, T arg1, Args... args)
{ const char *name = strchr(names, ',');cerr.write(names, name-names) << " = " << arg1 << endl;_F(name+2, args...);}

template< typename T1, typename T2 > istream& operator>>(istream& in, pair<T1, T2> &q){ in >> q.F >> q.S; return in;}
template< typename T1, typename T2 > ostream& operator<<(ostream& out, pair<T1, T2> &q){ out << q.F << " " << q.S; return out;}
template< typename T1, typename T2 > pair<T1, T2> operator+(pair<T1, T2> p1, pair<T1, T2> p2){ return {p1.F+p2.F, p1.S+p2.S};}
template< typename T1, typename T2 > pair<T1, T2> operator-(pair<T1, T2> p1, pair<T1, T2> p2){ return {p1.F-p2.F, p1.S-p2.S};}
template< typename T1, typename T2 > bool operator<(pair<T1, T2> p1, pair<T1, T2> p2){ return p1 < p2 ;}

template<typename T> void Unique(vector<T> &v) {
    sort(all(v)), v.resize(distance(v.begin(), unique(all(v))));
}

struct Dsu {
	int n;
	std::vector<int> par, siz;
	std::vector<map<int, int> > un;

	Dsu(int c[], int _n) {
		n = _n;
		par.resize(n+1), un.resize(n+1), siz.resize(n+1);
		for(int i = 1; i <= n; i++)
			par[i] = i, un[i][c[i]]++, siz[i] = 1;;
	}
	int root(int x) {
		return (par[x] == x ? x : par[x] = root(par[x]));
	}
	void merge(int x, int y) {
		x = root(x), y = root(y);
		if(x == y) return;
		if(siz[y] > siz[x]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		for(auto u : un[y])
			un[x][u.F] += u.S;
		un[y].clear();
	}
};

void solve() {
	int n, q;
	cin >> n >> q;
	int c[n+1];
	for(int i = 1; i <= n; i++)
		cin >> c[i];
	Dsu ds(c, n);
	while(q--) {
		int t, x, y; 
		cin >> t >> x >> y;
		if(t == 1) {
			ds.merge(x, y);
		}
		else {
			int r = ds.root(x);
			if(ds.un[r].count(y)) {
				cout << ds.un[r][y] << endl;
			}
			else cout << 0 << endl;
			// cout << ds.un[r].count(y) << endl;
		}
	}
}

signed main() {

    ios_base::sync_with_stdio(0); 
    cin.tie(0); cout.tie(0);   
    start = clock(); 

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin); 
    freopen("output.txt", "w", stdout);
    freopen("error.txt", "w", stderr);
    #endif

    int test = 1;
    // cin >> test;
 
    cout << fixed << setprecision(12);
     
    for(int i = 1; i <= test; ++i){
    	solve();
    }

    cerr << time(start);
    return 0;
}
