Write a program which manipulates a disjoint set S = {S1, S2, . . . , Sk}.

First of all, the program should read an integer n, then make a disjoint set where each element consists of 0, 1, ... n−1 respectively.

Next, the program should read an integer q and manipulate the set for q queries. There are two kinds of queries for different operations:

* unite(x, y): unites sets that contain x and y, say Sx and Sy, into a new set.
* same(x, y): determine whether x and y are in the same set.

Constraints

* 1 ≤ n ≤ 10000
* 1 ≤ q ≤ 100000
* x ≠ y

Input


n q
com1 x1 y1
com2 x2 y2
...
comq xq yq


In the first line, n and q are given. Then, q queries are given where com represents the type of queries. '0' denotes unite and '1' denotes same operation.

Output

For each same operation, print 1 if x and y are in the same set, otherwise 0, in a line.

Example

Input

5 12
0 1 4
0 2 3
1 1 2
1 3 4
1 1 4
1 3 2
0 1 3
1 2 4
1 3 0
0 0 4
1 0 2
1 3 0


Output

0
0
1
1
1
0
1
1

Difficulty: UNKNOWN_DIFFICULTY

Solutions:
def root(i):
	if par[i] == i:
		return i
	par[i] = root(par[i])
	return par[i]

def unite(x, y):
	xr = root(x)
	yr = root(y)
	par[yr] = xr

def same(x, y):
	return root(x) == root(y)
(n, q) = map(int, input().split())
par = list(range(n))
for i in range(q):
	commands = list(map(int, input().split()))
	if commands[0] == 0:
		unite(commands[1], commands[2])
	if commands[0] == 1:
		if same(commands[1], commands[2]):
			print(1)
		else:
			print(0)


class UnionFind:

	def __init__(self, n):
		self.parents = list(range(n))

	def find(self, x):
		if self.parents[x] == x:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x != y:
			self.parents[y] = x
import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com:
		print(int(uf.find(x) == uf.find(y)))
	else:
		uf.union(x, y)


class UnionFind:

	def __init__(self, s):
		self.nodes = [-1 for _ in range(s)]

	def find(self, x):
		if self.nodes[x] < 0:
			return x
		else:
			return self.find(self.nodes[x])

	def union(self, x, y):
		s_1 = self.find(x)
		s_2 = self.find(y)
		if s_1 == s_2:
			return False
		if self.nodes[s_1] > self.nodes[s_2]:
			(s_1, s_2) = (s_2, s_1)
		self.nodes[s_1] += self.nodes[s_2]
		self.nodes[s_2] = s_1
		return True

	def is_same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
sets = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		sets.union(x, y)
	else:
		result = sets.is_same(x, y)
		if result is True:
			print('1')
		else:
			print('0')


(n, q) = map(int, input().split())
parents = [i for i in range(n)]

def root(x):
	if parents[x] == x:
		return x
	parents[x] = root(parents[x])
	return parents[x]

def unit(x, y):
	root_x = root(x)
	root_y = root(y)
	if root_x < root_y:
		parents[root_y] = root_x
	else:
		parents[root_x] = root_y

def same(x, y):
	root_x = root(x)
	root_y = root(y)
	return root_x == root_y
for _ in range(q):
	(query, x, y) = map(int, input().split())
	if query == 0:
		unit(x, y)
	elif same(x, y):
		print(1)
	else:
		print(0)


from typing import Union, List
import sys
sys.setrecursionlimit(100000)

def find(x: int, S: List[int]) -> int:
	if S[x] == x:
		return x
	else:
		S[x] = find(S[x], S)
		return S[x]

def same(x: int, y: int, S: List[int]) -> bool:
	return find(x, S) == find(y, S)

def unite(x: int, y: int, S: List[int]) -> None:
	rx = find(x, S)
	ry = find(y, S)
	if rx == ry:
		return None
	else:
		S[rx] = ry
[n, q] = [int(i) for i in input().split()]
S = [i for i in range(n)]
for i in range(q):
	[com, x, y] = [int(i) for i in input().split()]
	if com == 0:
		unite(x, y, S)
	elif com == 1:
		if same(x, y, S):
			print('1')
		else:
			print('0')
	else:
		raise ValueError('value error')


class UnionFind:

	def __init__(self, num):
		self.rank = [0] * num
		self.par = [i for i in range(num)]
		self.n = num

	def find_set(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find_set(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find_set(x)
		y = self.find_set(y)
		if x == y:
			return
		if self.rank[x] > self.rank[y]:
			self.par[y] = x
		else:
			self.par[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def same(self, x, y):
		return self.find_set(x) == self.find_set(y)
(N, Q) = map(int, input().split())
uf = UnionFind(N)
for i in range(Q):
	(C, X, Y) = map(int, input().split())
	if C == 0:
		uf.union(X, Y)
	elif C == 1:
		print(1 if uf.same(X, Y) else 0)
	else:
		print(uf.find_set(X))


class UF:

	def __init__(self, n):
		self.n = n
		self.p = [i for i in range(n)]
		self.r = [1] * n
		self.num = n

	def find(self, x):
		if x == self.p[x]:
			return x
		self.p[x] = UF.find(self, self.p[x])
		return self.p[x]

	def same(self, x, y):
		return UF.find(self, x) == UF.find(self, y)

	def unite(self, x, y):
		x = UF.find(self, x)
		y = UF.find(self, y)
		if x == y:
			return
		if self.r[x] < self.r[y]:
			(x, y) = (y, x)
		self.r[x] += self.r[y]
		self.p[y] = x
		self.num -= 1

	def size(self, x):
		return self.r[x]

	def count(self):
		return self.num
[n, q] = list(map(int, input().split()))
uf = UF(n)
for i in range(q):
	[com, x, y] = list(map(int, input().split()))
	x -= 1
	y -= 1
	if com == 0:
		uf.unite(x, y)
	elif uf.same(x, y):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())
union = [x for x in range(n)]
answer = []

def root(idx):
	if idx == union[idx]:
		return idx
	else:
		union[idx] = root(union[idx])
		return union[idx]
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		min_root = min(root(x), root(y))
		union[root(x)] = union[root(y)] = min_root
	elif root(x) == root(y):
		answer.append('1')
	else:
		answer.append('0')
for i in answer:
	print(i)


from collections import deque

class UnionFind:

	def __init__(self, v):
		self.v = v
		self._tree = list(range(v + 1))

	def _root(self, a):
		queue = deque()
		while self._tree[a] != a:
			queue.append(a)
			a = self._tree[a]
		while queue:
			index = queue.popleft()
			self._tree[index] = a
		return a

	def union(self, a, b):
		root_a = self._root(a)
		root_b = self._root(b)
		self._tree[root_b] = root_a

	def find(self, a, b):
		return self._root(a) == self._root(b)
(N, Q) = map(int, input().split(' '))
queries = [tuple(map(int, input().split(' '))) for _ in range(Q)]
union_find = UnionFind(N - 1)
for (p, a, b) in queries:
	if p == 0:
		union_find.union(a, b)
	elif union_find.find(a, b):
		print(1)
	else:
		print(0)


def find(x):
	if tree[x] < 0:
		return x
	tree[x] = find(tree[x])
	return tree[x]

def unite(x, y):
	x_position = find(x)
	y_position = find(y)
	if x_position == y_position:
		return True
	if y_position < x_position:
		(x_position, y_position) = (y_position, x_position)
	tree[x_position] += tree[y_position]
	tree[y_position] = x_position
	return False

def same(x, y):
	if find(x) == find(y):
		print(1)
	else:
		print(0)
(n, q) = map(int, input().split())
tree = [-1] * n
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	if com == 1:
		same(x, y)


(n, q) = map(int, input().split())
par = [-1] * (n + 1)

def find(x):
	if par[x] < 0:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return False
	else:
		if par[x] > par[y]:
			(x, y) = (y, x)
		par[x] += par[y]
		par[y] = x
		return True

def same(x, y):
	return find(x) == find(y)

def size(x):
	return -par[find(x)]
for _ in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		unite(x, y)
	elif same(x, y):
		print(1)
	else:
		print(0)


class UnionFindTree:

	def __init__(self, n):
		self.a = [i for i in range(n)]
		self.rank = [1 for i in range(n)]

	def root(self, x):
		if self.a[x] != x:
			return self.root(self.a[x])
		return x

	def same(self, x, y):
		if self.root(x) == self.root(y):
			return 1
		else:
			return 0

	def union(self, x, y):
		rx = self.root(x)
		ry = self.root(y)
		if rx != ry:
			if self.rank[rx] < self.rank[ry]:
				self.a[rx] = ry
			else:
				self.a[ry] = rx
				if self.rank[rx] == self.rank[ry]:
					self.rank[rx] += 1
(n, q) = map(int, input().split())
unionFindTree = UnionFindTree(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unionFindTree.union(x, y)
	elif com == 1:
		print(unionFindTree.same(x, y))


(n, q) = map(int, input().split())
(com, x, y) = ([0] * q, [0] * q, [0] * q)
for i in range(q):
	(com[i], x[i], y[i]) = map(int, input().split())
par = [i for i in range(n)]
rank = [0 for _ in range(n)]

def root(x):
	if par[x] == x:
		return x
	else:
		par[x] = root(par[x])
		return par[x]

def same(x, y):
	return root(x) == root(y)

def unite(x, y):
	x = root(x)
	y = root(y)
	if x == y:
		return
	if rank[x] < rank[y]:
		par[x] = y
	else:
		par[y] = x
	if rank[x] == rank[y]:
		rank[x] += 1
for i in range(q):
	if com[i] == 0:
		unite(x[i], y[i])
	elif same(x[i], y[i]):
		print(1)
	else:
		print(0)


class DisjointSet:

	def __init__(self, n):
		self.p = [i for i in range(n)]
		self.rank = [0 for i in range(n)]

	def same(self, x, y):
		return self.findset(x) == self.findset(y)

	def findset(self, x):
		if x != self.p[x]:
			self.p[x] = self.findset(self.p[x])
		return self.p[x]

	def unite(self, x, y):
		self.link(self.findset(x), self.findset(y))

	def link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

def main():
	(n, q) = map(int, input().split(' '))
	ds = DisjointSet(n)
	for _ in range(q):
		(c, a, b) = map(int, input().split(' '))
		if c == 0:
			ds.unite(a, b)
		elif ds.same(a, b):
			print(1)
		else:
			print(0)
main()


class union_find:

	def __init__(self, size):
		self.table = [-1 for _ in range(size)]

	def union(self, x, y):
		(x, y) = (self.find(x), self.find(y))
		if x == y:
			return True
		if self.table[y] < self.table[x]:
			(x, y) = (y, x)
		self.table[x] += self.table[y]
		self.table[y] = x
		return False

	def find(self, x):
		if self.table[x] < 0:
			return x
		self.table[x] = self.find(self.table[x])
		return self.table[x]
import sys
f = sys.stdin
(n, q) = map(int, f.readline().split())
uf = union_find(n)
op = (uf.union, lambda x, y: print(1 if uf.find(x) == uf.find(y) else 0))
for (com, x, y) in (map(int, f.readline().split()) for _ in range(q)):
	op[com](x, y)


class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n)]

	def root(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.root(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		x = self.root(x)
		y = self.root(y)
		self.par[y] = x

	def same(self, x, y):
		return self.root(x) == self.root(y)
(N, Q) = map(int, input().split())
uf = UnionFind(N)
for q in range(Q):
	(c, x, y) = map(int, input().split())
	if c:
		print(int(uf.same(x, y)))
	else:
		uf.unite(x, y)


import sys
sys.setrecursionlimit(10 ** 6)
if sys.platform in ['ios', 'darwin', 'win32']:
	sys.stdin = open('Untitled.txt')
input = sys.stdin.readline

def INT():
	return int(input())

def MAP():
	return [int(s) for s in input().split()]

class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n)]

	def root(self, x):
		if self.par[x] == x:
			return x
		self.par[x] = self.root(self.par[x])
		return self.par[x]

	def same(self, x, y):
		return 1 if self.root(x) == self.root(y) else 0

	def union(self, x, y):
		(x, y) = (self.root(x), self.root(y))
		if x == y:
			return
		self.par[x] = y
(n, q) = MAP()
uf = UnionFind(n)
for _ in range(q):
	(com, x, y) = MAP()
	if com == 0:
		uf.union(x, y)
	if com == 1:
		print(uf.same(x, y))


import sys

def findset(x, element):
	if x != element[x]:
		element[x] = findset(element[x], element)
	return element[x]

def union(x, y, rank, element):
	link(findset(x, element), findset(y, element), rank, element)

def link(x, y, rank, element):
	if rank[x] > rank[y]:
		element[y] = x
	else:
		element[x] = y
		if rank[x] == rank[y]:
			rank[y] += 1
(n, q) = map(int, input().split())
element = [i for i in range(n)]
rank = [0 for i in range(n)]
for i in range(q):
	(query, x, y) = map(int, input().split())
	if query == 0:
		union(x, y, rank, element)
	elif findset(x, element) == findset(y, element):
		print(1)
	else:
		print(0)


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)
		self.rnk = [0] * (n + 1)
		self.Maxroot = -1

	def Find_Root(self, x):
		if self.root[x] < 0:
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			if self.root[x] < self.Maxroot:
				self.Maxroot = self.root[x]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			if self.root[y] < self.Maxroot:
				self.Maxroot = self.root[y]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return self.root[self.Find_Root(x)] * -1
(N, Q) = map(int, input().split())
solve = UnionFind(N)
ans = []
for _ in range(Q):
	(q, x, y) = map(int, input().split())
	if q == 0:
		solve.Unite(x, y)
	else:
		ans.append(solve.isSameGroup(x, y))
for a in ans:
	if a:
		print(1)
	else:
		print(0)


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for _ in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		uf.unite(x, y)
	else:
		print(1 if uf.same(x, y) else 0)


class N:

	def __init__(self, n):
		self.parent = n
		self.rank = 0
		self.n = n

def find(n: int) -> N:
	if data[n].parent == n:
		return data[n]
	else:
		data[n].parent = find(data[n].parent).n
		return data[data[n].parent]

def union(a: int, b: int):
	A = find(a)
	B = find(b)
	if A.rank > B.rank:
		B.parent = A.n
	elif A.rank < B.rank:
		A.parent = B.n
	elif A.n != B.n:
		B.parent = A.n
		A.rank = A.rank + 1
(n, p) = input().split(' ')
data = [N(i) for i in range(int(n))]
for i in range(int(p)):
	(com, x, y) = input().split(' ')
	if com == '0':
		union(int(x), int(y))
	elif find(int(x)).n != find(int(y)).n:
		print(0)
	else:
		print(1)


(N, Q) = map(int, input().split())
union = [x for x in range(N)]
answer_list = []

def fetch_root(idx):
	if idx == union[idx]:
		return idx
	else:
		union[idx] = fetch_root(union[union[idx]])
		return union[idx]
for i in range(Q):
	(q, a, b) = map(int, input().split())
	if q == 0:
		min_root_idx = max(fetch_root(a), fetch_root(b))
		union[min_root_idx] = min(fetch_root(a), fetch_root(b))
	elif fetch_root(union[a]) == fetch_root(union[b]):
		answer_list.append(1)
	else:
		answer_list.append(0)
for i in answer_list:
	print(i)


(n, q) = map(int, input().split())
(*parent,) = range(n)

def root(x):
	if x != parent[x]:
		x = parent[x] = root(parent[x])
	return x

def unite(x, y):
	px = root(x)
	py = root(y)
	if px < py:
		parent[py] = px
	else:
		parent[px] = py

