#include <bits/stdc++.h>
using namespace std;
int n;
long long int L, al[1000], ar[1000];
map<long long int, long long int> M[1000], M2[1000];
long long int query(int i, long long int x) {
  if (M[i].count(x)) return M[i][x];
  long long int y;
  cout << "? " << i + 1 << " " << x << endl;
  cin >> y;
  M[i][x] = y, M2[i][y] = x;
  return y;
}
long long int pos(int i, long long int y) {
  auto it = M2[i].lower_bound(y);
  if ((it != M2[i].end()) && (it->first == y)) return it->second;
  long long int s = 0, e = 1e18;
  if (it != M2[i].end()) e = it->second - 1;
  if (it != M2[i].begin()) it--, s = it->second + 1;
  while (s < e) {
    long long int m = (s + e) / 2;
    if (query(i, m) < y)
      s = m + 1;
    else
      e = m;
  }
  return s;
}
int findAns(long long int s, long long int e, long long int l, long long int r,
            vector<int> v) {
  if (v.size() == 1) {
    al[v[0]] = s, ar[v[0]] = e;
    return 0;
  }
  int i;
  vector<int> ll, mm = v, rr;
  long long int m = (l / (L / n) + r / (L / n)) / 2 * (L / n), x;
  while (1) {
    swap(mm[0], mm[rand() % mm.size()]);
    x = pos(mm[0], m);
    vector<int> l2, m2, r2;
    for (i = 0; i < mm.size(); i++) {
      long long int y = query(mm[i], x);
      if (y > m)
        l2.push_back(mm[i]);
      else if (y < m)
        r2.push_back(mm[i]);
      else
        m2.push_back(mm[i]);
    }
    if ((ll.size() + l2.size() <= v.size() / 2) &&
        (ll.size() + l2.size() + m2.size() >= v.size() / 2)) {
      ll.insert(ll.end(), l2.begin(), l2.end());
      rr.insert(rr.end(), r2.begin(), r2.end());
      mm = m2;
      break;
    } else {
      if (ll.size() + l2.size() < v.size() / 2)
        ll.insert(ll.end(), l2.begin(), l2.end()), l2.clear();
      else
        rr.insert(rr.end(), r2.begin(), r2.end()), r2.clear();
      mm.clear();
      mm.insert(mm.end(), l2.begin(), l2.end());
      mm.insert(mm.end(), m2.begin(), m2.end());
      mm.insert(mm.end(), r2.begin(), r2.end());
    }
  }
  while (!mm.empty()) {
    if (ll.size() >= rr.size())
      rr.push_back(mm.back());
    else
      ll.push_back(mm.back());
    mm.pop_back();
  }
  findAns(s, x, l, m, ll), findAns(x, e, m, r, rr);
  return 0;
}
int main() {
  int i;
  cin >> n >> L;
  vector<int> v;
  for (i = 0; i < n; i++) v.push_back(i);
  findAns(0, 1e18, 0, L, v);
  cout << "!" << endl;
  for (i = 0; i < n; i++) cout << al[i] << " " << ar[i] << endl;
  return 0;
}
