#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0;
  bool flg = false;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') flg = true;
  for (; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
  return flg ? -x : x;
}
const int INF = 1e9 + 9;
int n, m;
int ans = INF;
int ask(int x, int y) {
  printf("? %d %d\n", x, y);
  fflush(stdout);
  return read();
}
void reduce(int n, vector<int> &S, vector<int> &T) {
  static int A[1000010], B[1000010], Atot, Btot, C[1000010];
  if (T.size() <= S.size()) return;
  Atot = Btot = 0;
  for (int x : T) B[++Btot] = x;
  reverse(B + 1, B + Btot + 1);
  A[++Atot] = B[Btot--];
  C[Atot] = ask(S[Atot - 1], A[Atot]);
  while (Atot + Btot > n) {
    assert(Atot <= n);
    int t = ask(S[Atot - 1], B[Btot]);
    if (Atot < n && C[Atot] <= t) {
      A[++Atot] = B[Btot--];
      C[Atot] = ask(S[Atot - 1], A[Atot]);
      continue;
    }
    if (Atot == n && C[Atot] <= t) {
      --Btot;
      continue;
    }
    A[Atot] = B[Btot--];
    C[Atot] = t;
    if (Atot > 1) B[++Btot] = A[Atot--];
  }
  vector<int>().swap(T);
  T.reserve(n);
  for (int i = 1; i <= Atot; i++) T.push_back(A[i]);
  for (int i = Btot; i; i--) T.push_back(B[i]);
}
void solve(int n, vector<int> &S, vector<int> &T) {
  reduce(n, S, T);
  if (n == 1) {
    ans = min(ans, ask(S[0], T[0]));
    return;
  }
  vector<int> SS, TT = T, R = T;
  SS.reserve(n + 1 >> 1);
  for (int i = 1; i <= n; i += 2) SS.push_back(S[i - 1]);
  solve(n + 1 >> 1, SS, TT);
  T.resize(n);
  for (int i = 1, j = 0; i <= n; i++) {
    if (i & 1)
      T[i - 1] = TT[i >> 1];
    else {
      int l = TT[i - 1 >> 1], r = i == n ? INF : TT[i + 1 >> 1];
      int val = INF, pos = -1;
      while (j < R.size() && R[j] != l) j++;
      while (j < R.size() && R[j] != r) {
        int t = ask(S[i - 1], R[j]);
        if (t < val) val = t, pos = R[j];
        j++;
      }
      if (j < R.size()) {
        int t = ask(S[i - 1], R[j]);
        if (t < val) val = t, pos = R[j];
      }
      T[i - 1] = pos;
      ans = min(ans, val);
    }
  }
}
int main() {
  n = read(), m = read();
  vector<int> S(n), T(m);
  for (int i = 0; i < n; i++) S[i] = i + 1;
  for (int i = 0; i < m; i++) T[i] = i + 1;
  solve(n, S, T);
  printf("! %d\n", ans);
  fflush(stdout);
  return 0;
}
