{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}

import           Control.Applicative
import           Control.Monad
import qualified Data.ByteString.Char8 as B

import           Data.Array.IArray
import           Data.Array.IO
import           Data.Array.MArray
import           Data.IORef

readi :: B.ByteString -> Int
readi b | Just (n, _) <- B.readInt b = n

-- Union/Find
-- Mutable Algorithms in Immutable Languages, Part 1
-- http://jspha.com/thoughts/2016/8/23/from-the-archive-mutable-algorithms-in-immutable-languages-part-1

newtype Node a = Node (IORef (Node_ a))

data Node_ a = Node_
    { parent :: Maybe (IORef (Node_ a))
    , rank   :: Int
    , value  :: a
    }

makeSet :: a -> IO (Node a)
makeSet a = do
    n <- newIORef (Node_ { parent = Nothing, rank = 0, value = a })
    return (Node n)

findSet :: Node a -> IO (Node a)
findSet (Node a) = do
    Node p <- findRec (Node a)
    when (a /= p) $ do
        modifyIORef' a (\n -> n { parent = Just p })
    return (Node p)
  where
    findRec :: Node a -> IO (Node a)
    findRec (Node a) = do
        n <- readIORef a
        case parent n of
            Nothing -> return (Node a)
            Just p  -> findSet (Node p)

unite :: Node a -> Node a -> IO ()
unite n1 n2 = do
    Node p1 <- findSet n1
    Node p2 <- findSet n2
    when (p1 /= p2) (adopt p1 p2)
  where
    adopt x y = do
        nx <- readIORef x
        ny <- readIORef y
        case compare (rank nx) (rank ny) of
            EQ -> do
                writeIORef x (nx { rank = rank nx + 1 })
                writeIORef y (ny { parent = Just x })
            LT -> writeIORef x (nx { parent = Just y })
            GT -> writeIORef y (ny { parent = Just x })

same :: Node a -> Node a -> IO Bool
same n1 n2 = do
    Node p1 <- findSet n1
    Node p2 <- findSet n2
    return (p1 == p2)

--

type Forest = IOArray Int (Node Int)

unite' :: Int -> Int -> Forest -> IO ()
unite' x y dsf = do
    nx <- readArray dsf x
    ny <- readArray dsf y
    unite nx ny

same' :: Int -> Int -> Forest -> IO Bool
same' x y dsf = do
    nx <- readArray dsf x
    ny <- readArray dsf y
    same nx ny

main :: IO ()
main = do
    [n, q] <- fmap readi . B.words <$> B.getLine
    xss <- replicateM q $ do
        [a, b, c] <- fmap readi . B.words <$> B.getLine
        return (a, b, c)
    forest <- newListArray (0, n - 1) =<< mapM makeSet [0 .. n - 1]
              :: IO Forest

    forM_ xss $ \(a, b, c) -> do
        case a of
            0 -> unite' b c forest
            1 -> do
                isSame <- same' b c forest
                if isSame
                    then putStrLn "1"
                    else putStrLn "0"

