CodeEff/ECCO huggingface dataset:
# Original solution
# coding=utf-8


def unite(sets, x, y):
    sx = [s for s in sets if x in s][0]
    sy = [s for s in sets if y in s][0]
    if sx == sy:
        return sets
    else:
        newSets = []
        newSets.append(set.union(sx, sy))
        newSets += [s for s in sets if x not in s and y not in s]
        return newSets


def same(sets, x, y):
    for s in sets:
        if x in s and y in s:
            return 1
    else:
        return 0


def main():
    elemNum, queryNum = list(map(int, input().rstrip().split()))
    sets = [set([i]) for i in range(elemNum)]
    for _ in range(queryNum):
        qType, x, y = list(map(int, input().rstrip().split()))
        if qType == 0:
            sets = unite(sets, x, y)
        else:
            print(same(sets, x, y))


if __name__ == '__main__':
    main()

# Optimized solution
# coding=utf-8


def unite(sets, x, y):
    sx = [s for s in sets if x in s][0]
    # print sx
    if y in sx:
        return sets
    else:
        newSets = [s for s in sets if x not in s and y not in s]
        sy = [s for s in sets if y in s][0]
        # print sy
        newSets.append(set.union(sx, sy))
        return newSets


def same(sets, x, y):
    sx = [s for s in sets if x in s][0]
    if y in sx:
        return 1
    else:
        return 0


def main():
    elemNum, queryNum = list(map(int, input().rstrip().split()))
    sets = [set([i]) for i in range(elemNum)]
    for _ in range(queryNum):
        qType, x, y = list(map(int, input().rstrip().split()))
        if qType:
            print(same(sets, x, y))
        else:
            sets = unite(sets, x, y)
            # print sets


if __name__ == '__main__':
    main()
# Original solution
#!/usr/bin/python3

class UnionFindTree:
    def __init__(self, x):
        self.parent = self
        self.id = x

    def find(self):
        if self.id == self.parent.id:
            return self
        else:
            return self.parent.find()


# main
n, q = list(map(int, input().split()))
nodes = [UnionFindTree(i) for i in range(n)]
for i in range(q):
    com, x, y = list(map(int, input().split()))
    x_root = nodes[x].find()
    y_root = nodes[y].find()
    if com == 0:
        # union
        y_root.parent = x_root
    else:
        # same
        same = 1 if x_root.id == y_root.id else 0
        print(same)
            

# Optimized solution
#!/usr/bin/python3

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()


# main
n, q = list(map(int, input().split()))
nodes = [UnionFindTree(i) for i in range(n)]
for i in range(q):
    com, x, y = list(map(int, input().split()))
    x_root = nodes[x].find()
    y_root = nodes[y].find()
    if com == 0:
        # union
        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
        same = 1 if x_root.id == y_root.id else 0
        print(same)
# Original solution
# -*- coding: utf-8 -*-
class DisjointSets:
    '''
    Implementing disjoint sets using disjoint sets forests structure.

    --- methods ---
    __init__(size): size should be the number of elements in this disjoint sets
    unite(x, y): unite sets that contain x and y into a new set
    same(x, y): check if x and y are in the same set
    '''

    def __init__(self, size):
        self.size = size
        self.ranks = [0] * self.size
        self.roots = [0] * self.size
        for x in range(self.size):
            self._make_set(x)

    def _make_set(self, x):
        self.roots[x] = x
        self.ranks[x] = 0

    def _link(self, x, y):
        if self.ranks[x] > self.ranks[y]:
            self.roots[y] = x
        else:
            self.roots[x] = y
            if self.ranks[x] == self.ranks[y]:
                self.ranks[y] += 1

    def _find_set(self, x):
        # compression of the path
        if x != self.roots[x]:
            self.roots[x] = self._find_set(self.roots[x])

        return self.roots[x]

    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)


if __name__ == '__main__':
    import sys
    n, q = list(map(int, input().split()))
    ds = DisjointSets(n)

    for line in sys.stdin.readlines():
        query, x, y = list(map(int, line.strip().split()))
        if query == 0:
            ds.unite(x, y)
        elif query == 1:
            if ds.same(x, y):
                print((1))
            else:
                print((0))



