Problem:
Score : 100 points

Problem Statement

You are given an undirected graph with N vertices and 0 edges. Process Q queries of the following types.

0 u v: Add an edge (u, v).

1 u v: Print 1 if u and v are in the same connected component, 0 otherwise.

Constraints

1 \leq N \leq 200,000

1 \leq Q \leq 200,000

0 \leq u_i, v_i \lt N

Input

Input is given from Standard Input in the following format:

N Q
t_1 u_1 v_1
t_2 u_2 v_2
:
t_Q u_Q v_Q

出力

For each query of the latter type, print the answer.

Sample Input 1

4 7
1 0 1
0 0 1
0 2 3
1 0 1
1 1 2
0 0 2
1 1 3

Sample Output 1

0
1
0
1

Solution in PHP (7.4.4) (judge verdict: Accepted)

<?php
    ini_set("error_reporting", E_ALL & ~E_NOTICE);

    fscanf(STDIN, "%d %d", $N, $Q);

    $uf = new UnionFind($N);

    for ($i = 0; $i < $Q; $i++) {
        fscanf(STDIN, "%d %d %d", $t, $u, $v);
        switch($t) {
            case "1":
                printf("%d\n", ($uf->Find($u) === $uf->Find($v)) * 1);
                break;
            case "0":
                $uf->Union($u, $v);
                break;
        }
    }

    class UnionFind {

        var $cnt;
        var $data;
        // var $debug = true;
        var $debug = false;

        function __construct($cnt = 10) {
            $this->cnt = $cnt;
            $this->data = array();
            $this->MakeSetAll();
        }

        function MakeSetAll() {
            for ($i = 0; $i < $this->cnt; $i++) {
                $this->MakeSet($i);
            }
        }

        function DumpAll() {
            if ($this->debug === false) return;
            for ($i = 1; $i <= $this->cnt; $i++) {
                printf("[%d]%d ", $i, $this->Find($i));
            }
            echo "\n";
        }

        function MakeSet($x) {
            if (!isset($this->data[$x])) {
                $this->data[$x] = array('parent' => null, 'rank' => null);
            }
            $this->data[$x]['parent'] = $x;
            $this->data[$x]['rank'] = 0;
        }
 
        function Union($x, $y) {
            $xRoot = $this->Find($x);
            $yRoot = $this->Find($y);
            // echo "xRoot: ".$xRoot. "\n";
            // echo "yRoot: ".$yRoot. "\n";
            // print_r($xRoot);
            // print_r($yRoot);
            if ($xRoot['rank'] > $yRoot['rank']) {
                $this->data[$yRoot]['parent'] = $xRoot;
                if ($this->debug) echo "$yRoot parent changes $xRoot\n";
                // $yRoot['parent'] = $xRoot;
            } elseif ($xRoot['rank'] < $yRoot['rank']) {
                $this->data[$xRoot]['parent'] = $yRoot;
                if ($this->debug) echo "$xRoot parent changes $yRoot\n";
                // $xRoot['parent'] = $yRoot;
            } elseif ($xRoot != $yRoot) {
                $this->data[$yRoot]['parent'] = $xRoot;
                if ($this->debug) echo "$yRoot parent changes $xRoot\n";
                $this->data[$xRoot]['rank']++;
                // $yRoot['parent'] = $xRoot;
                // $xRoot['rank'] = $xRoot['rank'] + 1;
            }
            if ($this->debug) echo "OK\n";
        }

        function Find($x) {
            if ($this->data[$x]['parent'] == $x) {
                return $x;
            } else {
                $this->data[$x]['parent'] = $this->Find($this->data[$x]['parent']);
                return $this->data[$x]['parent'];
            }
        }
    }