package main

import (
	. "fmt"
	"bufio"
	"os"
	"strconv"
)

const INF int = 1e9
const LINF int64 = 1e9
const MOD int = INF + 7

func main() {
	next := NewScanner()
	n, q := next.Int(), next.Int()
	uf := NewUnionFind(n)

	for i := 0; i < q; i++ {
		f, x, y := next.Int(), next.Int(), next.Int()

		if f == 0 {
			uf.unite(x, y)
		} else {
			Println(Btoi(uf.same(x, y)))
		}
	}
}

// UnionFind
type UnionFind struct {
	data []int
}

func NewUnionFind(n int) *UnionFind {
	data := make([]int, n)
	for i := 0; i < n; i++ {
		data[i] = -1
	}

	return &UnionFind{data}
}

func (data *UnionFind) unite(x, y int) bool {
	x, y = data.find(x), data.find(y)

	if x == y {
		return false
	}

	if data.data[x] > data.data[y] {
		x, y = y, x
	}

	data.data[x] += data.data[y]
	data.data[y] = x
	return true
}

func (data *UnionFind) find(k int) int {
	if data.data[k] < 0 {
		return k
	} else {
		data.data[k] = data.find(data.data[k])
		return data.data[k]
	}
}

func (data *UnionFind) same(x, y int) bool {
	return data.find(x) == data.find(y)
}

func (data *UnionFind) size(k int) int {
	return -data.data[data.find(k)]
}

// Scanner begin

type scanner struct {
	r	*bufio.Reader
	buf []byte
	p	int
}

func NewScanner() *scanner {
	return &scanner{r: bufio.NewReaderSize(os.Stdin, 10000)}
}

func (s *scanner) next() string {
	s.pre()
	start := s.p

	for ; s.p < len(s.buf); s.p++ {
		if s.buf[s.p] == ' ' {
			break
		}
	}

	result := string(s.buf[start:s.p])
	s.p++
	return result
}

func (s *scanner) Line() string {
	s.pre()
	start := s.p
	s.p = len(s.buf)

	return string(s.buf[start:])
}

func (s *scanner) Int() int {
	v, _ := strconv.Atoi(s.next())
	return v
}

func (s *scanner) Int64() int64 {
	v, _ := strconv.ParseInt(s.next(), 10, 64)
	return v
}

func (s *scanner) Float() float32 {
	f, _ := strconv.ParseFloat(s.next(), 32)

	return float32(f)
}

func (s *scanner) Float64() float64 {
	f, _ := strconv.ParseFloat(s.next(), 64)

	return f
}

func (s *scanner) Bool() bool {
	b, _ := strconv.ParseBool(s.next())

	return b
}

func (s *scanner) String() string {
	return s.next()
}


func (s *scanner) pre() {
	if s.p >= len(s.buf) {
		s.readLine()
		s.p = 0
	}
}

func (s *scanner) readLine() {
	s.buf = make([]byte, 0)
	for {
		l, p, e := s.r.ReadLine()
		if e != nil {
			panic(e)
		}
		s.buf = append(s.buf, l...)
		if !p {
			break
		}
	}
}

// Scanner end

// Standard Function begin

func Itob(i int) bool {
	if i == 0 {
		return false
	} else {
		return true
	}
}

func Btoi(f bool) int {
	if f {
		return 1
	} else {
		return 0
	}
}

func min(a ...int) int {
	ret := a[0]
	for _, e := range a {
		if e < ret {
			ret = e
		}
	}

	return ret
}

func max(a ...int) int {
	ret := a[0]
	for _, e := range a {
		if e > ret {
			ret = e
		}
	}

	return ret
}

func minInt64(a ...int64) int64 {
	ret := a[0]
	for _, e := range a {
		if e < ret {
			ret = e
		}
	}

	return ret
}

func maxInt64(a ...int64) int64 {
	ret := a[0]
	for _, e := range a {
		if e > ret {
			ret = e
		}
	}

	return ret
}

func minFloat(a ...float32) float32 {
	ret := a[0]
	for _, e := range a {
		if e < ret {
			ret = e
		}
	}

	return ret
}

func maxFloat(a ...float32) float32 {
	ret := a[0]
	for _, e := range a {
		if e > ret {
			ret = e
		}
	}

	return ret
}

func minFloat64(a ...float64) float64 {
	ret := a[0]
	for _, e := range a {
		if e < ret {
			ret = e
		}
	}

	return ret
}

func maxFloat64(a ...float64) float64 {
	ret := a[0]
	for _, e := range a {
		if e > ret {
			ret = e
		}
	}

	return ret
}

func abs(a int) int {
	if a < 0 {
		return -a
	} else {
		return a
	}
}

func absInt64(a int64) int64 {
	if a < 0 {
		return -a
	} else {
		return a
	}
}

func absFloat(a float32) float32 {
	if a < 0 {
		return -a
	} else {
		return a
	}
}

func absFloat64(a float64) float64 {
	if a < 0 {
		return -a
	} else {
		return a
	}
}

// Standard Struct begin

type pair struct {
	first, second int
}

type pairs []pair

func Newpair() *pair {
	return &pair {
		first : 0,
		second : 0,
	}
}

func (p pairs) Less(i, j int) bool {
	if p[i].first < p[j].first {
		return true
	} else if p[i].first == p[j].first {
		return p[i].second < p[j].second
	} else {
		return false
	}
}



Measured memory_bytes: 4388