#include "bits/stdc++.h"
#define int long
#define MOD 1000000007
#define PI 3.14159265359
#define fi first
#define se second
#define pb push_back
#define se second
#define vi vector<int>
#define vvi vector<vi>
#define len(x) (int)x.size()
#define pi pair<int,int>
#define vpi vector<pi>
#define maxheap priority_queue<int>
#define minheap priority_queue<int,vi,greater<int>>
#define bits(x) __builtin_popcount(x)
#define fixed(x) cout<<fixed<<setprecision(x);
using namespace std;
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {return os << "(" << P.first << "," << P.second << ")";}
template<class T> ostream& operator<<(ostream &os, vector<T> V) {for(auto v : V) os << v << " ";return os<<"";}
template<class T> ostream& operator<<(ostream &os, set<T> S){os << "{ ";for(auto s:S) os<<s<<" ";return os<<"}";}
template<class T> ostream& operator<<(ostream &os, unordered_set<T> S){os << "{ ";for(auto s:S) os<<s<<" ";return os<<"}";}
template<class T> ostream& operator<<(ostream &os, multiset<T> S){os << "{ ";for(auto s:S) os<<s<<" ";return os<<"}";}
template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) {os << "{ ";for(auto m:M) os<<"("<<m.first<<":"<<m.second<<") ";return os<<"}";}
template<class L, class R> ostream& operator<<(ostream &os, unordered_map<L,R> M) {os << "{ ";for(auto m:M) os<<"("<<m.fi<<":"<<m.se<<") ";return os<<"}";}
template<typename T> istream& operator>>(istream& in,vector<T> &a){for(int i=0;i<len(a);i++)in>>a[i];return in;}
template<typename T1, typename T2> istream& operator>>(istream& in,pair<T1,T2>&p){in>>p.fi>>p.se;return in;}
template<typename T>
void print(T t){cout<<(t);cout<<'\n';}
template<typename T, typename... Args>
void print(T t, Args... args){cout << (t) <<' ';print(args...);}
inline int mul(int a,int b){return (1LL*a*b)%MOD;}
inline void add(int &x,int b){x += b;if(x>=MOD)x-=MOD;}
inline int bpow(int a,int b){int rt=1;while(b>0){if(b&1)rt=mul(rt,a);a=mul(a,a);b>>=1;}return rt;}
int gcd(int a,int b){if(a==0)return b;return gcd(b%a,a);}
const int N = 2e5+1;
int n,q,c[N],tp,a,b,par[N],sz[N];
map<int,map<int,int>>d;
int find(int x){
    if(par[x]==x)return x;
    return find(par[x]);
}
void unite(int x,int y){
    int p1=find(x),p2=find(y);
    if(p1==p2)return;
    if(sz[p1]>sz[p2]){
        sz[p1] += sz[p2];
        par[p2] = p1;
        // d[p1][c[y]]++;
        for(auto p:d[p2]){
            d[p1][p.fi]+=p.se;
        }
    }else{
        sz[p2] += sz[p1];
        par[p1] = p2;
        // d[p2][c[x]]++;
        for(auto p:d[p1]){
            d[p2][p.fi]+=p.se;
        }
    }
}
int32_t main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>q;
    for (int i = 1; i <= n; ++i)
    {
        cin>>c[i];
        par[i] = i,sz[i] = 1;
        d[i][c[i]]++;
    }
    for(int i=0;i<q;i++){
        cin>>tp>>a>>b;
        if(tp==1){
            unite(a,b);
            // print(d);
        }else{
            print(d[find(a)][b]);
        }
    }
    return 0;
}
#include <iostream>
#include <map>
#include <vector>

class disjoint_set {
    std::vector<int> parent;
public:
    std::vector<std::map<int,int>> mp;
    disjoint_set(int n): parent(n,-1), mp(n) {};
    int find(int x) {
        if (parent[x] < 0) return x;
        return parent[x] = find(parent[x]);
    }
    void fusion(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (parent[x] > parent[y]) std::swap(x, y);
        for (auto c: mp[y]) {
            mp[x][c.first] += c.second;
        }
        parent[x] += parent[y];
        parent[y] = x;
    }
};

int main() {
    int n, q;
    std::cin >> n >> q;
    disjoint_set d(n);
    for (int i {0}; i<n; ++i) {
        int c;
        std::cin >> c;
        d.mp[i][c] = 1;
    }
    for (int i {0}; i<q; ++i) {
        int type;
        std::cin >> type;
        if (type == 1) {
            int a, b;
            std::cin >> a >> b;
            --a;
            --b;
            d.fusion(a, b);
        } else {
            int x, y;
            std::cin >> x >> y;
            --x;
            x = d.find(x);
            std::cout << d.mp[x][y] << std::endl;
        }
    }
}