def same(x, y):
	return root(x) == root(y)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	else:
		print(int(same(x, y)))


class UnionFind:

	def __init__(self, N):
		self.parent = [-1] * N

	def findset(self, A):
		if self.parent[A] < 0:
			return A
		self.parent[A] = self.findset(self.parent[A])
		return self.parent[A]

	def size(self, A):
		return -self.parent[self.findset(A)]

	def unite(self, A, B):
		A = self.findset(A)
		B = self.findset(B)
		if A == B:
			return False
		if self.size(A) < self.size(B):
			(A, B) = (B, A)
		self.parent[A] += self.parent[B]
		self.parent[B] = A
		return True

	def is_in_same(self, A, B):
		return self.findset(A) == self.findset(B)
(N, Q) = map(int, input().split())
ds = UnionFind(N)
for q in range(Q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		ds.unite(x, y)
	elif com == 1:
		print(1 if ds.is_in_same(x, y) else 0)


from sys import stdin
input = stdin.readline
from collections import defaultdict
(n, q) = map(int, input().split())
dic = defaultdict()

def getRoot(x):
	global n
	for _ in range(n + 1):
		if dic[x]['parent'] == x:
			return x
		x = dic[x]['parent']

def makeSet(x):
	return

def unite(x, y):
	r = getRoot(x)
	l = getRoot(y)
	a = dic[r]['rank']
	b = dic[l]['rank']
	if a == b:
		dic[r]['rank'] += 1
		dic[l]['parent'] = r
	elif a > b:
		dic[l]['rank'] = 0
		dic[l]['parent'] = r
	elif a < b:
		dic[r]['rank'] = 0
		dic[r]['parent'] = l
for _ in range(n):
	dic[_] = {'rank': 0, 'parent': _}
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	else:
		s = getRoot(x)
		t = getRoot(y)
		if s == t:
			print('1')
		else:
			print('0')


class DisjointSet:

	def __init__(self, size):
		self.rank = [0] * size
		self.p = list(range(size))

	def findSet(self, x):
		if x != self.p[x]:
			self.p[x] = self.findSet(self.p[x])
		return self.p[x]

	def same(self, x, y):
		return self.findSet(x) == self.findSet(y)

	def link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def unite(self, x, y):
		self.link(self.findSet(x), self.findSet(y))
(n, q) = [int(v) for v in input().split()]
ds = DisjointSet(n)
for i in range(q):
	(com, x, y) = [int(v) for v in input().split()]
	if com == 0:
		ds.unite(x, y)
	elif com == 1:
		if ds.same(x, y):
			print(1)
		else:
			print(0)


class UnionFindTree:

	def __init__(self, n):
		self.par = list(range(n))
		self.rank = [0] * n

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		(x, y) = (self.find(x), self.find(y))
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)
(N, Q) = map(int, input().split())
DisjointSet = UnionFindTree(N)
for _ in range(Q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		DisjointSet.unite(x, y)
	elif com == 1:
		print(int(DisjointSet.same(x, y)))


(n, q) = map(int, input().split())
buf = [i for i in range(n)]
height = [1] * n

def find(i):
	while i != buf[i]:
		i = buf[i]
	return i

def union(i, j):
	i = find(i)
	j = find(j)
	if height[i] >= height[j]:
		buf[j] = i
		height[i] = max(height[i], height[j] + 1)
	else:
		buf[i] = j
		height[j] = max(height[j], height[i] + 1)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		union(x, y)
	elif find(x) == find(y):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())
parents = [i for i in range(n)]
deepth = [0 for _ in range(n)]

def find(x):
	if parents[x] == x:
		return x
	return find(parents[x])

def unite(x, y):
	px = find(x)
	py = find(y)
	if deepth[px] > deepth[py]:
		parents[py] = px
		deepth[px] = max(deepth[px], deepth[py] + 1)
	else:
		parents[px] = py
		deepth[py] = max(deepth[py], deepth[px] + 1)

def same(x, y):
	if find(x) == find(y):
		return True
	else:
		return False
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	if com == 1:
		if same(x, y):
			print(1)
		else:
			print(0)


maxn = 100000
(n, q) = map(int, input().split())
par = [0] * n
rank = [0] * n
for i in range(n):
	par[i] = i
	rank[i] = 0

def find(x):
	if par[x] == x:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	rx = find(x)
	ry = find(y)
	if rx == ry:
		return
	if rank[rx] < rank[ry]:
		par[rx] = ry
	elif rank[rx] > rank[ry]:
		par[ry] = rx
	else:
		par[ry] = x
		rank[rx] += 1

def same(x, y):
	return find(x) == find(y)
for i in range(q):
	(p, a, b) = map(int, input().split())
	if p == 0:
		unite(a, b)
	if p == 1:
		print(1 if same(a, b) else 0)


(n, q) = map(int, input().split())
L = []
for i in range(q):
	L.append(list(map(int, input().split())))
par = []
for i in range(n):
	par.append(i)
rank = [0] * n

def find(x, par):
	if x == par[x]:
		return x
	else:
		return find(par[x], par)

def unite(x, y, par, rank):
	x = find(x, par)
	y = find(y, par)
	if x != y:
		if rank[x] < rank[y]:
			par[x] = y
		else:
			par[y] = x
	else:
		par[y] = x
		if rank[x] == rank[y]:
			rank[x] += 1
for i in range(q):
	if L[i][0] == 0:
		unite(L[i][1], L[i][2], par, rank)
	elif find(L[i][1], par) == find(L[i][2], par):
		print(1)
	else:
		print(0)


(n, q) = [int(x) for x in input().split(' ')]
sets = [set([i]) for i in range(n)]

def unite(Sx, Sy):
	return Sx | Sy

def search(x):
	global sets
	flag = False
	for i in range(len(sets)):
		if x in sets[i]:
			flag = True
			break
	if flag:
		return i
	else:
		return None

def same(x, y):
	global sets
	flag = 0
	for set in sets:
		if x in set:
			if y in set:
				flag = 1
			break
	return flag
for i in range(q):
	(query, x, y) = input().split(' ')
	(x, y) = (int(x), int(y))
	if query == '0':
		i_x = search(x)
		i_y = search(y)
		if i_x != None and i_y != None and (i_x != i_y):
			sets[i_x] = unite(sets[i_x], sets[i_y])
			del sets[i_y]
	elif query == '1':
		print(same(x, y))


import sys
sys.setrecursionlimit(10 ** 7)
(n, q) = [int(s) for s in input().split()]
par = []
for i in range(n):
	par.append(i)

def find(x):
	if par[x] == x:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def same(x, y):
	return find(x) == find(y)

def union(x, y):
	x = find(x)
	y = find(y)
	if x != y:
		par[x] = y
for i in range(q):
	(q_type, x, y) = [int(s) for s in input().split()]
	if q_type == 1:
		if same(x, y):
			print(1)
		else:
			print(0)
	else:
		union(x, y)


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x != y:
			if self.parents[x] > self.parents[y]:
				(x, y) = (y, x)
			self.parents[x] += self.parents[y]
			self.parents[y] = x

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
UF = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		UF.unite(x, y)
	elif com == 1:
		if UF.same(x, y):
			print(1)
		else:
			print(0)


import sys
(N, Q) = map(int, input().split())
par = list(range(N))

def find(x):
	if x == par[x]:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def union(x, y):
	(rx, ry) = (find(x), find(y))
	par[ry] = rx
for _ in range(Q):
	(p, a, b) = map(int, sys.stdin.readline().split())
	if p == 0:
		union(a, b)
	if p == 1:
		if find(a) != find(b):
			print(0)
		else:
			print(1)


def main():

	def root(x):
		path = []
		while x != P[x]:
			path.append(x)
			x = P[x]
		for i in path:
			P[i] = x
		return x

	def is_same_set(x, y):
		return root(x) == root(y)

	def unite(x, y):
		P[root(x)] = root(y)
	(n, q) = map(int, input().split())
	P = [i for i in range(n)]
	for i in range(q):
		(q, a, b) = map(int, input().split())
		if q == 0:
			unite(a, b)
		elif is_same_set(a, b):
			print(1)
		else:
			print(0)
main()


(n, q) = map(int, input().split())

def find(x):
	if par[x] < 0:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return False
	else:
		if par[x] > par[y]:
			(x, y) = (y, x)
		par[x] += par[y]
		par[y] = x
		return True

def same(x, y):
	return find(x) == find(y)

def size(x):
	return -par[find(x)]
par = [-1] * n
for _ in range(q):
	(com, ai, bi) = map(int, input().split())
	if com == 0:
		unite(ai, bi)
	else:
		print(1 if same(ai, bi) else 0)


class UnionFind:

	def __init__(self, n):
		self.parent = [-1] * n

	def root(self, a):
		if self.parent[a] < 0:
			return a
		else:
			self.parent[a] = self.root(self.parent[a])
			return self.parent[a]

	def size(self, a):
		return -self.parent[self.root(a)]

	def connect(self, a, b) -> bool:
		a = self.root(a)
		b = self.root(b)
		if a == b:
			return False
		if self.size(a) < self.size(b):
			(a, b) = (b, a)
		self.parent[a] += self.parent[b]
		self.parent[b] = a
		return True
(n, q) = map(int, input().split())
unif = UnionFind(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unif.connect(x, y)
	else:
		print(1 if unif.root(x) == unif.root(y) else 0)


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)
		self.rnk = [0] * (n + 1)

	def Find_Root(self, x):
		if self.root[x] < 0:
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return -self.root[self.Find_Root(x)]
(n, q) = map(int, input().split())
uf = UnionFind(n)
for _ in range(q):
	(a, b, c) = map(int, input().split())
	if a:
		print(int(uf.isSameGroup(b, c)))
	else:
		uf.Unite(b, c)


class UnionFind:

	def __init__(self, n):
		self.p = [i for i in range(n)]
		self.r = [0 for i in range(n)]

	def root(self, x):
		if self.p[x] == x:
			return x
		else:
			self.p[x] = self.root(self.p[x])
			return self.p[x]

	def uni(self, x, y):
		x = self.root(x)
		y = self.root(y)
		if x == y:
			return
		if self.r[x] < self.r[y]:
			self.p[x] = y
		else:
			self.p[y] = x
			if self.r[x] == self.r[y]:
				self.r[x] += 1

	def same(self, x, y):
		return self.root(x) == self.root(y)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		uf.uni(x, y)
	else:
		print(uf.same(x, y) + 0)


def make_set(x, disjoint):
	disjoint[x] = x

def find_set(x, disjoint):
	if x not in disjoint.keys():
		make_set(x, disjoint)
	if x != disjoint[x]:
		disjoint[x] = find_set(disjoint[x], disjoint)
	return disjoint[x]

def link(x, y, disjoint):
	disjoint[y] = x

def unite(x, y, disjoint):
	link(find_set(x, disjoint), find_set(y, disjoint), disjoint)

def same(x, y, disjoint):
	if find_set(x, disjoint) == find_set(y, disjoint):
		return 1
	return 0
(n, q) = list(map(int, input().split()))
com_list = list()
x_list = list()
y_list = list()
for _ in range(q):
	(com, x, y) = list(map(int, input().split()))
	com_list.append(com)
	x_list.append(x)
	y_list.append(y)
disjoint = dict()
for i in range(q):
	com = com_list[i]
	x = x_list[i]
	y = y_list[i]
	if com == 0:
		unite(x, y, disjoint)
	else:
		print(same(x, y, disjoint))


import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
parent = list(range(n))
rank = [0] * n

def root(x):
	if x != parent[x]:
		x = root(parent[x])
	return x

def same(x, y):
	return root(x) == root(y)

def unite(x, y):
	rx = root(x)
	ry = root(y)
	if rank[rx] < rank[ry]:
		parent[rx] = ry
	else:
		parent[ry] = rx
		if rank[rx] == rank[ry]:
			rank[rx] += 1
for i in range(q):
	(c, a, b) = map(int, input().split())
	if c == 0:
		unite(a, b)
	elif same(a, b):
		print(1)
	else:
		print(0)


p = []
rank = []

def makeSet(x):
	global p, rank
	p.append(x)
	rank.append(0)

def findSet(x):
	global p
	if x != p[x]:
		p[x] = findSet(p[x])
	return p[x]

def link(x, y):
	global p, rank
	if rank[x] > rank[y]:
		p[y] = x
	else:
		p[x] = y
		if rank[x] == rank[y]:
			rank[y] += 1

def union(x, y):
	link(findSet(x), findSet(y))

def same(x, y):
	if findSet(x) == findSet(y):
		return 1
	else:
		return 0
[n, q] = list(map(int, input().split()))
for i in range(n):
	makeSet(i)
for i in range(q):
	[com, x, y] = list(map(int, input().split()))
	if com == 0:
		union(x, y)
	else:
		print(same(x, y))


COM_UNITE = 0
COM_SAME = 1

class UnionFindTree:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.rank = [0] * n

	def find(self, x):
		if self.parent[x] == x:
			return x
		else:
			self.parent[x] = self.find(self.parent[x])
			return self.parent[x]

	def unite(self, x, y):
		(x, y) = (self.find(x), self.find(y))
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.parent[x] = y
		else:
			self.parent[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = (int(s) for s in input().split())
tree = UnionFindTree(n)
for i in range(q):
	(com, x, y) = (int(s) for s in input().split())
	if com == COM_UNITE:
		tree.unite(x, y)
	elif com == COM_SAME:
		print(int(tree.same(x, y)))


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def size(self, x):
		return -self.parents[self.find(x)]

	def same(self, x, y):
		x = self.find(x)
		y = self.find(y)
		print(1 if x == y else 0)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.union(x, y)
	else:
		uf.same(x, y)


class UnionFindTree:

	def __init__(self, x):
		self.parent = self
		self.id = x
		self.rank = 0

	def find(self):
		if self.id == self.parent.id:
			return self
		else:
			return self.parent.find()
(n, q) = map(int, input().split())
nodes = [UnionFindTree(i) for i in range(n)]
for i in range(q):
	(com, x, y) = map(int, input().split())
	x_root = nodes[x].find()
	y_root = nodes[y].find()
	if com == 0:
		if x_root.rank > y_root.rank:
			y_root.parent = x_root
		elif y_root.rank > x_root.rank:
			x_root.parent = y_root
		elif x_root.id != y_root.id:
			y_root.parent = x_root
			x_root.rank += 1
	else:
		same = 1 if x_root.id == y_root.id else 0
		print(same)


import sys
sys.setrecursionlimit(2 * 10 ** 6)

class UF:

	def __init__(self, num):
		self.par = [-1] * num
		self.size = [1] * num

	def find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		(rx, ry) = (self.find(x), self.find(y))
		if rx == ry:
			return 0
		if rx < ry:
			(rx, ry) = (ry, rx)
		self.par[rx] += self.par[ry]
		self.par[rx] = ry
		self.size[rx] += self.size[ry]
		return 1

	def check(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
T = UF(n)
for _ in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		T.union(x, y)
	else:
		print(int(T.check(x, y)))


(n, q) = map(int, input().split(' '))
parent = [i for i in range(n)]
rank = [0] * len(parent)

def root(s):
	if parent[s] == s:
		return s
	else:
		parent[s] = root(parent[s])
		return parent[s]

def same(s1, s2):
	if root(s1) == root(s2):
		print('1')
	else:
		print('0')

def unite(s1, s2):
	s1 = root(s1)
	s2 = root(s2)
	if s1 == s2:
		return
	if rank[s1] < rank[s2]:
		parent[s1] = s2
	else:
		parent[s2] = s1
		if rank[s1] == rank[s2]:
			rank[s1] += 1
for i in range(q):
	(query, item1, item2) = input().split(' ')
	(item1, item2) = (int(item1), int(item2))
	if query == '0':
		unite(item1, item2)
	else:
		same(item1, item2)


def root(x):
	if parent[x] == x:
		return x
	else:
		parent[x] = root(parent[x])
		return parent[x]

def same(x, y):
	return root(x) == root(y)

def union(x, y):
	x = root(x)
	y = root(y)
	if x == y:
		return
	parent[x] = min(x, y)
	parent[y] = min(x, y)
	return
(n, q) = map(int, input().split())
parent = {i: i for i in range(n)}
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 1:
		print(int(same(x, y)))
	else:
		union(x, y)


class UnionFind:

	def __init__(self, N):
		self.par = [i for i in range(N)]
		self.siz = [1 for _ in range(N)]
		self.rank = [0 for _ in range(N)]

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, a, b):
		a = self.find(a)
		b = self.find(b)
		if a == b:
			return 0
		elif self.rank[a] > self.rank[b]:
			self.par[b] = a
			self.siz[a] += self.siz[b]
		else:
			self.par[a] = b
			self.siz[b] += self.siz[a]
			if self.rank[a] == self.rank[b]:
				self.rank[b] += 1

	def size(self, a):
		return self.siz[self.find(a)]

	def same(self, a, b):
		return self.find(a) == self.find(b)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	(x, y) = (x - 1, y - 1)
	if com:
		print(1 if uf.same(x, y) else 0)
	else:
		uf.union(x, y)


def findSet(x):
	if x == parent[x]:
		return x
	else:
		return findSet(parent[x])

def link(x, y):
	if rank[x] < rank[y]:
		parent[x] = y
	else:
		parent[y] = x
		if rank[x] == rank[y]:
			rank[y] += 1

def union(x, y):
	link(findSet(x), findSet(y))
(n, q) = list(map(int, input().split()))
data = (i for i in range(n))
rank = [0 for i in range(n)]
parent = [i for i in range(n)]
for i in range(q):
	(f, x, y) = list(map(int, input().split()))
	if f == 0:
		union(x, y)
	elif findSet(x) == findSet(y):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())
