import Data.Array.IO
import Control.Applicative
import Control.Monad
import Control.Monad.State

type DisJointSet a = IOArray a (Head a)
type Head a = (a,Int)

main = do
  [n,q] <- map read.words<$>getLine
  qs <- replicateM q (map read.words<$>getLine)
  let querys = map toQuery qs
  t <- initSet 0 n
  runStateT (sequence_ querys) t

printResult x = if x then print 1 else print 0

initSet :: (Enum a, Ix a) => a -> a -> IO (DisJointSet a)
initSet n m = newListArray (n,m) $ zip [n..m] [0..]

--------------------------------------------------------------------------------
toQuery :: [Int] -> StateT (DisJointSet Int) IO ()
toQuery [q,n,m] = if q == 0 then union n m
                             else (same n m >>= (\b -> liftIO $ printResult b))

makeSet :: Ix a => a -> StateT (DisJointSet a) IO ()
makeSet i = do
  arr <- get
  liftIO $ writeArray arr i (i,0)

findSet :: Ix a => a -> StateT (DisJointSet a) IO (Head a)
findSet x = do
  arr <- get
  h <- liftIO $ readArray arr x
  if fst h == x then return h
                else findSet (fst h)

union :: Ix a => a -> a -> StateT (DisJointSet a) IO ()
union x y = do
  arr <- get
  (hx,rx) <- findSet x
  (hy,ry) <- findSet y
  if rx >= ry then liftIO $ writeArray arr y (hx,rx)
              else if rx <= ry then liftIO $ writeArray arr x (hy,ry)
                               else liftIO $ writeArray arr x (hy,rx+1)

same :: Ix a => a -> a -> StateT (DisJointSet a) IO Bool
same x y = do
  (headx,rx) <- findSet x
  (heady,ry) <- findSet y
  return $ headx == heady