# Optimized solution
# -*- coding: utf-8 -*-
class DisjointSets:
    '''
    Implementing disjoint sets using disjoint sets forests structure.

    --- methods ---
    __init__(size): size should be the number of elements in this disjoint sets
    unite(x, y): unite sets that contain x and y into a new set
    same(x, y): check if x and y are in the same set
    '''

    def __init__(self, size):
        self.size = size
        self.roots = [x for x in range(self.size)]
        self.ranks = [0] * self.size

    def _link(self, x, y):
        if self.ranks[x] > self.ranks[y]:
            self.roots[y] = x
        else:
            self.roots[x] = y
            if self.ranks[x] == self.ranks[y]:
                self.ranks[y] += 1

    def _find_set(self, x):
        # compression of the path
        if x != self.roots[x]:
            self.roots[x] = self._find_set(self.roots[x])

        return self.roots[x]

    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)


if __name__ == '__main__':
    '''
    an example of using this function
    AIZU ONLINE JUDGE - DSL_1_A
    '''

    import sys
    n, q = list(map(int, input().split()))
    ds = DisjointSets(n)

    for line in sys.stdin.readlines():
        query, x, y = list(map(int, line.strip().split()))
        if query == 0:
            ds.unite(x, y)
        elif query == 1:
            if ds.same(x, y):
                print((1))
            else:
                print((0))
# Original solution
#!/usr/bin/env python

from sys import stdin


def main():
    n, q = (int(s) for s in stdin.readline().split())
    s = [{i} for i in range(n)]

    for _ in range(q):
        com, x, y = (int(s) for s in stdin.readline().split())
        if com:
            for si in s:
                if x in si and y in si:
                    print(1)
                    break
            else:
                print(0)
        else:
            for si in s:
                if x in si:
                    a = si
                if y in si:
                    b = si
            if a != b:
                s.append(a | b)
                s.remove(a)
                s.remove(b)


main()

# Optimized solution
#!/usr/bin/env python

from sys import stdin


def main():
    n, q = (int(s) for s in stdin.readline().split())
    s = [{i} for i in range(n)]

    for _ in range(q):
        com, x, y = (int(s) for s in stdin.readline().split())
        if com:
            if x in s[x] and y in s[x]:
                print(1)
            else:
                print(0)
        else:
            a = s[x]
            b = s[y]
            if a is not b:
                a |= b
                for i in a:
                    s[i] = a


main()
# Original solution
def main():
    n,q = list(map(int,input().split()))

    ds = DisjointSet(n)

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

class DisjointSet():
    def __init__(self,n):
        self.n = n
        self.root = list(range(n))
        self.parent = [-1]*n
        self.rank = [0]*n

    def findSet(self,x):
        if self.parent[x] == -1:
            return x
        else:
            p = self.findSet(self.parent[x])
            self.parent[x] = p

    def unite(self,x,y):
        if self.rank[x] > self.rank[y]:
            for z in [u for u in range(self.n) if self.root[u] == self.root[y]]:
                self.parent[z] = self.root[x]
                self.root[z] = self.root[x]
                self.rank[z] = self.rank[x]
        elif self.rank[x] < self.rank[y]:
            for z in [u for u in range(self.n) if self.root[u] == self.root[x]]:
                self.parent[z] = self.root[y]
                self.root[z] = self.root[y]
                self.rank[z] = self.rank[y]
        else:
            for z in [u for u in range(self.n) if self.root[u] == self.root[x]]:
                self.parent[z] = self.root[y]
                self.root[z] = self.root[y]
                self.rank[z] = self.rank[y]+1

if __name__ == "__main__":
    main()

# Optimized solution
def main():
    n,q = list(map(int,input().split()))

    ds = DisjointSet(n)

    for i in range(q):
        com,x,y = list(map(int,input().split()))
        if com:
            ds.findSet(x)
            ds.findSet(y)
            if ds.parent[x] == ds.parent[y]:
                print(1)
            else:
                print(0)
        else:
            ds.findSet(x)
            ds.findSet(y)
            ds.unite(x,y)

