#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define rrep(i,n) for(int i = 1; i <= (n); ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
#define srep(i,s,t) for (int i = s; i < t; ++i)
#define rng(a) a.begin(),a.end()
#define rrng(a) a.rbegin(),a.rend()
#define isin(x,l,r) ((l) <= (x) && (x) < (r))
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define uni(x) x.erase(unique(rng(x)),x.end())
#define snuke srand((unsigned)clock()+(unsigned)time(NULL));
#define show(x) cerr<<#x<<" = "<<x<<endl;
#define PQ(T) priority_queue<T,v(T),greater<T> >
#define bn(x) ((1<<x)-1)
#define dup(x,y) (((x)+(y)-1)/(y))
#define newline puts("")
using namespace std;
typedef long long int ll;
typedef unsigned uint;
typedef unsigned long long ull;
typedef pair<int,int> P;
typedef tuple<int,int,int> T;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<P> vp;
typedef vector<T> vt;
const double eps = 1e-10;
const ll LINF = 1001002003004005006ll;
const int INF = 1001001001;
#define dame { puts("-1"); return 0;}
#define yn {puts("Yes");}else{puts("No");}
const int MX = 200005;

// Unionfind
struct uf{
  vi d;
  vector<map<int,int> > mp;
  uf() {};
  uf(int mx) : d(mx,-1), mp(mx) {};
  int root(int x){
    if(d[x]<0) return x;
    return d[x] = root(d[x]);
  }
  bool unite(int x, int y){
    x = root(x); y = root(y);
    if(x == y) return false;
    if(d[x] > d[y]) swap(x,y);
    // データ構造をマージする一般的なテク：小さい集団から大きい集団にマージすることを繰り返すことによって、各要素でみたときに高々logn回マージされる（１回のマージで必ず集団の数が２倍以上なるため）
    for(auto p: mp[y]){ // このループの仕方めちゃ便利、連想配列もこのループで回せる
      mp[x][p.first] += p.second; // 連想配列もpair型のようにkey,valueを得ることができる
    }
    mp[y] = map<int,int>(); // 初期化方法
    d[x] += d[y]; d[y] = x;
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y);}
  int size(int x){ return -d[root(x)];}
  int operator[] (int x) {return root(x);}
  int operator() (int x) {return size(x);}
};

int main() {
  int n,q; cin >> n >> q;
  uf dis(n);
  rep(i,n){
    int c; cin >> c;
    dis.mp[i][c] = 1;
  }
  vi ans;
  rep(_,q){
    int type; cin >> type;
    if(type == 1){
      int a,b; cin >> a >> b; --a,--b;
      dis.unite(a,b);
    }else{
      int x,y; cin >> x >> y;
      --x;
      ans.push_back(dis.mp[dis.root(x)][y]);
    }
  }
  for(int res: ans) printf("%d\n", res);
  return 0;
}

#include <bits/stdc++.h>
#define REP(i, nn) for (int i = 0; i < (int)nn; i++)
#define REPS(i, ss, nn) for (int i = ss; i < (int)nn; i++)
#define REV(i, ss, nn) for (int i = ss; i >= nn; i--)
#define deb(x) std::cout << #x << " " << x << endl;
#define debl(x) std::cout << #x << " " << x << " ";
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
namespace std
{
    template <class Fun>
    class y_combinator_result
    {
        Fun fun_;

    public:
        template <class T>
        explicit y_combinator_result(T &&fun) : fun_(std::forward<T>(fun)) {}
        template <class... Args>
        decltype(auto) operator()(Args &&...args)
        {
            return fun_(std::ref(*this), std::forward<Args>(args)...);
        }
    };
    template <class Fun>
    decltype(auto) y_combinator(Fun &&fun)
    {
        return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun));
    }
};
template <typename T>
bool umax(T &a, T b)
{
    bool ret = a < b;
    if (ret)
        a = b;
    return ret;
}
template <typename T>
bool umin(T &a, T b)
{
    bool ret = a > b;
    if (ret)
        a = b;
    return ret;
}
struct edge
{
    int to;
    ll cost;
    int from;
    edge() { edge(0, 0); }
    edge(int to_, ll cost_) : to(to_), cost(cost_) {}
    edge(int to_, int from_, ll cost_) : to(to_), cost(cost_), from(from_) {}
};

template <typename... T>
void read(T &...a)
{
    ((cin >> a), ...);
}

template <typename... T>
void write(T... a)
{
    ((cout << a), ...);
}

template <typename T>
vector<T> read_array(int sz)
{
    vector<T> ret(sz);
    for (auto &x : ret)
        cin >> x;
    return ret;
}

void solve(){
    ll a, b, c, d;
    read(a, b, c, d);
    if(c * d - b <= 0){
        write("-1\n");
        return;
    }
    ll k = a / (c * d - b); 
    if( k * (c * d - b) < a) k++;
    write(k, "\n");
}
int main(){
    //making data IO Fast
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);
    /****************************/
    int T = 1;
    // cin >> T;
    while (T--)
        solve();
    return 0;
}