p = [i for i in range(n)]
rank = [0 for i in range(n)]

def makeSet(x):
	p[x] = x
	rank[x] = 0

def union(x, y):
	link(findSet(x), findSet(y))

def link(x, y):
	if rank[x] > rank[y]:
		p[y] = x
	else:
		p[x] = y
		if rank[x] == rank[y]:
			rank[y] = rank[y] + 1

def findSet(x):
	if x != p[x]:
		p[x] = findSet(p[x])
	return p[x]

def unite(x, y):
	union(x, y)

def same(x, y):
	x = findSet(x)
	y = findSet(y)
	if x == y:
		return 1
	else:
		return 0
output = []
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	else:
		output.append(same(x, y))
for ans in output:
	print(ans)


class UnionFindTree:

	def __init__(self, n: int):
		self.__parent = [i for i in range(n)]
		self.__rank = [0 for i in range(n)]

	def unite(self, x, y):
		self.__link(self.__find_set(x), self.__find_set(y))

	def same(self, x, y):
		return self.__find_set(x) == self.__find_set(y)

	def __find_set(self, x):
		if x != self.__parent[x]:
			self.__parent[x] = self.__find_set(self.__parent[x])
		return self.__parent[x]

	def __link(self, x, y):
		if self.__rank[x] < self.__rank[y]:
			self.__parent[x] = y
		else:
			if self.__rank[x] == self.__rank[y]:
				self.__rank[x] += 1
			self.__parent[y] = x
(N, Q) = map(int, input().split())
t = UnionFindTree(N)
for i in range(Q):
	(command, x, y) = map(int, input().split())
	if command == 0:
		t.unite(x, y)
	if command == 1:
		if t.same(x, y):
			print(1)
		else:
			print(0)


from sys import stdin

class DisjointSet:

	def __init__(self):
		self.parent = None
		self.ancestor = self

def ancestor(elems, x):
	s = elems[x].ancestor
	while s.parent is not None:
		s = s.parent
	elems[x].ancestor = s
	return s

def unite(elems, x, y):
	ax = ancestor(elems, x)
	ay = ancestor(elems, y)
	if ax is not ay:
		ax.parent = ay
		ax.ancestor = ay.ancestor

def same(elems, x, y):
	return ancestor(elems, x) is ancestor(elems, y)

def main():
	(n, q) = [int(x) for x in input().split()]
	elems = [DisjointSet() for _ in range(n)]
	for _ in range(q):
		(com, x, y) = [int(x) for x in input().split()]
		if com == 0:
			unite(elems, x, y)
		else:
			print(1 if same(elems, x, y) else 0)
main()


def makeSet(x):
	global p, rank
	p[x] = x
	rank[x] = 0

def union(x, y):
	link(findSet(x), findSet(y))

def link(x, y):
	global p, rank
	if rank[x] > rank[y]:
		p[y] = x
	else:
		p[x] = y
		if rank[x] == rank[y]:
			rank[y] = rank[y] + 1

def findSet(x):
	global p
	if x != p[x]:
		p[x] = findSet(p[x])
	return p[x]

def isSame(x, y):
	global p
	if findSet(x) == findSet(y):
		return True
	else:
		return False
(N, Q) = (int(z) for z in input().split())
p = [None] * N
rank = [None] * N
for i in range(N):
	makeSet(i)
for i in range(Q):
	(com_i, x, y) = (int(z) for z in input().split())
	if com_i == 0:
		union(x, y)
	if com_i == 1:
		if isSame(x, y) == False:
			print('0')
		else:
			print('1')


def find(x):
	global set_list
	if set_list[x] == x:
		return x
	result = set_list[x] = find(set_list[x])
	return result
(n, q) = map(int, input().split())
set_list = list(range(n))
while q:
	(op, x, y) = map(int, input().split())
	if op:
		print(1 if find(x) == find(y) else 0)
	else:
		set_list[find(y)] = find(x)
	q -= 1


import sys
line = input()
(n, q) = list(map(int, line.split()))
rel = {}
for i in range(0, n):
	rel[i] = []
parent = [i for i in range(0, n)]

def find(x):
	if parent[x] == x:
		return x
	else:
		y = find(parent[x])
		parent[x] = y
		return y

def unite(x, y):
	rx = find(x)
	ry = find(y)
	if rx < ry:
		parent[ry] = rx
	else:
		parent[rx] = ry

def same(x, y):
	return find(x) == find(y)
for _ in range(0, q):
	line = input()
	(query, x, y) = list(map(int, line.split()))
	if query == 0:
		unite(x, y)
	elif query == 1:
		print(1 if same(x, y) else 0)


import sys
sys.setrecursionlimit(10000)
(N, Q) = tuple(map(int, input().split()))
tree = [[-1, 1] for _ in range(N)]

def find(i):
	if tree[i][0] == -1:
		group = i
	else:
		group = find(tree[i][0])
	return group

def unite(x, y):
	px = find(x)
	py = find(y)
	if tree[px][1] == tree[py][1]:
		tree[py][0] = px
		tree[px][1] += 1
	else:
		if tree[px][1] < tree[py][1]:
			(px, py) = (py, px)
		tree[py][0] = px
for _ in range(Q):
	(com, x, y) = tuple(map(int, input().split()))
	if com:
		print(int(find(x) == find(y)))
	elif not int(find(x) == find(y)):
		unite(x, y)


class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n)]
		self.rank = [0] * n
		self.size = [1] * n

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
			self.size[y] += self.size[x]
		else:
			self.par[y] = x
			self.size[x] += self.size[y]
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same(self, x, y):
		if self.find(x) == self.find(y):
			return True
		else:
			return False
(N, Q) = map(int, input().split())
UF = UnionFind(N)
for i in range(Q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		UF.unite(x, y)
	if com == 1:
		print(int(UF.same(x, y)))


import queue

class UnionFind:

	def __init__(self, N):
		self.sizes = [1 for _ in range(N)]
		self.par = [i for i in range(N)]

	def find(self, x):
		if x == self.par[x]:
			return x
		self.par[x] = self.find(self.par[x])
		return self.par[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.sizes[x] < self.sizes[y]:
			(x, y) = (y, x)
		self.par[y] = x
		self.sizes[x] += self.sizes[y]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def size(self, x):
		return self.sizes[self.find(x)]

def main():
	(N, Q) = map(int, input().split())
	uf = UnionFind(N)
	for _ in range(Q):
		(com, x, y) = map(int, input().split())
		if com == 0:
			uf.unite(x, y)
		else:
			print(int(uf.same(x, y)))
	return
main()


from sys import stdin
input = stdin.readline

class DisjointSet(object):

	def __init__(self, n):
		self.p = list(range(n))
		self.rank = [0] * n

	def same(self, x, y):
		return self.find_set(x) == self.find_set(y)

	def unite(self, x, y):
		self.link(self.find_set(x), self.find_set(y))

	def link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def find_set(self, x):
		if x != self.p[x]:
			self.p[x] = self.find_set(self.p[x])
		return self.p[x]
(n, q) = map(int, input().split())
ds = DisjointSet(n)
for _ in range(q):
	(t, a, b) = map(int, input().split())
	if t == 0:
		ds.unite(a, b)
	elif t == 1:
		if ds.same(a, b):
			print(1)
		else:
			print(0)


class DisjoinSet:

	def __init__(self, size):
		self.rank = [0 for _ in range(size)]
		self.p = [0 for _ in range(size)]
		for i in range(n):
			self.makeSet(i)

	def makeSet(self, x):
		self.p[x] = x
		self.rank[x] = 0

	def same(self, x, y):
		print(int(self.findSet(x) == self.findSet(y)))

	def unite(self, x, y):
		self.link(self.findSet(x), self.findSet(y))

	def link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def findSet(self, x):
		if x != self.p[x]:
			self.p[x] = self.findSet(self.p[x])
		return self.p[x]
(n, q) = map(int, input().split())
D = DisjoinSet(n)
cmd = {0: lambda x, y: D.unite(x, y), 1: lambda x, y: D.same(x, y)}
for _ in range(q):
	(c, x, y) = map(int, input().split())
	cmd[c](x, y)


class UnionSet:

	def __init__(self, nmax: int) -> None:
		self.size = [1] * nmax
		self.id = [i for i in range(nmax)]

	def root(self, i: int) -> int:
		while i != self.id[i]:
			self.id[i] = self.id[self.id[i]]
			i = self.id[i]
		return i

	def connected(self, p: int, q: int) -> bool:
		return self.root(p) == self.root(q)

	def unite(self, p: int, q: int) -> None:
		(i, j) = (self.root(p), self.root(q))
		if i == j:
			return
		if self.size[i] < self.size[j]:
			self.id[i] = j
			self.size[j] += self.size[i]
		else:
			self.id[j] = i
			self.size[i] += self.size[j]
(n, q) = map(int, input().split())
u = UnionSet(n)
for _ in range(q):
	(op, x, y) = map(lambda x: int(x), input().split())
	if 0 == op:
		u.unite(x, y)
	else:
		print(f'{(1 if u.connected(x, y) else 0)}')


class UnionFind:

	def __init__(self, n):
		self.p = [i for i in range(n)]
		self.rank = [1] * n

	def root(self, x):
		if x == self.p[x]:
			return x
		self.p[x] = y = self.root(self.p[x])
		return y

	def unite(self, x, y):
		px = self.root(x)
		py = self.root(y)
		if px == py:
			return 0
		rx = self.rank[px]
		ry = self.rank[py]
		if ry < rx:
			self.p[py] = px
		elif rx < ry:
			self.p[px] = py
		else:
			self.p[py] = px
			self.rank[px] += 1
		return 1

	def same(self, x, y):
		px = self.root(x)
		py = self.root(y)
		return px == py
(n, q) = list(map(int, input().split()))
COMXY = [list(map(int, input().split())) for _ in range(q)]
union_find = UnionFind(n)
for comxy in COMXY:
	if comxy[0] == 0:
		union_find.unite(comxy[1], comxy[2])
	if comxy[0] == 1:
		if union_find.same(comxy[1], comxy[2]):
			print(1)
		else:
			print(0)


class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n + 1)]
		self.rank = [0] * (n + 1)

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.union(x, y)
	if com == 1:
		if uf.same(x, y):
			print(1)
		else:
			print(0)


from typing import List

