Problem:
Disjoint Set

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.

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.

Constraints

1 ≤ n ≤ 10000

1 ≤ q ≤ 100000

x ≠ y

Sample 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

Sample Output

0
0
1
1
1
0
1
1

Solution in C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Practice
{
    class Program
    {
        static void Main(string[] args)
        {
            //SolveA(args);
            SolveB(args);
            //SolveC(args);
            //SolveD(args);


        }
        static void SolveB(string[] args)
        {
            int[] nq = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
            int n = nq[0];
            var forest = new Forest(n);
            int q = nq[1];
            for(int i=0;i<q;++i)
            {
                int[] line = Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
                int cmd = line[0];
                int x = line[1];
                int y = line[2];
                if(cmd == 0)
                {
                    forest.Unite(x, y);
                }
                else
                {
                    int rx = forest.FindSet(x);
                    int ry = forest.FindSet(y);
                    if( rx == ry)
                    {
                        Console.WriteLine(1);
                    }
                    else
                    {
                        Console.WriteLine(0);
                    }
                }
            }
        }
        
        public class Node
        {
            public Node parent;
            public int val;
            
        }
        public class Forest
        {
            public List<Node> _trees;
            public int[] parent;
            public int[] rank;

            public Forest(int n)
            {
                // makesetのつもり
                _trees = new List<Node>(n);
                for(int i=0;i<n;++i)
                {
                    var node = new Node();
                    node.parent = node;
                    node.val = i;
                    _trees.Add(node);
                }
                parent = new int[n];
                rank = new int[n];

            }
            
            public int FindSet(int x)
            {
                foreach(Node n in _trees)
                {
                    if(n.val != x) { continue; }

                    // 代表の要素を求めるぞ
                    Node node = n;
                    while(node.parent != node)
                    {
                        node = node.parent;
                    }
                    return node.val;
                }
                // error
                Console.WriteLine("Error Not Found=" + x);
                return -1;
            }
            private Node FindNode(int x)
            {
                foreach (Node n in _trees)
                {
                    if (n.val != x) { continue; }

                    // 代表の要素を求めるぞ
                    Node node = n;
                    while (node.parent != node)
                    {
                        node = node.parent;
                    }
                    return node;
                }
                return null;
            }
            public void Unite(int x, int y)
            {
                Node rootX = FindNode(x);
                Node rootY = FindNode(y);
                int rx = rank[rootX.val];
                int ry = rank[rootY.val];
                if( rx > ry)
                {
                    // yをxに
                    rootY.parent = rootX;
                }else if( rx < ry)
                {
                    rootX.parent = rootY;
                }
                else
                {
                    rootX.parent = rootY;
                    rank[rootX.val] += 1;
                }
            }
        }

    }
}