#include <bits/stdc++.h>
using namespace std;
const int mod = 1000000007;
const int MAXN = 100010;
int R[MAXN];
int find(int u) { return u == R[u] ? u : R[u] = find(R[u]); }
int n, m, t, p;
int pre[MAXN];
int post[MAXN];
int boss[MAXN];
vector<int> child[MAXN];
int T[MAXN];
int A[MAXN];
int B[MAXN];
vector<pair<long long, long long> > Z[MAXN];
int W[MAXN];
void dfs(int u) {
  pre[u] = ++t;
  for (int v : child[u]) dfs(v);
  post[u] = ++t;
}
bool ancestor(int u, int v) { return pre[u] <= pre[v] && post[v] <= post[u]; }
int main() {
  scanf("%d %d", &n, &m);
  for (int i = (0); i < (m); ++i) {
    int t, a, b;
    scanf("%d", &t);
    if (t == 1) {
      scanf("%d %d", &a, &b);
      child[b].push_back(a);
      boss[a] = b;
    }
    if (t == 2) scanf("%d", &a);
    if (t == 3) {
      scanf("%d %d", &a, &b);
      Z[b].push_back(pair<long long, long long>(a, i));
    }
    T[i] = t;
    A[i] = a;
    B[i] = b;
  }
  for (int i = (1); i < (n + 1); ++i) R[i] = i;
  for (int i = (1); i < (n + 1); ++i)
    if (pre[i] == 0) {
      int b = i;
      while (boss[b]) b = boss[b];
      dfs(b);
    }
  for (int i = (0); i < (m); ++i) {
    if (T[i] == 1) R[find(A[i])] = find(B[i]);
    if (T[i] == 2) {
      ++p;
      for (auto q : Z[p])
        A[q.second] = ancestor(q.first, A[i]) && find(q.first) == find(A[i]);
    }
    if (T[i] == 3) printf(A[i] ? "YES\n" : "NO\n");
  }
  return 0;
}
