#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, fa[N];
int l[N], r[N], tot;
vector <int> v[N];
int dep[N], up[N][18];
struct Query {
int op, x, y;
} q[N];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void dfs(int x, int p) {
dep[x] = dep[p]+1;
for (int to : v[x]) {
up[to][0] = x;
for (int i = 1; i < 18; i++) {
up[to][i] = up[up[to][i-1]][i-1];
}
dfs(to, x);
}
}
int lca(int a, int b) {
if (dep[a] < dep[b]) swap(a, b);
for (int i = 17; i >= 0; i--) {
if (dep[up[a][i]] >= dep[b]) a = up[a][i];
}
if (a == b) return a;
for (int i = 17; i >= 0; i--) {
if (up[a][i] != up[b][i]) a = up[a][i], b = up[b][i];
}
return up[a][0];
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int op, x, y = 0;
scanf("%d%d", &op, &x);
if (op & 1) scanf("%d", &y);
if (op == 1) v[y].push_back(x);
q[i] = {op, x, y};
}
for (int i = 1; i <= n; i++) {
if (!dep[i]) dfs(i, 0);
fa[i] = i;
}
for (int i = 1; i <= m; i++) {
int op = q[i].op, x = q[i].x, y = q[i].y;
if (op == 1) {
fa[x] = find(y);
} else if (op == 2) {
tot++;
l[tot] = find(x);
r[tot] = x;
} else {
if (find(l[y]) == find(x)) {
if (lca(l[y], x) == l[y] && lca(r[y], x) == x) {
puts("YES");
} else puts("NO");
} else puts("NO");
}
}
return 0;
}