#include <bits/stdc++.h>
inline int read() {
  int x = 0, c = getchar(), f = 1;
  while (c < '0' || c > '9') {
    if (c == '-') f = -f;
    c = getchar();
  }
  while (c >= '0' && c <= '9')
    x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
  return x * f;
}
template <typename T>
void read(T &x) {
  x = read();
}
template <typename T, typename... Argv>
void read(T &x, Argv &...argv) {
  read(x);
  read(argv...);
}
const int N = 1e5 + 5;
int n, m, num, cnt;
int fa[N], s[N], t[N], c[N];
bool vis[N];
std::vector<std::pair<int, int> > v[N];
struct Edge {
  int to;
  Edge *nxt;
  Edge(int to = 0, Edge *nxt = NULL) : to(to), nxt(nxt) {}
} * head[N], pool[N], *tail = pool;
inline void add(int u, int v) { head[u] = new (tail++) Edge(v, head[u]); }
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
void dfs(int x) {
  vis[x] = 1;
  for (Edge *i = head[x]; i; i = i->nxt) dfs(i->to);
  for (int i = 0; i < (int)v[x].size(); i++)
    if (vis[v[x][i].first]) c[v[x][i].second]++;
  vis[x] = 0;
}
int main() {
  n = read();
  m = read();
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1; i <= m; i++) {
    int opt = read(), x = read(), y;
    if (opt != 2) y = read();
    if (opt == 1) {
      add(y, x);
      fa[x] = find(y);
    } else if (opt == 2) {
      num++;
      s[num] = x;
      t[num] = find(x);
    } else {
      cnt++;
      v[x].push_back(std::make_pair(t[y], cnt));
      v[s[y]].push_back(std::make_pair(x, cnt));
    }
  }
  for (int i = 1; i <= n; i++)
    if (i == find(i)) dfs(i);
  for (int i = 1; i <= cnt; i++) puts(c[i] == 2 ? "YES" : "NO");
  return 0;
}
