#include <bits/stdc++.h>
using namespace std;
const long long B = (long long)1e9;
const int SZ = 5;
struct Num {
  long long a[SZ];
  Num() : a() {}
  Num(long long x) {
    for (int i = 0; i < SZ; i++) {
      a[i] = x % B;
      x /= B;
    }
  }
  Num operator+(const Num &A) const {
    Num R = Num();
    long long d = 0;
    for (int i = 0; i < SZ; i++) {
      d += a[i] + A.a[i];
      R.a[i] = d % B;
      d /= B;
    }
    return R;
  }
  Num operator*(const Num &A) const {
    Num R = Num();
    for (int i = 0; i < SZ; i++)
      for (int j = 0; i + j < SZ; j++) R.a[i + j] += a[i] * A.a[j];
    for (int i = 0; i < SZ - 1; i++) {
      R.a[i + 1] += R.a[i] / B;
      R.a[i] %= B;
    }
    return R;
  }
  Num operator/(const long long &x) const {
    Num R = Num();
    long long d = 0;
    for (int i = SZ - 1; i >= 0; i--) {
      d = d * B + a[i];
      R.a[i] = d / x;
      d %= x;
    }
    return R;
  }
  bool operator<(const Num &A) const {
    for (int i = SZ - 1; i >= 0; i--) {
      if (a[i] != A.a[i]) return a[i] < A.a[i];
    }
    return false;
  }
};
vector<pair<long long, long long> > a;
long long N;
long long U, R;
Num getSX(long long X) {
  Num S = Num();
  for (int i = 1; i < (int)a.size(); i++) {
    if (a[i].first <= X) continue;
    S = S + Num(a[i].first - max(a[i - 1].first, X)) * Num(U - a[i].second);
  }
  return S;
}
Num getSY(long long Y) {
  Num S = Num();
  for (int i = (int)a.size() - 2; i >= 0; i--) {
    if (a[i].second <= Y) continue;
    S = S + Num(a[i].second - max(a[i + 1].second, Y)) * Num(R - a[i].first);
  }
  return S;
}
long long getX() {
  Num S = getSX(0) / 3LL;
  long long l = 0, r = R;
  while (r - l > 1) {
    long long x = (l + r) / 2;
    if (S < getSX(x))
      l = x;
    else
      r = x;
  }
  return r;
}
long long getY() {
  Num S = getSY(0) / 3LL;
  long long l = 0, r = U;
  while (r - l > 1) {
    long long y = (l + r) / 2;
    if (S < getSY(y))
      l = y;
    else
      r = y;
  }
  return r;
}
void cutX(long long X) {
  R = X - 1;
  int pos = (int)a.size() - 1;
  while (a[pos - 1].first >= X) pos--;
  a[pos].first = X - 1;
  while ((int)a.size() > pos + 1) a.pop_back();
}
void cutY(long long Y) {
  reverse(a.begin(), a.end());
  U = Y - 1;
  int pos = (int)a.size() - 1;
  while (a[pos - 1].second >= Y) pos--;
  a[pos].second = Y - 1;
  while ((int)a.size() > pos + 1) a.pop_back();
  reverse(a.begin(), a.end());
}
void cut3(long long X, long long Y) {
  vector<pair<long long, long long> > b;
  for (pair<long long, long long> t : a) {
    if (t.second > Y) {
      b.push_back(t);
    }
  }
  b.push_back(make_pair(X, Y));
  for (pair<long long, long long> t : a) {
    if (t.first > X) {
      b.push_back(t);
    }
  }
  a = b;
}
bool query() {
  long long X = getX();
  long long Y = getY();
  printf("%lld %lld\n", N - X, N - Y);
  fflush(stdout);
  int t;
  scanf("%d", &t);
  if (t == 0) return true;
  if (t == 1)
    cutX(X);
  else if (t == 2)
    cutY(Y);
  else
    cut3(X, Y);
  return false;
}
int main() {
  scanf("%lld", &N);
  R = U = N;
  N++;
  a.push_back(make_pair(0LL, U));
  a.push_back(make_pair(R, 0LL));
  while (!query()) {
  }
  return 0;
}