class DisjointSet():
    def __init__(self,n):
        self.n = n
        self.parent = list(range(n))

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

    def unite(self,x,y):
        if self.parent[y] > self.parent[x]:
            self.parent[self.parent[y]] = self.parent[x]
        else:
            self.parent[self.parent[x]] = self.parent[y]

if __name__ == "__main__":
    main()
# Original solution
n, q = list(map(int, input().split()))

set_list = [{i} for i in range(n)]
set_dict = list(range(n))

while q:
    op, x, y = list(map(int, input().split()))
    if op:
        print((1 if set_dict[x] == set_dict[y] else 0))
    else:
        idx_x, idx_y = set_dict[x], set_dict[y]
        set_y = set_list[idx_y]

        for i in set_y:
            set_dict[i] = idx_x
        set_list[idx_x] |= set_y

    q -= 1

# Optimized solution
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 = list(map(int, input().split()))
set_list = list(range(n))

while q:
    op, x, y = list(map(int, input().split()))
    if op:
        print((1 if find(x) == find(y) else 0))
    else:
        set_list[find(y)] = find(x)
    q -= 1
# Original solution
def unite(x, y, s_list):
    x_list = None
    y_list = None
    for s in s_list:
        if x in s and y in s:
            x_list = s.copy()
            y_list = s.copy()
            del s
        elif x in s:
            x_list = s.copy()
            del s
        elif y in s:
            y_list = s.copy()
            del s
    if x_list != None and y_list != None:
        s_list.append(list(set(x_list + y_list)))
    elif x_list != None and y_list == None:
        x_list.append(y)
        s_list.append(x_list)
    elif x_list == None and y_list != None:
        y_list.append(x)
        s_list.append(y_list)
    else:
        s_list.append([x, y])

def same(x, y, s_list):
    x_list = None
    y_list = None
    for s in s_list:
        if x in s and y in s:
            return 1
    return 0


n, q = list(map(int, input().split()))
com_list = list()
x_list = list()
y_list = list()
s_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)

for i in range(q):
    com = com_list[i]
    x = x_list[i]
    y = y_list[i]
    if com == 0:
        unite(x, y, s_list)
    else:
        result = same(x, y, s_list)
        print(result)

    

# Optimized solution
def make_set(x, disjoint):
    disjoint[x] = x

def find_set(x, disjoint):
    if x not in list(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)))
# Original solution
# -*- coding: utf-8 -*-
import sys
sys.setrecursionlimit(10000)

N, Q = tuple(map(int, input().split()))

tree = [[-1, 1]  for _ in range(N)] # [next, rank]

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]: # rank is same
        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: # same
        print((int(find(x) == find(y))))
    else: # unite
        if not int(find(x) == find(y)):
            unite(x, y)

# Optimized solution
# -*- coding: utf-8 -*-
import sys
sys.setrecursionlimit(10000)
 
N, Q = tuple(map(int, input().split()))
 
tree = [[-1, 1]  for _ in range(N)] # [next, rank]
 
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]: # rank is same
        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: # same
        print((int(find(x) == find(y))))
    else: # unite
        if not int(find(x) == find(y)):
            unite(x, y)
# Original solution
class UnionFind:
    def __init__(self,n):
        self.parent = {}
        for i in range(n):
            self.parent[i] = i

    def get_root(self,x):
        r = x
        depth = 0
        while self.parent[r]!=r:
            r = self.parent[r]
            depth += 1
        return r,depth

    def unite(self,x,y):
        rx,dx = self.get_root(x)
        ry,dy = self.get_root(y)
        if rx!=ry:
            if dx > dy:
                self.parent[ry] = rx
            else:
                self.parent[rx] = ry

    def same(self,x,y):
        rx,_ = self.get_root(x)
        ry,_ = self.get_root(y)
        if rx==ry: return 1
        else: return 0


