#include <bits/stdc++.h>
using namespace std;
const int N = 100100;
int m_f(int a, int b) {
  if (a != 0 && b != 0) return 0;
  if (a != 1 && b != 1) return 1;
  return 2;
}
int my_mex(long long s, long long e) {
  int prv = -1, mxl = -1;
  for (int it = 1;; ++it) {
    long long lw = (e >> it) + 1;
    long long rw = (e >> (it - 1));
    int mxr = m_f(prv, mxl);
    if (s == rw) return mxr;
    int mxr1 = m_f(prv, mxr);
    if (s >= lw && s <= rw) {
      return ((rw - s) & 1) ? mxr1 : mxr;
    }
    if (rw & 1)
      prv = mxr1;
    else
      prv = mxr;
    mxl = ((rw - lw) & 1) ? mxr1 : mxr;
  }
  return -1;
}
int my_mex2(long long s, long long e) {
  if (2 * s > e) return 1;
  return my_mex(s, e / 2);
}
long long vs[N], ve[N];
int v_mex[N], t, dp1[2][N], dp2[2][N];
bool can_w[N], can_l[N];
int main() {
  scanf("%d", &t);
  for (int i = 0; i < t; ++i) {
    scanf("%lld %lld", vs + i, ve + i);
    if (my_mex(vs[i], ve[i]) != 0) can_w[i] = 1;
    if (my_mex2(vs[i], ve[i]) != 0) can_l[i] = 1;
  }
  dp1[1][t] = 1;
  for (int i = t - 1; i >= 0; --i) {
    for (int f = 0; f < 2; ++f) {
      if (f == 0) {
        if (can_w[i]) dp1[0][i] |= dp1[1][i + 1];
        if (can_l[i]) dp1[0][i] |= dp1[0][i + 1];
      } else {
        dp1[1][i] = 1;
        if (can_w[i]) dp1[1][i] &= dp1[0][i + 1];
        if (can_l[i]) dp1[1][i] &= dp1[1][i + 1];
      }
    }
  }
  dp2[0][t] = 1;
  for (int i = t - 1; i >= 0; --i) {
    for (int f = 0; f < 2; ++f) {
      if (f == 0) {
        dp2[0][i] = 0;
        if (can_w[i]) dp2[0][i] |= dp2[1][i + 1];
        if (can_l[i]) dp2[0][i] |= dp2[0][i + 1];
      } else {
        dp2[1][i] = 1;
        if (can_w[i]) dp2[1][i] &= dp2[0][i + 1];
        if (can_l[i]) dp2[1][i] &= dp2[1][i + 1];
      }
    }
  }
  printf("%d %d\n", dp1[0][0], dp2[0][0]);
  return 0;
};
