// abc183_f
#include <bits/stdc++.h>
#ifdef LOCAL
#include "../cxx-prettyprint/prettyprint.hpp"
#endif
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;

#define REP(i, n) for (int (i) = 0 ; (i) < (int)(n) ; ++(i))
#define REPN(i, m, n) for (int (i) = m ; (i) < (int)(n) ; ++(i))
#define REP_REV(i, n) for (int (i) = (int)(n) - 1 ; (i) >= 0 ; --(i))
#define REPN_REV(i, m, n) for (int (i) = (int)(n) - 1 ; (i) >= m ; --(i))
#define ALL(x) x.begin(), x.end()

#define INF (ll)(1e9)
#define MOD (1000000007)

#define print2D(h, w, arr) REP(i, h) { REP(j, w) cout << arr[i][j] << " "; cout << endl; }
#define print_line(vec, n) {for(int idx=0;idx<(n-1);idx++) cout << (vec)[idx] << " "; cout << (vec)[(n)-1] << endl;}
template<class T> void print(const T& x){cout << x << "\n";}
template<class T, class... A> void print(const T& first, const A&... rest) { cout << first << " "; print(rest...); }
struct PreMain {PreMain(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(20);}} premain;

struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
    vector<int> rank;
    vector<int> size; // size[i]: iが親なら連結成分の数

    vector<map<int, int>> info;

    UnionFind(int N, vector<int>& C) : par(N), rank(N), size(N), info(N) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) {
            par[i] = i; rank[i] = 0; size[i] = 1;
            info[i][C[i]]++;
        }

    }

    int find(int x) { // データxが属する木の根を再帰で得る：find(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = find(par[x]);
    }

    void unite(int x, int y) { // xとyの木を併合
        int rx = find(x); //xの根をrx
        int ry = find(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま

        // rank[rx] >= rank[ry] となるように rx と ry を swap
        if(rank[rx] < rank[ry]) swap(rx, ry);

        // 同じ高さだったならばまとめたことによって高さ +1
        if(rank[rx] == rank[ry]) ++rank[rx];

        par[ry] = rx; // root rx に ry の木をつなぐ
        size[rx] += size[ry];
        size[ry] = 0;
        for (auto e: info[ry]){
            info[rx][e.first] += e.second;
        }

    }

    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = find(x);
        int ry = find(y);
        return rx == ry;
    }

    int get_size(int x){
        int rx = find(x);
        return size[rx];
    }
};


int main() {
#ifdef LOCAL
    ifstream in("../arg.txt"); cin.rdbuf(in.rdbuf());
#endif

    int N, Q;
    cin >> N >> Q;

    vector<int> C(N);
    REP(i, N){
        cin >> C[i]; C[i]--;
    }

    UnionFind uf(N, C);

    REP(i, Q){
        int t;
        cin >> t;
        if (t == 1){
            int a, b;
            cin >> a >> b; a--; b--;
            if (not uf.same(a, b)){
                uf.unite(a, b);
            }

        } else {
            int x, y;
            cin >> x >> y; x--; y--;
            int ans = uf.info[uf.find(x)][y];
            print(ans);
        }

    }

    return 0;
}

#define _GLIBCXX_DEBUG
// #include <bits/stdc++.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <unordered_set>
#include <utility>
#include <tuple>
using namespace std;

using ll = int64_t;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)

const ll INF = 1ll << 60; // 十分大きい値とする (ここでは 2^60)
const ll MOD = 1000000009;

template<class T> void chmin(T &a, T b) {
  if (a > b) a = b;
}

template<class T> void chmax(T &a, T b) {
  if (a < b) a = b;
}

int main() {
  ll N;
  cin >> N;

  vector< tuple<ll, ll, ll> > p(N);
  rep(i, N) {
    ll A, B;
    cin >> A >> B;
    p[i] = make_tuple(2*A + B, A, B);
  }

  sort(p.begin(), p.end());
  reverse(p.begin(), p.end());
  /*
  cout << endl;
  rep(i, N) {
    cout << get<1>(p[i]) << " " << get<2>(p[i]) << endl;
  }
  cout << endl;
  */



  ll score_T = 0, score_A = 0;
  rep(i, N) score_A += get<1>(p[i]);

  // cout << score_A << " " << score_T << endl;
  rep(i, N) {
    ll A, B;
    A = get<1>(p[i]);
    B = get<2>(p[i]);
    score_A -= A;
    score_T += A + B;
    // cout << score_A << " " << score_T << endl;
    if (score_T > score_A) {
      cout << i+1 << endl;
      break;
    }
  }
}