n,q = list(map(int,input().split(' ')))
tree = UnionFind(n)

answers = []
for _ in range(q):
    com,x,y = list(map(int,input().split(' ')))
    if com==0:
        tree.unite(x,y)
    elif com==1:
        answers.append(tree.same(x,y))

for a in answers:
    print(a)

# Optimized solution
class UnionFind:
    def __init__(self,n):
        self.parent = {}
        for i in range(n):
            self.parent[i] = i

    def get_root(self,x):
        r = x
        depth = 0
        path = [r]
        while self.parent[r]!=r:
            r = self.parent[r]
            path.append(r)
            depth += 1
        for n in path:
            self.parent[n] = r
        return r,depth

    def unite(self,x,y):
        rx,dx = self.get_root(x)
        ry,dy = self.get_root(y)
        if rx!=ry:
            if dx > dy:
                self.parent[ry] = rx
            else:
                self.parent[rx] = ry

    def same(self,x,y):
        rx,_ = self.get_root(x)
        ry,_ = self.get_root(y)
        if rx==ry: return 1
        else: return 0


n,q = list(map(int,input().split(' ')))
tree = UnionFind(n)

answers = []
for _ in range(q):
    com,x,y = list(map(int,input().split(' ')))
    if com==0:
        tree.unite(x,y)
    elif com==1:
        answers.append(tree.same(x,y))

for a in answers:
    print(a)
# Original solution
import sys

def solve():
    n, q = map(int, sys.stdin.readline().split())
    uf = UnionFind(n)
    
    for lp in range(q):
        c, x, y = map(int, sys.stdin.readline().split())

        if c == 0:
            uf.unite(x, y)
        else:
            print(1 if uf.same(x, y) else 0)


class UnionFind:

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

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

        res = self.root[x]
        updates = [x]

        while res != self.root[res]:
            updates.append(res)
            res = self.root[res]

        for u in updates:
            self.root[u] = res

        return res

    def 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)

        if p == q:
            return None

        if self.rank[p] < self.rank[q]:
            self.root[p] = q
        elif self.rank[q] < self.rank[p]:
            self.root[q] = p
        else:
            self.root[q] = p
            self.rank[p] += 1

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

if __name__ == '__main__':
    solve()


# Optimized solution
import sys

def solve():
    n, q = map(int, sys.stdin.readline().split())
    uf = UnionFind(n)

    for lp in range(q):
        c, x, y = map(int, sys.stdin.readline().split())

        if c == 0:
            uf.unite(x, y)
        else:
            print(1 if uf.same(x, y) else 0)


class UnionFind:

    def __init__(self, n):
        self.ds = [i for i in range(n)]
        self.root = [i for i in range(n)]
        self.rank = [0] * 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 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)

        if p == q:
            return None

        if self.rank[p] < self.rank[q]:
            self.root[p] = q
        elif self.rank[q] < self.rank[p]:
            self.root[q] = p
        else:
            self.root[q] = p
            self.rank[p] += 1

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

if __name__ == '__main__':
    solve()
# Original solution
import sys

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)]
        self.rank = [0] * 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)

        if p == q:
            return None

        if self.rank[p] < self.rank[q]:
            self.root[p] = q
        elif self.rank[q] < self.rank[p]:
            self.root[q] = p
        else:
            self.root[q] = p
            self.rank[p] += 1

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

if __name__ == '__main__':
    solve()


# Optimized solution
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

if __name__ == '__main__':
    solve()
# Original solution
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)]
        # self.rank = [0] * 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

if __name__ == '__main__':
    solve()


# Optimized solution
import sys

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.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)]
        self.rank = [0] * n

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

        res = self.root[x]

        while res != self.root[res]:
            res = self.root[res]

        return res

    def 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)

        if p == q:
            return None

        if self.rank[p] < self.rank[q]:
            self.root[p] = q
        elif self.rank[q] < self.rank[p]:
            self.root[q] = p
        else:
            self.root[q] = p
            self.rank[p] += 1

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

if __name__ == '__main__':
    solve()