class UnionFind:

	def __init__(self, V: int) -> None:
		self.V: int = V
		self.pi: List[int] = [i for i in range(V)]
		self.rank: int = [0 for _ in range(V)]

	def findSet(self, x: int) -> int:
		if x != self.pi[x]:
			self.pi[x] = self.findSet(self.pi[x])
		return self.pi[x]

	def same(self, x: int, y: int) -> bool:
		return self.findSet(x) == self.findSet(y)

	def link(self, x: int, y: int) -> None:
		if self.rank[x] > self.rank[y]:
			self.pi[y] = x
		else:
			self.pi[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def unite(self, x: int, y: int) -> None:
		self.link(self.findSet(x), self.findSet(y))
(n, q) = map(int, input().split())
UF = UnionFind(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		UF.unite(x, y)
	elif UF.same(x, y):
		print(1)
	else:
		print(0)


def find(x):
	if par[x] < 0:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def same(x, y):
	if find(x) == find(y):
		return True
	else:
		return False

def unite(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return
	if par[x] > par[y]:
		(x, y) = (y, x)
	par[x] += par[y]
	par[y] = x

def uCnt(x):
	return -par[find(x)]
(n, q) = map(int, input().split())
par = [-1 for i in range(n)]
for i in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		unite(x, y)
	elif same(x, y):
		print(1)
	else:
		print(0)


(N, Q) = map(int, input().strip().split())
P = [i for i in range(N)]

def root(x):
	path_to_root = []
	while P[x] != x:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def is_same_set(x, y):
	return root(x) == root(y)

def unite(x, y):
	P[root(x)] = root(y)
for i in range(Q):
	(q, x, y) = map(int, input().strip().split())
	if q == 0:
		unite(x, y)
	if q == 1:
		print(int(is_same_set(x, y)))


class UnionFind:

	def __init__(self, n):
		self.rank = [0] * n
		self.parent = [i for i in range(n)]

	def find(self, x):
		if self.parent[x] == x:
			return x
		else:
			self.parent[x] = self.find(self.parent[x])
			return self.parent[x]

	def merge(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.parent[x] = y
		elif self.rank[x] > self.rank[y]:
			self.parent[y] = x
		else:
			self.parent[x] = y
			self.rank[y] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.merge(x, y)
	else:
		print(1 if uf.same(x, y) else 0)


def search_root(x):
	i = x
	while True:
		if i == nodes[i]:
			nodes[x] = i
			return i
		else:
			i = nodes[i]

def unite(x, y):
	nodes[search_root(x)] = search_root(y)

def same(x, y):
	if search_root(x) == search_root(y):
		print(1)
	else:
		print(0)
(n, q) = map(int, input().split())
nodes = [i for i in range(n)]
commands = []
for _ in range(q):
	commands.append(input())
for cmd in commands:
	(c, x, y) = map(int, cmd.split())
	if c == 0:
		unite(x, y)
	else:
		same(x, y)


class Node:

	def __init__(self, data):
		self.data = data
		self.parent = self

def find_root(node):
	if node.parent == node:
		return node
	else:
		node.parent = find_root(node.parent)
		return node.parent

def unite(x, y):
	x_root = find_root(x)
	y_root = find_root(y)
	if x_root == y_root:
		return
	else:
		y_root.parent = x_root

def same(x, y):
	if find_root(x) == find_root(y):
		print(1)
	else:
		print(0)
(n, q) = map(int, input().split())
nodeset = []
for i in range(n):
	nodeset.append(Node(i))
for i in range(q):
	(com, x, y) = map(int, input().split())
	x_node = nodeset[x]
	y_node = nodeset[y]
	if com == 0:
		unite(x_node, y_node)
	else:
		same(x_node, y_node)


class UnionFind:

	def __init__(self, n):
		self.parents = [i for i in range(n)]
		self.sizes = [1] * n
		self.rank = [0] * n

	def find(self, i):
		if self.parents[i] == i:
			return i
		else:
			self.parents[i] = self.find(self.parents[i])
			return self.parents[i]

	def unite(self, i, j):
		pi = self.find(i)
		pj = self.find(j)
		if pi != pj:
			if self.rank[pi] < self.rank[pj]:
				self.sizes[pj] += self.sizes[pi]
				self.parents[pi] = pj
			else:
				self.sizes[pi] += self.sizes[pj]
				self.parents[pj] = pi
				if self.rank[pi] == self.rank[pj]:
					self.rank[pi] += 1

	def same(self, i, j):
		return self.find(i) == self.find(j)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for q in range(q):
	(cmd, i, j) = map(int, input().split())
	if cmd == 0:
		uf.unite(i, j)
	else:
		print(int(uf.same(i, j)))


import sys
sys.setrecursionlimit(500000)
(N, Q) = map(int, input().split())

class Uf:

	def __init__(self, N):
		self.Par = list(range(N + 1))

	def root(self, x):
		if self.Par[x] == x:
			return x
		else:
			self.Par[x] = self.root(self.Par[x])
			return self.Par[x]

	def same(self, x, y):
		return self.root(x) == self.root(y)

	def unite(self, x, y):
		x = self.root(x)
		y = self.root(y)
		if x != y:
			self.Par[x] = y
uf = Uf(N)
for i in range(Q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.unite(x, y)
	else:
		print(int(uf.same(x, y)))


class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n)]
		self.rank = [0] * n

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
(n, q) = map(int, input().split())
sets = UnionFind(n)
for _ in range(q):
	l = list(map(int, input().split()))
	if l[0] == 0:
		sets.union(l[1], l[2])
	elif sets.same(l[1], l[2]):
		print(1)
	else:
		print(0)


def root(x):
	path = []
	while P[x] != x:
		path.append(x)
		x = P[x]
	for node in path:
		P[node] = x
	return x

def check(x, y):
	if root(x) == root(y):
		return 1
	else:
		return 0

def unite(x, y):
	P[root(x)] = root(y)
(n, q) = map(int, input().split())
P = [i for i in range(n)]
for j in range(q):
	s = list(map(int, input().split()))
	if s[0] == 0:
		unite(s[1], s[2])
	else:
		print(check(s[1], s[2]))


from sys import stdin
(n, q) = map(int, stdin.readline().split())
ans = []
ans_append = ans.append
high = [0] * n
par = [i for i in range(n)]

def findSet(x):
	if par[x] == x:
		return x
	par[x] = findSet(par[x])
	return par[x]

def unite(x, y):
	x = findSet(x)
	y = findSet(y)
	if x == y:
		return
	if high[x] > high[y]:
		par[y] = x
	else:
		par[x] = y
		if high[x] == high[y]:
			high[y] += 1

def same(x, y):
	return findSet(x) == findSet(y)
for i in range(q):
	(t, a, b) = map(int, stdin.readline().split())
	if t == 0:
		unite(a, b)
	elif t == 1:
		ans_append(1 if same(a, b) else 0)
print(*ans, sep='\n')


def find(x):
	if p[x] == x:
		return x
	else:
		p[x] = find(p[x])
		return p[x]

def unite(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return
	if rank[x] < rank[y]:
		p[x] = y
	else:
		p[y] = x
		if rank[x] == rank[y]:
			rank[x] += 1

def same(x, y):
	if find(x) == find(y):
		return 1
	else:
		return 0
(n, q) = (int(x) for x in input().split())
p = [i for i in range(n)]
rank = [0 for i in range(n)]
for i in range(q):
	(com, x, y) = (int(x) for x in input().split())
	if com == 0:
		unite(x, y)
	else:
		print(same(x, y))


class UnionFindWithRank(object):
	par = []
	rank = []
	cache = True
	log = []

	def __init__(self, n):
		for i in range(n):
			self.par.append(i)
			self.rank.append(0)

	def root(self, x):
		if self.par[x] == x:
			return x
		else:
			p = self.root(self.par[x])
			self.par[x] = p
			return p

	def same(self, x, y):
		return self.root(x) == self.root(y)

	def unite(self, x, y):
		(ox, oy) = (x, y)
		x = self.root(x)
		y = self.root(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			(x, y) = (y, x)
			self.par[y] = x
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
(n, q) = map(int, input().split())
u = UnionFindWithRank(n)
for _ in range(q):
	(c, a, b) = map(int, input().split())
	(a, b) = (a, b)
	if c == 0:
		u.unite(a, b)
	else:
		print(1 if u.same(a, b) else 0)


class UnionFind:

	def __init__(self, n):
		self.rank = [0] * n
		self.parent = [i for i in range(n)]

	def find(self, x):
		if self.parent[x] == x:
			return x
		else:
			self.parent[x] = self.find(self.parent[x])
			return self.parent[x]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def unit(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.parent[x] = y
		elif self.rank[x] > self.rank[y]:
			self.parent[y] = x
		else:
			self.rank[x] += 1
			self.parent[y] = x
(n, q) = map(int, input().split())
u = UnionFind(n)
for i in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		u.unit(x, y)
	elif u.same(x, y):
		print(1)
	else:
		print(0)


class Disjointset:

	def __init__(self, n):
		self.rank = [0] * n
		self.p = [i for i in range(n)]

	def same(self, x, y):
		return self.findSet(x) == self.findSet(y)

	def unite(self, x, y):
		return self.link(self.findSet(x), self.findSet(y))

	def link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def findSet(self, x):
		if x != self.p[x]:
			self.p[x] = self.findSet(self.p[x])
		return self.p[x]
(n, q) = map(int, input().split())
ds = Disjointset(n)
ans = []
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		ds.unite(x, y)
	else:
		ans.append('1' if ds.same(x, y) else '0')
print('\n'.join(ans))


(n, q) = map(int, input().split())
queries = []
for _ in range(q):
	(com, x, y) = map(int, input().split())
	queries.append((com, x, y))
joining = [[x] for x in range(n)]

def unite(x, y):
	if joining[x] == joining[y]:
		return
	joining[x] += joining[y]
	for member in joining[y]:
		joining[member] = joining[x]

def is_same(x, y):
	return joining[x] == joining[y]
answers = []
for query in queries:
	if query[0] == 0:
		unite(query[1], query[2])
	else:
		answers.append(is_same(query[1], query[2]))
for answer in answers:
	if answer:
		print(1)
	else:
		print(0)


class UnionFind:
	__slots__ = ['forest']

	def __init__(self, forest: list):
		self.forest = forest

	def get_root(self, x: int) -> int:
		if self.forest[x] < 0:
			return x
		else:
			self.forest[x] = self.get_root(self.forest[x])
			return self.forest[x]

	def unite(self, x, y) -> None:
		(root_x, root_y) = (self.get_root(x), self.get_root(y))
		if root_x != root_y:
			(bigroot, smallroot) = (root_x, root_y) if self.forest[root_x] < self.forest[root_y] else (root_y, root_x)
			self.forest[bigroot] += self.forest[smallroot]
			self.forest[smallroot] = bigroot
(n, q) = map(int, input().split())
uf = UnionFind([-1 for _ in [None] * n])
for _ in [None] * q:
	(c, x, y) = map(int, input().split())
	if c == 0:
		uf.unite(x, y)
	else:
		print(1 if uf.get_root(x) == uf.get_root(y) else 0)


class UnionFind(object):

	def __init__(self, n=1):
		self.par = [i for i in range(n)]
		self.rank = [0 for _ in range(n)]

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x != y:
			if self.rank[x] < self.rank[y]:
				(x, y) = (y, x)
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
			self.par[y] = x

	def is_same(self, x, y):
		return self.find(x) == self.find(y)
(N, Q) = map(int, input().split())
uf = UnionFind(N)
for _ in range(Q):
	(P, A, B) = map(int, input().split())
	if P == 0:
		uf.union(A, B)
	elif uf.is_same(A, B):
		print(1)
	else:
		print(0)


class DisjointSet:

	def __init__(self, size):
		self.rank = [None] * size
		self.p = [None] * size
		for i in range(size):
			self.makeSet(i)

	def makeSet(self, x):
		self.p[x] = x
		self.rank[x] = 0

	def same(self, x, y):
		return self.findSet(x) == self.findSet(y)

	def unite(self, x, y):
		self.link(self.findSet(x), self.findSet(y))

	def link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def findSet(self, x):
		if x != self.p[x]:
			self.p[x] = self.findSet(self.p[x])
		return self.p[x]
(n, q) = map(int, input().split())
ds = DisjointSet(n)
for i in range(q):
	(t, a, b) = map(int, input().split())
	if t == 0:
		ds.unite(a, b)
	elif t == 1:
		if ds.same(a, b):
			print('1')
		else:
			print('0')


class UnionFind:

	def __init__(self, n):
		self.root = list(range(n + 1))
		self.size = [1] * (n + 1)

	def __getitem__(self, x):
		root = self.root
		while root[x] != x:
			root[x] = root[root[x]]
			x = root[x]
		return x

	def merge(self, x, y):
		x = self[x]
		y = self[y]
		if x == y:
			return
		(sx, sy) = (self.size[x], self.size[y])
		if sx < sy:
			(x, y) = (y, x)
			(sx, sy) = (sy, sx)
		self.root[y] = x
		self.size[x] += sy
(n, q) = map(int, input().split())
uni = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uni.merge(x, y)
	else:
		print(int(uni[x] == uni[y]))


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)
		self.rnk = [0] * (n + 1)

	def Find_Root(self, x):
		if self.root[x] < 0:
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return -self.root[self.Find_Root(x)]
(n, q) = map(int, input().split())
uf = UnionFind(n)
l = [list(map(int, input().split())) for _ in range(q)]
for i in range(q):
	(p, x, y) = (l[i][0], l[i][1], l[i][2])
	if not p:
		uf.Unite(x, y)
	else:
		print(1 if uf.isSameGroup(x, y) else 0)


(n, nq) = map(int, input().split())
set_list = list(range(n))

def find(n):
	global set_list
	if set_list[n] == n:
		return n
	result = set_list[n] = find(set_list[n])
	return result

def same(x, y):
	set_list[find(y)] = find(x)

def unite(x, y):
	return find(x) == find(y)
for _ in range(nq):
	(com, x, y) = map(int, input().split())
	if com == 0:
		same(x, y)
	elif unite(x, y):
		print(1)
	else:
		print(0)


class UnionFind:

	def __init__(self, num):
		self.rank = [0] * num
		self.par = [i for i in range(num)]
		self.n = num
		self.size = [1] * num

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] > self.rank[y]:
			self.par[y] = x
			self.size[x] += self.size[y]
			self.size[y] = 0
		else:
			self.par[x] = y
			self.size[y] += self.size[x]
			self.size[x] = 0
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def all_find(self):
		ls = []
		for i in range(len(self.par)):
			ls.append(self.find(i))
		return ls
(n, q) = map(int, input().split())
uf = UnionFind(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.union(x, y)
	else:
		print(int(uf.same(x, y)))


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.par = [-1] * (n + 1)
		self.size = [1] * (n + 1)

	def root(self, idx):
		if self.par[idx] == -1:
			return idx
		self.par[idx] = self.root(self.par[idx])
		return self.par[idx]

	def unite(self, idx1, idx2):
		idx1_par = self.root(idx1)
		idx2_par = self.root(idx2)
		if idx1_par == idx2_par:
			return
		if self.size[idx1_par] >= self.size[idx2_par]:
			self.size[idx1_par] += self.size[idx2_par]
			self.par[idx2_par] = idx1_par
		else:
			self.size[idx2_par] += self.size[idx1_par]
			self.par[idx1_par] = idx2_par

	def same(self, idx1, idx2):
		return self.root(idx1) == self.root(idx2)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.unite(x, y)
	elif uf.same(x, y):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())
lines = [list(map(int, input().split())) for i in range(q)]
set = []
c = 0
index = [-i - 1 for i in range(n)]
for line in lines:
	if line.pop(0) == 0:
		index_a = index[line[0]]
		index_b = index[line[1]]
		if index_a < 0 and index_b < 0:
			set += [line]
			index[line[0]] = c
			index[line[1]] = c
			c += 1
		elif index_a < 0:
			set[index_b] += [line[0]]
			index[line[0]] = index_b
		elif index_b < 0:
			set[index_a] += [line[1]]
			index[line[1]] = index_a
		elif index_a == index_b:
			continue
		else:
			set[index_a] += set[index_b]
			for i in set[index_b]:
				index[i] = index_a
	elif index[line[0]] == index[line[1]]:
		print(1)
	else:
		print(0)


import sys
input = sys.stdin.readline
from collections import deque

def main():
	(n, q) = map(int, input().split())
	s = [i for i in range(n)]
	dq = [deque() for i in range(n)]
	for i in range(n):
		dq[i].append(i)
	for i in range(q):
		(a, b, c) = map(int, input().split())
		if a == 0:
			sb = s[b]
			sc = s[c]
			if sb == sc:
				continue
			dq[sb].extend(dq[sc])
			dq[sc] = None
			for j in dq[sb]:
				s[j] = sb
		elif a == 1:
			if c in dq[s[b]]:
				print('1')
			else:
				print('0')
main()


import time
(N, Q) = map(int, input().split())
rank = [0 for i in range(N)]

class Tree:

	def __init__(self, par, key):
		self.par = par
		self.key = key
List = [Tree(i, i) for i in range(N)]

def unit(x, y):
	while List[x].par != x:
		x = List[x].par
	a = rank[x]
	while List[y].par != y:
		y = List[y].par
	b = rank[y]
	if a <= b:
		if a == b:
			rank[x] += 1
		List[y].par = x
	else:
		List[x].par = y

def Find(x, y):
	Q = []
	P = []
	while List[x].par != x:
		x = List[x].par
		Q.append(x)
	while List[y].par != y:
		y = List[y].par
		P.append(y)
	for xi in Q:
		List[xi].par = x
		rank[xi] = 1
	for yi in P:
		List[yi].par = y
		rank[yi] = 1
	if x == y:
		print(1)
	else:
		print(0)
for i in range(Q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unit(x, y)
	else:
		Find(x, y)


class UnionFind:

	def __init__(self, n):
		self.par = [x for x in range(n)]
		self.rank = [0] * n

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		(x, y) = (self.find(x), self.find(y))
		if self.rank[x] > self.rank[y]:
			self.par[y] = x
		elif self.rank[y] > self.rank[x]:
			self.par[x] = y
		else:
			self.par[x] = y
			self.rank[y] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(_c, _x, _y) = map(int, input().split())
	if _c == 0:
		uf.unite(_x, _y)
	elif uf.same(_x, _y):
		print('1')
	else:
		print('0')


(n, q) = map(int, input().split())
p = [-1] * n

def root(x):
	if p[x] == -1:
		return x
	p[x] = root(p[x])
	return p[x]

def unite(a, b):
	if root(a) != root(b):
		if a > b:
			(a, b) = (b, a)
		p[root(b)] = root(a)

def same(a, b):
	if root(a) == root(b):
		return True
	else:
		return False
for i in range(q):
	(c, a, b) = map(int, input().split())
	if c == 0:
		unite(a, b)
	if c == 1:
		if same(a, b):
			print(1)
		else:
			print(0)


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def same(self, a, b):
		return self.find(a) == self.find(b)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(str, input().split())
	x = int(x)
	y = int(y)
	if com == '0':
		uf.unite(x, y)
	if com == '1':
		if uf.same(x, y):
			print(1)
		else:
			print(0)


def root(x):
	path_to_root = []
	while P[x] != x:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def is_same_set(x, y):
	return root(x) == root(y)

def unite(x, y):
	P[root(x)] = root(y)
(n, q) = map(int, input().split())
P = [i for i in range(n)]
for _ in range(q):
	(a, b, c) = map(int, input().split())
	if a == 0:
		unite(b, c)
	elif a == 1:
		if is_same_set(b, c):
			print(1)
		else:
			print(0)


class UnionFindTree:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.parents[x] > self.parents[y]:
			(x, y) = (y, x)
		self.parents[x] += self.parents[y]
		self.parents[y] = x

def main():
	(n, q) = map(int, input().split())
	union_find = UnionFindTree(n)
	for _ in range(q):
		(com, x, y) = map(int, input().split())
		if com == 0:
			union_find.union(x, y)
		else:
			x_p = union_find.find(x)
			y_p = union_find.find(y)
			if x_p == y_p:
				print(1)
			else:
				print(0)
main()


from sys import stdin
high = [0] * 10000
par = [i for i in range(10000)]

def findSet(x):
	if par[x] == x:
		return x
	par[x] = findSet(par[x])
	return par[x]

def unite(x, y):
	x = findSet(x)
	y = findSet(y)
	if x == y:
		return
	if high[x] > high[y]:
		par[y] = x
	else:
		par[x] = y
		if high[x] == high[y]:
			high[y] += 1

def same(x, y):
	return findSet(x) == findSet(y)
(n, q) = map(int, stdin.readline().split())
ans = []
for i in range(q):
	(t, a, b) = map(int, stdin.readline().split())
	if t == 0:
		unite(a, b)
	elif t == 1:
		ans.append(1 if same(a, b) else 0)
print(*ans, sep='\n')


def find(x):
	global s
	if s[x] == x:
		return x
	s[x] = find(s[x])
	return s[x]
(n, q) = map(int, input().split())
s = [i for i in range(n)]
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com:
		if find(x) == find(y):
			print(1)
		else:
			print(0)
	else:
		s[find(y)] = find(x)


class UnionFind:

	def __init__(self, node_num):
		self._rank = [0] * node_num
		self._par = [i for i in range(node_num)]
		self.N = node_num

	def _find(self, x):
		if self._par[x] == x:
			return x
		else:
			self._par[x] = self._find(self._par[x])
			return self._par[x]

	def merge(self, x, y):
		x = self._find(x)
		y = self._find(y)
		if x == y:
			return
		if self._rank[x] < self._rank[y]:
			self._par[x] = y
		else:
			self._par[y] = x
			if self._rank[x] == self._rank[y]:
				self._rank[y] += 1

	def is_same(self, x, y):
		return self._find(x) == self._find(y)
(N, Q) = map(int, input().split())
uf = UnionFind(N)
for _ in range(Q):
	(C, X, Y) = map(int, input().split())
	if C == 0:
		uf.merge(X, Y)
	else:
		print(1 if uf.is_same(X, Y) else 0)


(n, p) = map(int, input().split())
nodes = [x for x in range(n)]
answer = []

def get_root(idx):
	if idx == nodes[idx]:
		return idx
	else:
		nodes[idx] = get_root(nodes[idx])
		return nodes[idx]
for i in range(p):
	(q, a, b) = map(int, input().split())
	if q == 0:
		parent_min = min(get_root(a), get_root(b))
		nodes[get_root(a)] = nodes[get_root(b)] = parent_min
	elif get_root(a) == get_root(b):
		answer.append(1)
	else:
		answer.append(0)
for i in answer:
	print(i)


import sys
sys.setrecursionlimit(10000)
(N, Q) = tuple(map(int, input().split()))
tree = [[-1, 1] for _ in range(N)]

def find(i):
	if tree[i][0] == -1:
		group = i
	else:
		group = find(tree[i][0])
		tree[i][0] = group
	return group

def unite(x, y):
	px = find(x)
	py = find(y)
	if tree[px][1] == tree[py][1]:
		tree[py][0] = px
		tree[px][1] += 1
	else:
		if tree[px][1] < tree[py][1]:
			(px, py) = (py, px)
		tree[py][0] = px
for _ in range(Q):
	(com, x, y) = tuple(map(int, input().split()))
	if com:
		print(int(find(x) == find(y)))
	elif not int(find(x) == find(y)):
		unite(x, y)


class UnionFind:

	def __init__(self, n):
		super().__init__()
		self.rank = [0] * n
		self.parent = [i for i in range(n)]

	def print_set(self):
		print(self.parent)
		print(self.rank)

	def find_set(self, x):
		if x != self.parent[x]:
			self.parent[x] = self.find_set(self.parent[x])
		return self.parent[x]

	def unite(self, x, y):
		x_parent = self.find_set(x)
		y_parent = self.find_set(y)
		if self.rank[x_parent] > self.rank[y_parent]:
			self.parent[y_parent] = x_parent
		else:
			self.parent[x_parent] = y_parent
			if self.rank[x_parent] == self.rank[y_parent]:
				self.rank[y_parent] += 1
(n, q) = map(int, input().split())
u = UnionFind(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		u.unite(x, y)
	elif u.find_set(x) == u.find_set(y):
		print(1)
	else:
		print(0)


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parent = [i for i in range(self.n)]
		self.rank = [0] * self.n

	def find_root(self, x):
		if self.parent[x] == x:
			return x
		else:
			self.parent[x] = self.find_root(self.parent[x])
			return self.parent[x]

	def unite(self, x, y):
		rx = self.find_root(x)
		ry = self.find_root(y)
		if rx == ry:
			return
		if self.rank[rx] < self.rank[ry]:
			self.parent[rx] = ry
		else:
			self.parent[ry] = rx
			if self.rank[rx] == self.rank[ry]:
				self.rank[rx] += 1

	def is_same(self, x, y):
		return self.find_root(x) == self.find_root(y)
(N, Q) = map(int, input().split())
uf = UnionFind(N)
for _ in range(Q):
	(p, a, b) = map(int, input().split())
	if p == 0:
		uf.unite(a, b)
	elif uf.is_same(a, b):
		print(1)
	else:
		print(0)


def union(x, y):
	link(findSet(x), findSet(y))

def link(x, y):
	if r[x] > r[y]:
		p[y] = x
	else:
		p[x] = y
		if r[x] == r[y]:
			r[y] = r[y] + 1

def findSet(x):
	if x != p[x]:
		p[x] = findSet(p[x])
	return p[x]
p = []
r = []
(n_set, n_quare) = map(int, input().split())
for i in range(n_set):
	p.append(i)
	r.append(0)
for i in range(n_quare):
	(q, x, y) = map(int, input().split())
	if q == 0:
		union(x, y)
	else:
		print(int(findSet(x) == findSet(y)))


import sys
sys.setrecursionlimit(10 ** 6)
(n, q) = map(int, input().split())
(*parent,) = range(n)

def root(x):
	if x != parent[x]:
		x = parent[x] = root(parent[x])
	return x

def unite(x, y):
	px = root(x)
	py = root(y)
	if px < py:
		parent[py] = px
	else:
		parent[px] = py

def same(x, y):
	return root(x) == root(y)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	else:
		print(int(same(x, y)))


(n, m) = map(int, input().split())
p = [i for i in range(n + 1)]

def root(n):
	pathroot = []
	while p[n] != n:
		pathroot.append(n)
		n = p[n]
	for node in pathroot:
		p[node] = n
	return n

def same(n, m):
	return root(p[n]) == root(p[m])

def union(n, m):
	p[root(n)] = root(m)
for i in range(m):
	(a, x, y) = map(int, input().split())
	if a == 1:
		if same(x, y):
			print(1)
		else:
			print(0)
	else:
		union(x, y)


(n, p) = map(int, input().split())
nodes = [x for x in range(n)]
answer = []

def get_root(idx):
	if idx == nodes[idx]:
		return idx
	else:
		return get_root(nodes[idx])
for i in range(p):
	(q, a, b) = map(int, input().split())
	if q == 0:
		parent_min = min(get_root(a), get_root(b))
		nodes[get_root(a)] = nodes[get_root(b)] = parent_min
	elif get_root(a) == get_root(b):
		answer.append(1)
	else:
		answer.append(0)
for i in answer:
	print(i)


(n, q) = list(map(int, input().split()))
parents = [-1 for _ in range(n)]

def root(i):
	if parents[i] == -1:
		return i
	else:
		parents[i] = root(parents[i])
		return parents[i]

def unite(x, y):
	if same(x, y):
		return
	x = root(x)
	y = root(y)
	parents[y] = x

def same(x, y):
	return root(x) == root(y)
for _ in range(q):
	(com, x, y) = list(map(int, input().split()))
	if com == 0:
		unite(x, y)
	elif com == 1:
		if same(x, y):
			print(1)
		else:
			print(0)
	else:
		raise Exception


import sys
sys.setrecursionlimit(1000000)
(n, q) = map(int, input().split())
parent = [i for i in range(n)]

def get_par(x):
	if x == parent[x]:
		return x
	parent[x] = get_par(parent[x])
	return parent[x]
for _ in range(q):
	(com, x, y) = map(int, input().split())
	(px, py) = (get_par(x), get_par(y))
	if com == 0:
		parent[px] = py
	else:
		print(int(px == py))


class UnionFind:

	def __init__(self, N):
		self.N = N
		self.parent = list(range(N))

	def root(self, x):
		path_to_root = []
		while self.parent[x] != x:
			path_to_root.append(x)
			x = self.parent[x]
		for node in path_to_root:
			self.parent[node] = x
		return x

	def same(self, x, y):
		return self.root(x) == self.root(y)

	def unite(self, x, y):
		self.parent[self.root(x)] = self.root(y)

	def __str__(self):
		groups = {}
		for x in range(self.N):
			root = self.root(x)
			if root in groups.keys():
				groups[root].append(x)
			else:
				groups[root] = [x]
		result = ''
		for root in groups.keys():
			result += str(groups[root]) + '\n'
		return result
(n, q) = map(int, input().split())
u = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		u.unite(x, y)
	elif u.same(x, y):
		print(1)
	else:
		print(0)


COM_UNITE = 0
COM_SAME = 1

class UnionFind:

	def __init__(self, n):
		self.parent = list(range(n))
		self.rank = [0] * n

	def find(self, x):
		if self.parent[x] == x:
			return x
		else:
			self.parent[x] = self.find(self.parent[x])
			return self.parent[x]

	def unite(self, x, y):
		(x, y) = (self.find(x), self.find(y))
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.parent[x] = y
		else:
			self.parent[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = (int(s) for s in input().split())
tree = UnionFind(n)
for i in range(q):
	(com, x, y) = (int(s) for s in input().split())
	if com == COM_UNITE:
		tree.unite(x, y)
	else:
		print(int(tree.same(x, y)))


class UnionFindTree:

	def __init__(self, n):
		self.par = [i for i in range(n + 1)]
		self.rank = [0] * (n + 1)

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.find(self.par[x])

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same_check(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = [int(x) for x in input().split(' ')]
uft = UnionFindTree(n - 1)
for i in range(q):
	(com, x, y) = [int(x) for x in input().split(' ')]
	if com == 0:
		uft.unite(x, y)
	elif com == 1:
		if uft.same_check(x, y):
			print(1)
		else:
			print(0)


(n, q) = map(int, input().split())
tree = [i for i in range(n)]

def root(x):
	pre = []
	while x != tree[x]:
		pre.append(x)
		x = tree[x]
	for node in pre:
		tree[node] = x
	return x

def unite(x, y):
	(X, Y) = (root(x), root(y))
	if X != Y:
		tree[X] = Y

def same(x, y):
	if root(x) == root(y):
		return print(1)
	else:
		return print(0)
for _ in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		unite(x, y)
	else:
		same(x, y)


def root(x, rt):
	if rt[x] == x:
		return x
	else:
		while rt[x] != x:
			rt[x] = root(rt[x], rt)
			return rt[x]

def union(x, y, rt, rank):
	rootx = root(x, rt)
	rooty = root(y, rt)
	if rootx == rooty:
		return 0
	elif rank[rootx] < rank[rooty]:
		rt[rootx] = rooty
	else:
		rt[rooty] = rootx
		if rank[rootx] == rank[rooty]:
			rank[rootx] += 1

def issame(x, y, rt):
	return root(x, rt) == root(y, rt)
(length, query) = (int(n) for n in input().split(' '))
rootlist = [n for n in range(length)]
rank = [0 for n in range(length)]
for q in range(query):
	(com, x, y) = (int(n) for n in input().split(' '))
	if com == 0:
		union(x, y, rootlist, rank)
	else:
		print(1 if issame(x, y, rootlist) else 0)


class UnionFind:

	def __init__(self, n):
		self._tree = [i for i in range(n)]
		self._rank = [1] * n

	def root(self, a):
		if self._tree[a] == a:
			return a
		self._tree[a] = self.root(self._tree[a])
		return self._tree[a]

	def is_same_set(self, a, b):
		return self.root(a) == self.root(b)

	def unite(self, a, b):
		ra = self.root(a)
		rb = self.root(b)
		if ra == rb:
			return
		if self._rank[ra] < self._rank[rb]:
			self._tree[ra] = rb
		else:
			self._tree[rb] = ra
			if self._rank[ra] == self._rank[rb]:
				self._rank[ra] += 1
(n, q) = map(int, input().split())
uft = UnionFind(n)
for i in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		uft.unite(x, y)
	else:
		print(1 if uft.is_same_set(x, y) else 0)


class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n + 1)]
		self.rank = [0] * (n + 1)

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same_check(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
u = UnionFind(n)
ans_list = []
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 1:
		ans = u.same_check(x, y)
		ans_list.append(ans)
	else:
		u.union(x, y)
for num in ans_list:
	print(int(num))


class UnionFindTree:

	def __init__(self):
		self.p = {}
		self.rank = {}

	def make(self, x):
		self.p[x] = x
		self.rank[x] = 0

	def find(self, x):
		if x in self.p:
			if self.p[x] != x:
				self.p[x] = self.find(self.p[x])
			return self.p[x]
		return None

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def unite(self, x, y):
		self._unite(self.find(x), self.find(y))

	def _unite(self, x, y):
		if self.rank[x] < self.rank[y]:
			self.p[x] = y
		else:
			self.p[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
(n, q) = map(int, input().split())
uft = UnionFindTree()
for i in range(n):
	uft.make(i)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uft.unite(x, y)
	else:
		print(1 if uft.same(x, y) else 0)


class DisjointSetElement:

	def __init__(self):
		self.parent = None
		self.anc = self

	def ancestor(self):
		s = self.anc
		while s.parent is not None:
			s = s.parent
		self.anc = s
		return s

	def unite(self, y):
		ax = self.ancestor()
		ay = y.ancestor()
		if ax is not ay:
			ax.parent = ay
			ax.anc = ay.anc

	def same(self, y):
		return self.ancestor() is y.ancestor()

def main():
	(n, q) = [int(x) for x in input().split()]
	elems = [DisjointSetElement() for _ in range(n)]
	for _ in range(q):
		(com, x, y) = [int(x) for x in input().split()]
		if com == 0:
			elems[x].unite(elems[y])
		else:
			print(1 if elems[x].same(elems[y]) else 0)
main()


import sys
sys.setrecursionlimit(1000000)

def find(x):
	if p[x] == x:
		return x
	else:
		p[x] = find(p[x])
		return p[x]

def unite(x, y):
	(px, py) = (find(x), find(y))
	p[px] = py
(n, q) = map(int, input().split())
p = list(range(n))
for _ in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		unite(x, y)
	else:
		print(1 if find(x) == find(y) else 0)


class UnionFind:

	def __init__(self, n):
		self.parent = [i for i in range(n)]
		self.height = [0 for i in range(n)]

	def get_root(self, i):
		if self.parent[i] == i:
			return i
		else:
			self.parent[i] = self.get_root(self.parent[i])
			return self.parent[i]

	def unite(self, i, j):
		root_i = self.get_root(i)
		root_j = self.get_root(j)
		if root_i != root_j:
			if self.height[root_i] < self.height[root_j]:
				self.parent[root_i] = root_j
			else:
				self.parent[root_j] = root_i
				if self.height[root_i] == self.height[root_j]:
					self.height[root_i] += 1

	def is_in_group(self, i, j):
		if self.get_root(i) == self.get_root(j):
			return 1
		else:
			return 0
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(a, b, c) = map(int, input().split())
	if a == 0:
		uf.unite(b, c)
	else:
		print(uf.is_in_group(b, c))


class UFT(object):

	def __init__(self):
		self.par = {i: i for i in range(10001)}
		self.rank = {i: 0 for i in range(10001)}

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def unite_chk(self, a, b):
		return self.find(a) == self.find(b)
obj = UFT()
(n, q) = map(int, input().split())
for _ in range(q):
	(c, x, y) = map(int, input().split())
	if c:
		print(int(obj.unite_chk(x, y)))
	else:
		obj.unite(x, y)


def init(N, parent, rank):
	for i in range(N):
		parent.append(i)
		rank.append(0)
	return (parent, rank)

def find(parent, v):
	if parent[v] == v:
		return v
	else:
		parent[v] = find(parent, parent[v])
		return parent[v]

def unite(parent, rank, a, b):
	a = find(parent, a)
	b = find(parent, b)
	if a == b:
		return
	elif rank[a] < rank[b]:
		parent[a] = b
		return parent
	elif rank[a] > b:
		parent[b] = a
		return parent
	else:
		parent[b] = a
		rank[a] += 1
		return (parent, rank)

def union_find():
	(N, Q) = [int(i) for i in input().split()]
	parent = []
	rank = []
	init(N, parent, rank)
	for i in range(Q):
		(P, A, B) = [int(i) for i in input().split()]
		if P == 0:
			unite(parent, rank, A, B)
		else:
			a = find(parent, A)
			b = find(parent, B)
			if a == b:
				print('1')
			else:
				print('0')
union_find()


(n, q) = map(int, input().split())
forest = [-1] * n

def get_root(x: int) -> int:
	if forest[x] < 0:
		return x
	else:
		forest[x] = get_root(forest[x])
		return forest[x]

def unite(x: int, y: int) -> None:
	(root_x, root_y) = (get_root(x), get_root(y))
	if root_x != root_y:
		(bigroot, smallroot) = (root_x, root_y) if forest[root_x] < forest[root_y] else (root_y, root_x)
		forest[bigroot] += forest[smallroot]
		forest[smallroot] = bigroot
for _ in [None] * q:
	(c, x, y) = map(int, input().split())
	if c == 0:
		unite(x, y)
	else:
		print(1 if get_root(x) == get_root(y) else 0)


(n, q) = map(int, input().split())
tag = [i for i in range(n)]
for _ in range(q):
	(cmmd, x, y) = map(int, input().split())
	if cmmd == 0:
		chng1 = []
		chng2 = []
		chng1.append(x)
		x = tag[x]
		chng2.append(y)
		y = tag[y]
		while x != tag[x]:
			chng1.append(x)
			x = tag[x]
		chng1.append(x)
		while y != tag[y]:
			chng2.append(y)
			y = tag[y]
		chng2.append(y)
		if x != y:
			if len(chng1) < len(chng2):
				for x_ in chng1:
					tag[x_] = y
			else:
				for y_ in chng2:
					tag[y_] = x
	else:
		while x != tag[x]:
			x = tag[x]
		while y != tag[y]:
			y = tag[y]
		if x != y:
			print(0)
		else:
			print(1)


(n, q) = map(int, input().split())
root_list = [i for i in range(n)]

def root(x):
	path_to_root = []
	while root_list[x] != x:
		path_to_root.append(x)
		x = root_list[x]
	for node in path_to_root:
		root_list[node] = x
	return x

def is_same_set(x, y):
	return root(x) == root(y)

def unite(x, y):
	root_list[root(x)] = root(y)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	elif is_same_set(x, y):
		print(1)
	else:
		print(0)


import sys

def solve():
	(n, q) = map(int, sys.stdin.readline().split())
	ds = [[i] for i in range(n)]
	n2s = [i for i in range(n)]
	ans = []
	for lp in range(q):
		(c, x, y) = map(int, sys.stdin.readline().split())
		if c == 0:
			merge(ds, n2s, x, y)
		else:
			ans.append(1 if n2s[x] == n2s[y] else 0)
	print(*ans, sep='\n')

def merge(ds, n2s, x, y):
	u = n2s[x]
	v = n2s[y]
	if u == v:
		return None
	if len(ds[u]) < len(ds[v]):
		ds[v].extend(ds[u])
		for w in ds[u]:
			n2s[w] = v
		del ds[u][:]
	else:
		ds[u].extend(ds[v])
		for w in ds[v]:
			n2s[w] = u
		del ds[v][:]

def debug(x, table):
	for (name, val) in table.items():
		if x is val:
			print('DEBUG:{} -> {}'.format(name, val), file=sys.stderr)
			return None
solve()


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.p = [i for i in range(n)]
		self.rank = [0] * n

	def same(self, x, y):
		return self.root(x) == self.root(y)

	def root(self, x):
		if x != self.p[x]:
			self.p[x] = self.root(self.p[x])
		return self.p[x]

	def unite(self, x, y):
		x = self.root(x)
		y = self.root(y)
		if self.rank[y] < self.rank[x]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[y] == self.rank[x]:
				self.rank[y] += 1

def main():
	(n, q) = map(int, input().split())
	UF = UnionFind(n)
	for _ in range(q):
		(a, b, c) = map(int, input().split())
		if a == 0:
			UF.unite(b, c)
		elif UF.same(b, c):
			print(1)
		else:
			print(0)
main()


import sys
sys.setrecursionlimit(10 ** 7)

def init(n):
	return list(range(n + 1))

def find(lis, x):
	if lis[x] == x:
		return x
	else:
		lis[x] = find(lis, lis[x])
		return lis[x]

def sameset(lis, x, y):
	return find(lis, x) == find(lis, y)

def union(lis, x, y):
	x = find(lis, x)
	y = find(lis, y)
	if x != y:
		lis[x] = y
(n, q) = map(int, input().split())
union_find_lis = init(n - 1)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		union(union_find_lis, x, y)
	elif sameset(union_find_lis, x, y):
		print(1)
	else:
		print(0)


class UnionFind:

	def __init__(self, n):
		self.rank = [0] * n
		self.par = list(range(n))

	def find(self, x):
		children = []
		while self.par[x] != x:
			children.append(x)
			x = self.par[x]
		for c in children:
			self.par[c] = x
		return x

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def union(self, x, y):
		if self.same(x, y):
			return
		rx = self.find(x)
		ry = self.find(y)
		if self.rank[rx] > self.rank[ry]:
			self.par[ry] = rx
		elif self.rank[rx] == self.rank[ry]:
			self.par[ry] = rx
			self.rank[rx] += 1
		else:
			self.par[rx] = ry
(n, q) = [int(x) for x in input().split()]
uf = UnionFind(n)
for _ in range(q):
	(cmd, x, y) = [int(x) for x in input().split()]
	if cmd == 0:
		uf.union(x, y)
	else:
		print(int(uf.same(x, y)))


def main():
	(n, q) = input().split()
	n = int(n)
	q = int(q)
	nums = [i for i in range(n)]
	rank = [0 for i in range(n)]

	def find_top(x):
		if nums[x] != x:
			nums[x] = find_top(nums[x])
		return nums[x]

	def unite(x, y):
		x = find_top(x)
		y = find_top(y)
		if rank[x] > rank[y]:
			nums[y] = x
		else:
			nums[x] = y
			if rank[x] == rank[y]:
				rank[y] += 1

	def same(x, y):
		return find_top(x) == find_top(y)
	for _ in range(q):
		query = input().split()
		(com, x, y) = tuple(map(int, query))
		if com == 0:
			unite(x, y)
		else:
			print(same(x, y) * 1)
main()


class Node:

	def __init__(self, id):
		self.id = id
		self.p = self
		self.rank = 0

class DisjointSet:

	def __init__(self, n):
		self.nodes = {}
		for i in range(n):
			self.makeSet(i)

	def makeSet(self, i):
		self.nodes[i] = Node(i)

	def findSet(self, x):
		if x.p is not x:
			x.p = self.findSet(x.p)
		return x.p

	def unite(self, x, y):
		px = self.findSet(x)
		py = self.findSet(y)
		if px.rank > py.rank:
			py.p = px
		else:
			px.p = py
		if x.rank == y.rank:
			py.rank += 1

	def bool(self, x, y):
		return self.findSet(x) == self.findSet(y)
(n, q) = map(int, input().split())
uf = DisjointSet(n)
for i in range(q):
	(com, ix, iy) = map(int, input().split())
	if com == 0:
		uf.unite(uf.nodes[ix], uf.nodes[iy])
	else:
		print(1 if uf.bool(uf.nodes[ix], uf.nodes[iy]) else 0)


import sys
sys.setrecursionlimit(10000)
(n, q) = map(int, input().split())

def root(x):
	if par[x] == x:
		return x
	else:
		par[x] = root(par[x])
		return par[x]

def unite(x, y):
	rx = root(x)
	ry = root(y)
	if rx != ry:
		par[rx] = ry

def same(x, y):
	return root(x) == root(y)
par = [i for i in range(n)]
for i in range(q):
	(p, a, b) = map(int, input().split())
	if p:
		print(1 if same(a, b) else 0)
	else:
		unite(a, b)


import sys
input = sys.stdin.readline
sys.setrecursionlimit(pow(10, 6))

class UnionFind:

	def __init__(self, size):
		self.size = size
		self.parent = [i for i in range(size)]
		self.size = [1 for _ in range(size)]
		self.height = [1 for _ in range(size)]

	def root(self, i):
		if i != self.parent[i]:
			self.parent[i] = self.root(self.parent[i])
		return self.parent[i]

	def union(self, i, j):
		(pi, pj) = (self.root(i), self.root(j))
		if pi == pj:
			return
		if self.height[pi] < self.height[pj]:
			self.parent[pi] = pj
			self.size[pj] += self.size[pi]
		else:
			self.parent[pj] = pi
			self.size[pi] += self.size[pj]
			if self.height[pi] == self.height[pj]:
				self.height[pi] += 1

	def is_same(self, i, j):
		return self.root(i) == self.root(j)

def main():
	(n, q) = map(int, input().split())
	uf = UnionFind(n)
	for _ in range(q):
		(c, x, y) = map(int, input().split())
		if c == 1:
			if uf.is_same(x, y):
				print(1)
			else:
				print(0)
		else:
			uf.union(x, y)
main()


class UnionFind:

	def __init__(self, dimension):
		self.root = [i for i in range(dimension)]
		self.height = [1 for i in range(dimension)]

	def parent(self, i):
		p = self.root[i]
		if i == p:
			return p
		else:
			pp = self.parent(p)
			self.root[i] = pp
			return pp

	def unite(self, i1, i2):
		p1 = self.parent(i1)
		p2 = self.parent(i2)
		if self.height[p1] < self.height[p2]:
			self.root[p1] = p2
		else:
			self.root[p2] = p1
			if self.height[p1] == self.height[p2]:
				self.height[p1] += 1

	def same(self, i1, i2):
		return self.parent(i1) == self.parent(i2)
(n, q) = map(int, input().strip().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().strip().split())
	if com == 0:
		uf.unite(x, y)
	else:
		print(1 if uf.same(x, y) else 0)


import sys
line = input().split()
n = int(line[0])
q = int(line[1])
mat = [0] * n
for i in range(n):
	mat[i] = i
sys.setrecursionlimit(100000)

def root(a):
	if mat[a] == a:
		return a
	else:
		mat[a] = root(mat[a])
		return mat[a]

def union(a, b):
	mat[root(a)] = root(b)

def is_same(a, b):
	if root(a) == root(b):
		return 1
	else:
		return 0
for i in range(q):
	line = input().split()
	a = int(line[0])
	line[1] = int(line[1]) - 1
	line[2] = int(line[2]) - 1
	if a == 0:
		union(mat[line[1]], mat[line[2]])
	if a == 1:
		print(is_same(mat[line[1]], mat[line[2]]))


from sys import stdin
high = [0] * 10000
par = [i for i in range(10000)]

def findSet(x):
	if par[x] == x:
		return x
	par[x] = findSet(par[x])
	return par[x]

def unite(x, y):
	x = findSet(x)
	y = findSet(y)
	if x == y:
		return
	if high[x] > high[y]:
		par[y] = x
	else:
		par[x] = y
		if high[x] == high[y]:
			high[y] += 1

def same(x, y):
	return findSet(x) == findSet(y)
(n, q) = map(int, stdin.readline().split())
ans = []
ans_append = ans.append
for i in range(q):
	(t, a, b) = map(int, stdin.readline().split())
	if t == 0:
		unite(a, b)
	elif t == 1:
		ans_append(1 if same(a, b) else 0)
print(*ans, sep='\n')


def makeSet(x):
	p[x] = x
	rank[x] = 0

def union(x, y):
	link(findSet(x), findSet(y))

def link(x, y):
	if rank[x] > rank[y]:
		p[y] = x
	else:
		p[x] = y
		if rank[x] == rank[y]:
			rank[y] += 1

def findSet(x):
	if x != p[x]:
		p[x] = findSet(p[x])
	return p[x]
(n, q) = map(int, input().split())
p = [0] * n
rank = [0] * n
for x in range(n):
	makeSet(x)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		union(x, y)
	elif findSet(x) == findSet(y):
		print('1')
	else:
		print('0')


import sys
sys.setrecursionlimit(10000)

class Node:

	def __init__(self):
		self.root = self
		self.child = None
		self.length = 1

	def set_root(self, root):
		if self.child:
			self.child.set_root(root)
		self.root = root

	def set_child(self, child):
		if self.child:
			self.child.set_child(child)
		else:
			self.child = child
(n, q) = [int(i) for i in input().split()]
A = []
for i in range(n):
	A.append(Node())
for i in range(q):
	(c, x, y) = [int(i) for i in input().split()]
	if c == 0:
		if A[x].root == A[y].root:
			continue
		if A[x].root.length < A[y].root.length:
			A[y].set_child(A[x].root)
			A[y].root.length += A[x].root.length
			A[x].root.set_root(A[y].root)
		else:
			A[x].set_child(A[y].root)
			A[x].root.length += A[y].root.length
			A[y].root.set_root(A[x].root)
	elif A[x].root == A[y].root:
		print(1)
	else:
		print(0)


class unionfind:
	sz = 0
	par = []

	def __init__(self, n):
		self.sz = n
		for i in range(n):
			self.par.append(-1)

	def find(self, a):
		if self.par[a] < 0:
			return a
		self.par[a] = self.find(self.par[a])
		return self.par[a]

	def size(self, a):
		a = self.find(a)
		return -self.par[a]

	def same(self, a, b):
		return self.find(a) == self.find(b)

	def unite(self, a, b):
		a = self.find(a)
		b = self.find(b)
		if self.same(a, b):
			return False
		if self.size(a) < self.size(b):
			(a, b) = (b, a)
		self.par[a] += self.par[b]
		self.par[b] = a
		return True
(n, q) = map(int, input().split())
UF = unionfind(n + 1)
for _ in range(q):
	(c, a, b) = map(int, input().split())
	if c == 0:
		UF.unite(a, b)
	elif UF.same(a, b):
		print(1)
	else:
		print(0)


def find(x):
	if par[x] < 0:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return False
	else:
		if par[x] > par[y]:
			(x, y) = (y, x)
		par[x] += par[y]
		par[y] = x
		return True

def same(x, y):
	return find(x) == find(y)
(n, q) = map(int, input().split())
par = [-1] * n
for i in range(q):
	(j, x, y) = map(int, input().split())
	if j == 0:
		unite(x, y)
	else:
		print(1 if same(x, y) else 0)


from pprint import pprint
from collections import deque, defaultdict
import itertools
import math
import sys
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.buffer.readline
INF = float('inf')
(n, q) = map(int, input().split())
queries = []
for _ in range(q):
	(com, x, y) = map(int, input().split())
	queries.append([com, x, y])
parents = [i for i in range(n)]
size = [1 for _ in range(n)]

def find(x):
	if x != parents[x]:
		parents[x] = find(parents[x])
	return parents[x]

def same(x, y):
	return find(x) == find(y)

def unite(x, y):
	x_root = find(x)
	y_root = find(y)
	if x_root == y_root:
		return
	if x_root < y_root:
		(x_root, y_root) = (y_root, x_root)
	parents[y_root] = x_root
	size[x_root] += size[y_root]
for (com, x, y) in queries:
	if com == 0:
		unite(x, y)
	elif same(x, y):
		print(1)
	else:
		print(0)


class DisjointSet:

	def __init__(self, n):
		self.p = [x for x in range(n)]
		self.rank = [0 for x in range(n)]

	def find_set(self, x):
		if self.p[x] != x:
			self.p[x] = self.find_set(self.p[x])
		return self.p[x]

	def link(self, x, y):
		if self.rank[y] < self.rank[x]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def union(self, x, y):
		self.link(self.find_set(x), self.find_set(y))

	def same(self, x, y):
		return self.find_set(x) == self.find_set(y)
(n, q) = list(map(int, input().split()))
S = DisjointSet(n)
for i in range(q):
	(com, x, y) = list(map(int, input().split()))
	if com == 0:
		S.union(x, y)
	elif com == 1:
		if S.same(x, y):
			print(1)
		else:
			print(0)


import sys
input = sys.stdin.readline

def root(s):
	global pa
	if pa[s] == s:
		return s
	pa[s] = p = root(pa[s])
	return p

def unite(s, t):
	global pa
	a = root(s)
	b = root(t)
	if a == b:
		return 1
	elif rank[a] == rank[b]:
		pa[b] = a
		rank[a] += 1
	elif rank[a] < rank[b]:
		pa[a] = b
	else:
		pa[b] = a
(n, q) = map(int, input().split())
pa = [i for i in range(n)]
rank = [1] * n
for i in range(q):
	(a, b, c) = map(int, input().split())
	if a == 0:
		unite(b, c)
	elif root(b) == root(c):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())
group = [[i] for i in range(n)]
key = [i for i in range(n)]
for j in range(q):
	(com, x, y) = map(int, input().split())
	if com == 1:
		if key[x] == key[y]:
			print(1)
		else:
			print(0)
	elif key[x] != key[y]:
		v = key[y]
		group[key[x]] += group[v]
		for i in group[v]:
			key[i] = key[x]
		group[v] = []


import sys
sys.setrecursionlimit(10 ** 6)
(n, q) = map(int, input().split())
pair = [i for i in range(n)]

def root(x):
	if pair[x] == x:
		return x
	else:
		pair[x] = root(pair[x])
		return pair[x]
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		x1 = root(x - 1)
		y1 = root(y - 1)
		if x1 != y1:
			pair[x1] = y1
	elif com == 1:
		if root(x - 1) == root(y - 1):
			print(1)
		else:
			print(0)


import sys
f = sys.stdin

def unite(x, y):
	global dat
	(x, y) = (find(dat, x), find(dat, y))
	if x == y:
		return True
	if dat[y] < dat[x]:
		(x, y) = (y, x)
	dat[x] += dat[y]
	dat[y] = x
	return False

def same(x, y):
	global dat
	(x, y) = (find(dat, x), find(dat, y))
	print(1 if x == y else 0)

def find(dat, x):
	if dat[x] < 0:
		return x
	dat[x] = find(dat, dat[x])
	return dat[x]
com = (unite, same)
(n, q) = map(int, f.readline().split())
dat = [-1] * n
for (c, x, y) in (map(int, f.readline().split()) for _ in range(q)):
	com[c](x, y)


class DisjointSet:

	def __init__(self, size):
		self.rank = [None] * size
		self.p = [None] * size
		for i in range(size):
			self.make_set(i)
		return

	def make_set(self, x):
		self.p[x] = x
		self.rank[x] = 0
		return

	def same(self, x, y):
		return self.find_set(x) == self.find_set(y)

	def unite(self, x, y):
		self.link(self.find_set(x), self.find_set(y))
		return

	def link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def find_set(self, x):
		if x != self.p[x]:
			self.p[x] = self.find_set(self.p[x])
		return self.p[x]
(n, q) = map(int, input().split())
djs = DisjointSet(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		djs.unite(x, y)
	else:
		print(int(djs.same(x, y)))


class Node:

	def __init__(self):
		self.par = self
		self.rank = 1

class Utree:

	def __init__(self, n):
		self.nodes = [Node() for i in range(n)]

	def root(self, x):
		if x.par is x:
			return x
		else:
			r = self.root(x.par)
			x.par = r
			return r

	def unite(self, x, y):
		xr = self.root(self.nodes[x])
		yr = self.root(self.nodes[y])
		if xr.rank < yr.rank:
			xr.par = yr
			yr.rank += xr.rank
		else:
			yr.par = xr
			xr.rank += yr.rank

	def same(self, x, y):
		return self.root(self.nodes[x]) is self.root(self.nodes[y])
(n, q) = map(int, input().split())
ut = Utree(n)
for i in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		ut.unite(x, y)
	else:
		print(1 if ut.same(x, y) else 0)


class UF:

	def __init__(self, N):
		self.parents = [-1] * N

	def find(self, n):
		if self.parents[n] < 0:
			return n
		else:
			self.parents[n] = self.find(self.parents[n])
			return self.parents[n]

	def union(self, u, v):
		(p1, p2) = (self.find(u), self.find(v))
		if p1 == p2:
			return
		if p1 > p2:
			(p1, p2) = (p2, p1)
		self.parents[p1] += self.parents[p2]
		self.parents[p2] = p1

	def same(self, u, v):
		return self.find(u) == self.find(v)
(n, q) = map(int, input().split())
uf = UF(n)
for _ in range(q):
	(i, u, v) = map(int, input().split())
	if i == 0:
		uf.union(u, v)
	elif uf.same(u, v):
		print(1)
	else:
		print(0)


class UnionFind:

	def __init__(self, N):
		self.parent = list(range(N))
		self.rank = [0] * N
		self.size = [1] * N

	def find(self, x):
		r = x
		while self.parent[r] != r:
			r = self.parent[r]
		while self.parent[x] != r:
			(x, self.parent[x]) = (self.parent[x], r)
		return r

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.parent[x] = y
			self.size[y] += self.size[x]
		else:
			self.parent[y] = x
			self.size[x] += self.size[y]
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def get_size(self, x):
		return self.size[self.find(x)]
(n, q) = map(int, input().split())
uf = UnionFind(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.unite(x, y)
	else:
		print(1 if uf.same(x, y) else 0)


import sys
input = lambda : sys.stdin.readline().rstrip()
(n, q) = map(int, input().split())
parents = [-1] * n

def find(x):
	if parents[x] < 0:
		return x
	else:
		parents[x] = find(parents[x])
		return parents[x]

def union(x, y):
	x = find(x)
	y = find(y)
	if x == y:
		return
	if parents[x] > parents[y]:
		(x, y) = (y, x)
	parents[x] += parents[y]
	parents[y] = x

def same(x, y):
	return find(x) == find(y)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		union(x, y)
	elif same(x, y):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())
P = [i for i in range(n)]

def root(x):
	path_to_root = []
	while P[x] != x:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def same(x, y):
	return root(x) == root(y)

def unite(x, y):
	P[root(x)] = root(y)
for i in range(q):
	(t, x, y) = map(int, input().split())
	if t == 0:
		unite(x, y)
	else:
		print('1' if same(x, y) else '0')


def fg(x):
	if g[x] == x:
		return x
	re = fg(g[x])
	g[x] = re
	return re

def kg(x, y):
	x = fg(x)
	y = fg(y)
	if d[y] > d[x]:
		g[x] = y
	else:
		g[y] = x
	if d[x] == d[y]:
		d[x] += 1
(n, q) = map(int, input().split())
d = [0] * n
g = [x for x in range(n)]
for _ in range(q):
	(c, x, y) = map(int, input().split())
	if c:
		print((fg(x) == fg(y)) * 1)
	else:
		kg(x, y)


import sys
sys.setrecursionlimit(10 ** 5)

def solve():
	(n, q) = map(int, sys.stdin.readline().split())
	uf = UnionFind(n)
	ans = []
	for lp in range(q):
		(c, x, y) = map(int, sys.stdin.readline().split())
		if c == 0:
			uf.unite(x, y)
		else:
			ans.append(1 if uf.is_same(x, y) else 0)
	print(*ans, sep='\n')

class UnionFind:

	def __init__(self, n):
		self.ds = [i for i in range(n)]
		self.root = [i for i in range(n)]

	def find_root(self, x):
		if x != self.root[x]:
			self.root[x] = self.find_root(self.root[x])
		return self.root[x]

	def is_same(self, x, y):
		return self.find_root(x) == self.find_root(y)

	def unite(self, x, y):
		p = self.find_root(x)
		q = self.find_root(y)
		self.root[p] = q

def debug(x, table):
	for (name, val) in table.items():
		if x is val:
			print('DEBUG:{} -> {}'.format(name, val), file=sys.stderr)
			return None
solve()


(N, Q) = map(int, input().split())
P = [i for i in range(N)]

def root(x):
	path_to_root = []
	while P[x] != x:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def is_same_set(x, y):
	return root(x) == root(y)

def unite(x, y):
	P[root(x)] = root(y)
for _ in range(Q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	elif com == 1:
		if is_same_set(x, y):
			print(1)
		else:
			print(0)


class Union_find:

	def __init__(self, N):
		self.Group = [i for i in range(N)]

	def find(self, x):
		while self.Group[x] != x:
			x = self.Group[x]
		return x

	def Union(self, x, y):
		if self.find(x) != self.find(y):
			self.Group[self.find(y)] = self.Group[self.find(x)] = min(self.find(y), self.find(x))
(N, q) = map(int, input().split())
A = Union_find(N)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		A.Union(x, y)
	elif A.find(x) == A.find(y):
		print(1)
	else:
		print(0)


def root(x):
	path_to_root = []
	while x != P[x]:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def unite(x, y):
	P[root(x)] = root(y)

def is_same_set(x, y):
	return root(x) == root(y)
(n, q) = map(int, input().split())
P = [i for i in range(n)]
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	elif is_same_set(x, y):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())

class UnionFind(object):

	def __init__(self, n=1):
		self.par = [i for i in range(n)]
		self.rank = [0 for _ in range(n)]

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x != y:
			if self.rank[x] < self.rank[y]:
				(x, y) = (y, x)
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1
			self.par[y] = x

	def is_same(self, x, y):
		return self.find(x) == self.find(y)
uf = UnionFind(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.union(x, y)
	elif uf.is_same(x, y):
		print(1)
	else:
		print(0)


(n, q) = map(int, input().split())
p = [i for i in range(n)]

def root(x):
	path_to_root = []
	while p[x] != x:
		path_to_root.append(x)
		x = p[x]
	for node in path_to_root:
		p[node] = x
	return x
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com:
		print(int(root(x) == root(y)))
	else:
		p[root(x)] = root(y)


class UnionSet:

	def __init__(self, nmax):
		self.size = [1] * nmax
		self.id = [i for i in range(nmax + 1)]

	def root(self, i):
		while i != self.id[i]:
			self.id[i] = self.id[self.id[i]]
			i = self.id[i]
		return i

	def connected(self, p, q):
		return self.root(p) == self.root(q)

	def unite(self, p, q):
		(i, j) = (self.root(p), self.root(q))
		if i == j:
			return
		if self.size[i] < self.size[j]:
			self.id[i] = j
			self.size[j] += self.size[i]
		else:
			self.id[j] = i
			self.size[i] += self.size[j]
(n, q) = map(int, input().split())
u = UnionSet(n)
for i in range(q):
	(cmd, x, y) = map(int, input().split())
	if cmd == 0:
		u.unite(x, y)
	else:
		print(1 if u.connected(x, y) else 0)


def root(x):
	path_to_root = []
	while P[x] != x:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def is_same_set(x, y):
	return root(x) == root(y)

def unite(x, y):
	P[root(x)] = root(y)
(N, Q) = map(int, input().strip().split(' '))
P = [i for i in range(N)]
for i in range(Q):
	(com, x, y) = map(int, input().strip().split(' '))
	if com == 0:
		unite(x, y)
	elif is_same_set(x, y):
		print(1)
	else:
		print(0)


class UnionFind:
	MAX_N = 0
	PAR = []
	RANK = []

	def __init__(self, n):
		self.MAX_N = n
		self.PAR = [i for i in range(n)]
		self.RANK = [0] * n

	def find(self, x):
		if self.PAR[x] == x:
			return x
		else:
			self.PAR[x] = self.find(self.PAR[x])
			return self.PAR[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.RANK[x] < self.RANK[y]:
			self.PAR[x] = y
		else:
			self.PAR[y] = x
			if self.RANK[x] == self.RANK[y]:
				self.RANK[x] += 1

	def same(self, x, y):
		return self.find(x) == self.find(y)
(N, Q) = map(int, input().split())
Ans = []
tree = UnionFind(N + 1)
for _ in range(Q):
	(t, u, v) = map(int, input().split())
	if t == 0:
		tree.union(u, v)
	elif tree.same(u, v):
		Ans.append(1)
	else:
		Ans.append(0)
for a in Ans:
	print(a)


class DisjointSet:

	def __init__(self, n):
		self.p = list(range(n))
		self.rank = [0] * n

	def same(self, x, y):
		return self.find_set(x) == self.find_set(y)

	def unite(self, x, y):
		self.__link(self.find_set(x), self.find_set(y))

	def __link(self, x, y):
		if self.rank[x] > self.rank[y]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def find_set(self, x):
		if x != self.p[x]:
			self.p[x] = self.find_set(self.p[x])
		return self.p[x]

def main():
	(n, q) = map(int, input().split())
	ds = DisjointSet(n)
	for _ in range(q):
		(com, x, y) = map(int, input().split())
		if com == 0:
			ds.unite(x, y)
		elif com == 1:
			print(1 if ds.same(x, y) else 0)
main()


class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n + 1)]
		self.rank = [0] * (n + 1)

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same_check(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split())
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.union(x, y)
	elif com == 1:
		if uf.same_check(x, y):
			print('1')
		else:
			print('0')


import collections
import itertools
import operator

class UnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n + 1)]
		self.rank = [0] * (n + 1)

	def find(self, x):
		if self.par[x] == x:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
		else:
			self.par[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

	def same_check(self, x, y):
		return self.find(x) == self.find(y)
(a, b) = map(int, input().split())
uf = UnionFind(a)
for i in range(b):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.union(x, y)
	elif com == 1:
		print(1 if uf.same_check(x, y) else 0)


from sys import stdin

class DisjointSet:

	def __init__(self):
		self.parent = None
		self.ancestor = self

def ancestor(elems, x):
	s = elems[x].ancestor
	while s.parent is not None:
		s = s.parent
	elems[x].ancestor = s
	return s

def unite(elems, x, y):
	ax = ancestor(elems, x)
	ay = ancestor(elems, y)
	if ax is not ay:
		parent = DisjointSet()
		ax.parent = ay.parent = parent

def same(elems, x, y):
	return ancestor(elems, x) is ancestor(elems, y)

def main():
	(n, q) = [int(x) for x in input().split()]
	elems = [DisjointSet() for _ in range(n)]
	for _ in range(q):
		(com, x, y) = [int(x) for x in input().split()]
		if com == 0:
			unite(elems, x, y)
		else:
			print(1 if same(elems, x, y) else 0)
main()


class DisjointSet:

	def __init__(self, size):
		self.p = [i for i in range(size)]
		self.rank = [0] * size

	def same(self, x, y):
		return self.find_set(x) == self.find_set(y)

	def unite(self, x, y):
		self.link(self.find_set(x), self.find_set(y))

	def link(self, x, y):
		if self.rank[y] < self.rank[x]:
			self.p[y] = x
		else:
			self.p[x] = y
			if self.rank[x] == self.rank[y]:
				self.rank[y] += 1

	def find_set(self, x):
		if x != self.p[x]:
			self.p[x] = self.find_set(self.p[x])
		return self.p[x]
(n, q) = map(int, input().split())
ds = DisjointSet(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		ds.unite(x, y)
	if com == 1:
		print(1 if ds.same(x, y) else 0)


(n, q) = map(int, input().split())
par = [-1] * n

def find(v):
	if par[v] < 0:
		return v
	else:
		par[v] = find(par[v])
		return par[v]

def union(u, v):
	root_u = find(u)
	root_v = find(v)
	if root_u == root_v:
		return
	if par[root_u] > par[root_v]:
		par[root_v] += par[root_u]
		par[root_u] = root_v
	else:
		par[root_u] += par[root_v]
		par[root_v] = root_u

def same(u, v):
	if find(u) == find(v):
		return True
	else:
		return False
for i in range(q):
	(c, x, y) = map(int, input().split())
	if c == 0:
		union(x, y)
	else:
		ans = same(x, y)
		if ans:
			print(1)
		else:
			print(0)


import sys

def solve():
	(n, q) = map(int, sys.stdin.readline().split())
	ds = [[i] for i in range(n)]
	n2s = [i for i in range(n)]
	ans = []
	for lp in range(q):
		(c, x, y) = map(int, sys.stdin.readline().split())
		if c == 0:
			merge(ds, n2s, x, y)
		else:
			ans.append(1 if n2s[x] == n2s[y] else 0)
	print(*ans, sep='\n')

def merge(ds, n2s, x, y):
	u = n2s[x]
	v = n2s[y]
	if u == v:
		return None
	ds[v].extend(ds[u])
	for w in ds[u]:
		n2s[w] = v
	del ds[u][:]

def debug(x, table):
	for (name, val) in table.items():
		if x is val:
			print('DEBUG:{} -> {}'.format(name, val), file=sys.stderr)
			return None
solve()


class UnionFind:

	def __init__(self, N):
		self.par = [-1 for i in range(N)]

	def find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def unite(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.par[x] > self.par[y]:
			(x, y) = (y, x)
		self.par[x] += self.par[y]
		self.par[y] = x

	def size(self, x):
		return -self.par[self.find(x)]

	def same(self, x, y):
		return self.find(x) == self.find(y)
(n, q) = map(int, input().split(' '))
uf = UnionFind(n)
for i in range(q):
	(com, x, y) = map(int, input().split(' '))
	if com == 0:
		uf.unite(x, y)
	else:
		print(int(uf.same(x, y)))


class Unionfind:

	def __init__(self, n):
		self.par = [-1] * n

	def find(self, x):
		if self.par[x] < 0:
			return x
		else:
			self.par[x] = self.find(self.par[x])
			return self.par[x]

	def same(self, x, y):
		return self.find(x) == self.find(y)

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return False
		if self.par[x] > self.par[y]:
			(x, y) = (y, x)
		self.par[x] += self.par[y]
		self.par[y] = x
		return True

	def size(self, x):
		return -self.par[self.find(x)]

	def count_group():
		c = 0
		for i in range(len(self.par)):
			if self.par[i] < 0:
				c += 1
		return c
(n, q) = map(int, input().split())
uf = Unionfind(n)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.union(x, y)
	else:
		print(int(uf.same(x, y)))


def main():
	(n, q) = [int(i) for i in input().split()]
	par = [i for i in range(n)]
	rank = [0 for i in range(n)]

	def find(x):
		if par[x] == x:
			return x
		else:
			par[x] = find(par[x])
			return par[x]

	def unite(x, y):
		x = find(x)
		y = find(y)
		if x == y:
			return
		if rank[x] < rank[y]:
			par[x] = y
			return
		elif rank[y] < rank[x]:
			par[y] = x
			return
		else:
			par[x] = y
			rank[y] += 1
			return

	def same(x, y):
		return find(x) == find(y)
	for i in range(q):
		(com, x, y) = [int(j) for j in input().split()]
		if com == 0:
			unite(x, y)
		elif same(x, y):
			print(1)
		else:
			print(0)
main()


import sys
readline = sys.stdin.readline

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [-1] * n
		self.rank = [0] * n

	def find(self, x):
		if self.parents[x] < 0:
			return x
		else:
			self.parents[x] = self.find(self.parents[x])
			return self.parents[x]

	def union(self, x, y):
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.parents[x] = y
		else:
			self.parents[y] = x
			if self.rank[x] == self.rank[y]:
				self.rank[x] += 1

def main():
	(n, q) = map(int, readline().split())
	uf = UnionFind(n)
	for _ in range(q):
		(com, x, y) = map(int, readline().split())
		if com == 0:
			uf.union(x, y)
		else:
			px = uf.find(x)
			py = uf.find(y)
			print((px == py) * 1)
main()


rank = {}
p = {}

def makeSet(x):
	p[x] = x
	rank[x] = 0

def link(x, y):
	if rank[x] > rank[y]:
		p[y] = x
	else:
		p[x] = y
	if rank[x] == rank[y]:
		rank[y] += 1

def union(x, y):
	link(findSet(x), findSet(y))

def findSet(x):
	if x != p[x]:
		p[x] = findSet(p[x])
	return p[x]

def isSameSet(x, y):
	return findSet(x) == findSet(y)
(n, q) = map(int, input().split())
for x in range(n):
	makeSet(x)
for i in range(q):
	(a, x, y) = map(int, input().split())
	ret = (union if a == 0 else isSameSet)(x, y)
	if ret is None:
		continue
	if ret == True:
		print(1)
	else:
		print(0)


class Node:

	def __init__(self, num):
		self.num = num
		self.parent = self
		self.rank = 0

def findSet(node):
	tmp = []
	while node.parent != node:
		tmp.append(node)
		node = node.parent
	while tmp:
		tmp.pop().parent = node
	return node

def unite(x, y):
	node1 = findSet(nodes[x])
	node2 = findSet(nodes[y])
	if node1.rank == node2.rank:
		node2.parent = node1
		node1.rank += 1
	elif node1.rank > node2.rank:
		node2.parent = node1
	else:
		node1.parent = node2

def same(x, y):
	node1 = findSet(nodes[x])
	node2 = findSet(nodes[y])
	return node1.parent == node2.parent
nums = list(map(int, input().split()))
n = nums[0]
q = nums[1]
nodes = []
for i in range(n):
	nodes.append(Node(i))
for i in range(q):
	nums = list(map(int, input().split()))
	if nums[0] == 0:
		unite(nums[1], nums[2])
	elif same(nums[1], nums[2]):
		print(1)
	else:
		print(0)


import sys

class UnionFind:

	def __init__(self, max_size):
		self.max_size = max_size
		self.dat = [i for i in range(self.max_size)]

	def find(self, vertex):
		if self.dat[vertex] is vertex:
			return vertex
		self.dat[vertex] = self.find(self.dat[vertex])
		return self.dat[vertex]

	def merge(self, child, parent):
		self.dat[self.find(child)] = self.dat[self.find(parent)]

	def is_same(self, v, w):
		return self.find(v) == self.find(w)
(n, q) = map(int, input().split())
uni = UnionFind(n)
sys.setrecursionlimit(114514)
while q > 0:
	q -= 1
	(com, x, y) = map(int, input().split())
	if com is 0:
		uni.merge(x, y)
	else:
		print(1 if uni.is_same(x, y) else 0)


(n, q) = map(int, input().split(' '))
uf = list(range(n))
import sys
sys.setrecursionlimit(30000)

def find_root(x):
	global uf
	if uf[x] == x:
		return x
	else:
		uf[x] = find_root(uf[x])
		return uf[x]
for _ in range(q):
	(c, x, y) = map(int, input().split(' '))
	if c == 0:
		uf[find_root(x)] = find_root(y)
	else:
		print(int(find_root(x) == find_root(y)))


import sys, queue, math as np
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
LI = lambda : [int(x) for x in input().split()]
(N, Q) = LI()
g = [i for i in range(N)]

def root(x):
	if x == g[x]:
		return x
	g[x] = root(g[x])
	return g[x]
for _ in range(Q):
	(c, x, y) = LI()
	if c == 0:
		g[root(x)] = root(y)
	else:
		print(int(root(x) == root(y)))


(n, q) = map(int, input().strip().split(' '))
P = [i for i in range(n)]

def root(x):
	path_to_root = []
	while P[x] != x:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def is_same_set(x, y):
	return root(x) == root(y)

def unite(x, y):
	P[root(x)] = root(y)
for j in range(q):
	(com, x, y) = map(int, input().strip().split(' '))
	if com == 0:
		unite(x, y)
	elif is_same_set(x, y):
		print(1)
	else:
		print(0)


from sys import stdin
high = [0] * 10000
par = [i for i in range(10000)]

def findSet(x):
	if par[x] == x:
		return x
	par[x] = findSet(par[x])
	return par[x]

def unite(x, y):
	x = findSet(x)
	y = findSet(y)
	if x == y:
		return
	if high[x] > high[y]:
		par[y] = x
	else:
		par[x] = y
		if high[x] == high[y]:
			high[y] += 1

def same(x, y):
	return findSet(x) == findSet(y)
(n, q) = map(int, stdin.readline().split())
for i in range(q):
	(t, a, b) = map(int, stdin.readline().split())
	if t == 0:
		unite(a, b)
	elif t == 1:
		print(1 if same(a, b) else 0)


rank = []
p = []

def makeSet(x):
	p.append(x)
	rank.append(0)

def union(x, y):
	link(findSet(x), findSet(y))

def link(x, y):
	if rank[x] > rank[y]:
		p[y] = x
	else:
		p[x] = y
		if rank[x] == rank[y]:
			rank[y] = rank[y] + 1

def findSet(x):
	if x != p[x]:
		p[x] = findSet(p[x])
	return p[x]

def same(x, y):
	return findSet(x) == findSet(y)
(n, q) = map(int, input().split())
for i in range(n):
	makeSet(i)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		union(x, y)
	elif com == 1:
		print(int(same(x, y)))


(n, q) = map(int, input().split())
P = [i for i in range(n)]

def root(x):
	path_to_root = []
	while P[x] != x:
		path_to_root.append(x)
		x = P[x]
	for node in path_to_root:
		P[node] = x
	return x

def is_same_set(x, y):
	if root(x) == root(y):
		return 1
	else:
		return 0

def unite(x, y):
	P[root(x)] = root(y)
for i in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	if com == 1:
		print(is_same_set(x, y))


import sys
input = sys.stdin.readline

class UnionFind:
	N = 0
	cost = 0
	par = []

	def init(N):
		UnionFind.N = N
		UnionFind.par = [i for i in range(N)]

	def find(v):
		c = 0
		u = v
		while v != UnionFind.par[v]:
			v = UnionFind.par[v]
			c += 1
		if c > 10:
			while u != v:
				(u, UnionFind.par[u]) = (UnionFind.par[u], v)
		return v

	def union(v, u, c=0):
		vr = UnionFind.find(v)
		ur = UnionFind.find(u)
		if vr == ur:
			return True
		UnionFind.par[ur] = vr
		UnionFind.cost += c
		return False

	def get_cost():
		return UnionFind.cost

	def same(v, u):
		return UnionFind.find(v) == UnionFind.find(u)

def main():
	(n, q) = list(map(int, input().split()))
	UnionFind.init(n)
	for i in range(q):
		(com, x, y) = list(map(int, input().split()))
		if com == 0:
			UnionFind.union(x, y)
		elif UnionFind.same(x, y):
			print(1)
		else:
			print(0)
main()


import sys
input = sys.stdin.readline

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [i for i in range(n)]
		self.rank = [0 for _ in range(n)]

	def find(self, x):
		root = x
		while self.parents[root] != root:
			root = self.parents[root]
		while self.parents[x] != root:
			parent = self.parents[x]
			self.parents[x] = root
			x = parent
		return root

	def unite(self, x, y):
		(xroot, yroot) = (self.find(x), self.find(y))
		if xroot == yroot:
			return
		(xrank, yrank) = (self.rank[xroot], self.rank[yroot])
		if xrank < yrank:
			self.parents[xroot] = yroot
		elif xrank == yrank:
			self.parents[yroot] = xroot
			self.rank[yroot] += 1
		else:
			self.parents[yroot] = xroot
(N, Q) = map(int, input().split())
uf = UnionFind(N)
for _ in range(Q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		uf.unite(x, y)
	else:
		print(1 if uf.find(x) == uf.find(y) else 0)


(n, q) = map(int, input().split())
par = [-1] * n
rank = [0] * n

def find(x):
	if par[x] < 0:
		return x
	else:
		par[x] = find(par[x])
		return par[x]

def unite(x, y):
	rootx = find(x)
	rooty = find(y)
	if rootx == rooty:
		return False
	else:
		if rank[rootx] < rank[rooty]:
			par[rootx] = rooty
		else:
			par[rooty] = rootx
			if rank[rootx] == rank[rooty]:
				rank[rootx] += 1
		return True

def same(x, y):
	return find(x) == find(y)
for _ in range(q):
	(com, x, y) = map(int, input().split())
	if com == 0:
		unite(x, y)
	elif com == 1:
		if same(x, y):
			print(1)
		else:
			print(0)