#include <bits/stdc++.h>
using namespace std;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
long long int myRand(long long int B) { return (long long unsigned)rng() % B; }
const int N = 1500;
int _a[N][N];
void init(int n, int m) {
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) scanf("%d", &_a[i][j]);
}
int _cnt = 0;
int force_ask(int x, int y) {
  printf("? %d %d\n", x, y);
  fflush(stdout);
  int ans;
  scanf("%d", &ans);
  return ans;
}
map<pair<int, int>, int> mem;
int ask(int x, int y) {
  if (mem.count(make_pair(x, y)) == 0) mem[make_pair(x, y)] = force_ask(x, y);
  return mem[make_pair(x, y)];
}
vector<int> reduce(vector<int> rows, vector<int> cols) {
  vector<int> ans;
  42;
  int i = 0;
  for (int c : cols) {
    42;
    if (ans.empty()) {
      ans.push_back(c);
      continue;
    }
    while (!ans.empty() && ask(rows[i], ans.back()) > ask(rows[i], c)) {
      ans.pop_back();
      i--;
    }
    if (ans.size() == rows.size())
      continue;
    else {
      ans.push_back(c);
      i++;
    }
  }
  42;
  return ans;
}
vector<int> solve(vector<int> rows, vector<int> cols) {
  if ((int)cols.size() > (int)rows.size()) cols = reduce(rows, cols);
  int n = (int)rows.size();
  int m = (int)cols.size();
  vector<int> nrows;
  for (int i = 1; i < n; i += 2) nrows.push_back(rows[i]);
  vector<int> nans;
  if (!nrows.empty()) nans = solve(nrows, cols);
  vector<int> ans;
  int ptr = 0;
  for (int i = 0; i < n; i++) {
    if (i % 2 == 1) {
      ans.push_back(nans[i / 2]);
      continue;
    }
    int nptr = m - 1;
    if (i + 1 < n) {
      nptr = ptr;
      while (cols[nptr] < nans[i / 2]) nptr++;
    }
    int bst = ptr;
    for (int j = ptr; j <= nptr; j++)
      if (ask(rows[i], cols[j]) < ask(rows[i], cols[bst])) bst = j;
    ans.push_back(cols[bst]);
    ptr = nptr;
  }
  return ans;
}
int main(int, char **) {
  int n, m;
  scanf("%d%d", &n, &m);
  vector<int> rows, cols;
  for (int i = 1; i <= n; i++) rows.push_back(i);
  for (int i = 1; i <= m; i++) cols.push_back(i);
  vector<int> mins = solve(rows, cols);
  int bst = 0;
  for (int i = 0; i < n; i++)
    if (ask(rows[i], mins[i]) < ask(rows[bst], mins[bst])) bst = i;
  42;
  printf("! %d\n", ask(rows[bst], mins[bst]));
  fflush(stdout);
  return 0;
}
