#line 1 "test/aoj_DSL_1_A.test.cpp"
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_A"
#include <cstdio>
#line 1 "DataStructure/disjoint_set.cpp"
/**
* @brief 素集合データ構造
* @author えびちゃん
*/
#include <cstddef>
#include <cstdint>
#include <utility>
#include <vector>
class disjoint_set {
public:
using size_type = size_t;
private:
mutable std::vector<intmax_t> M_c;
public:
disjoint_set() = default;
explicit disjoint_set(size_type n): M_c(n, -1) {}
void reset() { M_c.assign(M_c.size(), -1); }
size_type representative(size_type v) const {
if (M_c[v] < 0) return v;
return (M_c[v] = representative(M_c[v]));
}
bool unite(size_type u, size_type v) {
u = representative(u);
v = representative(v);
if (u == v) return false;
if (-M_c[u] > -M_c[v]) std::swap(u, v);
M_c[v] += M_c[u];
M_c[u] = v;
return true;
}
bool equivalent(size_type u, size_type v) const {
return (representative(u) == representative(v));
}
size_type size() const noexcept { return M_c.size(); }
size_type count(size_type v) const {
return -M_c[representative(v)];
}
};
#line 6 "test/aoj_DSL_1_A.test.cpp"
int main() {
size_t n, q;
scanf("%zu %zu", &n, &q);
disjoint_set ds(n);
for (size_t i = 0; i < q; ++i) {
int com;
scanf("%d", &com);
if (com == 0) {
size_t x, y;
scanf("%zu %zu", &x, &y);
ds.unite(x, y);
} else if (com == 1) {
size_t x, y;
scanf("%zu %zu", &x, &y);
printf("%d\n", !!ds.equivalent(x, y));
}
}
}