package main
import (
"bufio"
"io"
"os"
)
const (
wsBit uint8 = 1
lsBit uint8 = 2
wnBit uint8 = 4
lnBit uint8 = 8
)
var data []byte
var idx int
func nextUint64() uint64 {
for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
idx++
}
var x uint64
for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
x = x*10 + uint64(data[idx]-'0')
idx++
}
return x
}
func solve(s, e uint64) uint8 {
if s > (e >> 1) {
mask := lsBit
if ((e - s) & 1) == 1 {
mask |= wsBit
} else {
mask |= wnBit
}
return mask
}
m := e >> 1
small := solve(s, m)
if (e & 1) == 1 {
mask := uint8(wnBit)
if (s & 1) == 0 {
mask = wsBit
}
mask |= (small & wsBit) << 1
mask |= (small & wnBit) << 1
return mask
}
return ((small & lsBit) >> 1) | ((small & lnBit) >> 1) | ((small & wsBit) << 1) | ((small & wnBit) << 1)
}
func trans(x, y, canLose, canWin bool) bool {
return (x && y) || (x && canLose) || (y && canWin)
}
func main() {
data, _ = io.ReadAll(os.Stdin)
t := int(nextUint64())
masks := make([]uint8, t)
for i := 0; i < t; i++ {
s := nextUint64()
e := nextUint64()
masks[i] = solve(s, e)
}
winLee, winIce := false, true
loseLee, loseIce := true, false
for i := t - 1; i >= 0; i-- {
m := masks[i]
cws := (m & wsBit) != 0
cls := (m & lsBit) != 0
cwn := (m & wnBit) != 0
cln := (m & lnBit) != 0
nWinLee := trans(winLee, winIce, cls, cws)
nWinIce := trans(winLee, winIce, cln, cwn)
nLoseLee := trans(loseLee, loseIce, cls, cws)
nLoseIce := trans(loseLee, loseIce, cln, cwn)
winLee, winIce = nWinLee, nWinIce
loseLee, loseIce = nLoseLee, nLoseIce
}
out := bufio.NewWriterSize(os.Stdout, 32)
if winLee {
out.WriteByte('1')
} else {
out.WriteByte('0')
}
out.WriteByte(' ')
if loseLee {
out.WriteByte('1')
} else {
out.WriteByte('0')
}
out.WriteByte('\n')
out.Flush()
}