#include <bits/stdc++.h> using namespace std; const int MAXN = 1000001; int father[MAXN]; // 每个节点的父节点 int group_size[MAXN]; // 每个集合的大小 int st[MAXN]; // 用于路径压缩的栈 int n; // 节点数量 // 初始化并查集 void build() { for (int i = 0; i <= n; i++) { father[i] = i; // 自己是自己的父节点 group_size[i] = 1; // 初始大小为1 } } // 查找并返回i的根节点,带路径压缩 int find(int i) { // 沿途收集路径上的所有节点 int size = 0; while (i != father[i]) { st[size++] = i; // 将当前节点压入栈 i = father[i]; // 一直往上找 } // 路径压缩,所有节点都直接指向根节点 while (size > 0) { father[st[--size]] = i; } return i; // 返回根节点 } // 判断x和y是否在同一集合中 bool isSameSet(int x, int y) { return find(x) == find(y); // 如果根节点相同,则在同一个集合 } // 合并x和y所在的两个集合 void unionSets(int x, int y) { int fx = find(x); // 找到x的根节点 int fy = find(y); // 找到y的根节点 if (fx != fy) { // 如果x和y不在同一个集合 // fx是集合的代表:拿大小 // fy是集合的代表:拿大小 if (group_size[fx] >= group_size[fy]) { group_size[fx] += group_size[fy]; // 合并两个集合 father[fy] = fx; // 将fy的根节点指向fx } else { group_size[fy] += group_size[fx]; father[fx] = fy; } } } int main() { ios::sync_with_stdio(false); // 提高输入输出效率 cin.tie(nullptr); // 解除cin与cout的绑定 cout.tie(nullptr); // 输入处理 int m; while (cin >> n) { // 读取节点数 build(); // 初始化并查集 cin >> m; // 读取操作次数 for (int i = 0; i < m; i++) { int op, x, y; cin >> op >> x >> y; if (op == 1) { // 查询是否在同一集合 cout << (isSameSet(x, y) ? "Yes" : "No") << endl; } else { // 合并集合 unionSets(x, y); } } } return 0; }