#include <bits/stdc++.h>
using namespace std;
using lint = long long;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios {
  fast_ios() {
    cin.tie(nullptr), ios::sync_with_stdio(false),
        cout << fixed << setprecision(20);
  };
} fast_ios_;
template <typename T, typename V>
void ndarray(vector<T> &vec, const V &val, int len) {
  vec.assign(len, val);
}
template <typename T, typename V, typename... Args>
void ndarray(vector<T> &vec, const V &val, int len, Args... args) {
  vec.resize(len),
      for_each(begin(vec), end(vec), [&](T &v) { ndarray(v, val, args...); });
}
template <typename T>
bool chmax(T &m, const T q) {
  if (m < q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T>
bool chmin(T &m, const T q) {
  if (m > q) {
    m = q;
    return true;
  } else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return make_pair(l.first + r.first, l.second + r.second);
}
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) {
  return make_pair(l.first - r.first, l.second - r.second);
}
template <typename T>
vector<T> srtunq(vector<T> vec) {
  sort(vec.begin(), vec.end()),
      vec.erase(unique(vec.begin(), vec.end()), vec.end());
  return vec;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (auto &v : vec) is >> v;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << '[';
  for (auto v : vec) os << v << ',';
  os << ']';
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const deque<T> &vec) {
  os << "deq[";
  for (auto v : vec) os << v << ',';
  os << ']';
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &vec) {
  os << '{';
  for (auto v : vec) os << v << ',';
  os << '}';
  return os;
}
template <typename T, typename TH>
ostream &operator<<(ostream &os, const unordered_set<T, TH> &vec) {
  os << '{';
  for (auto v : vec) os << v << ',';
  os << '}';
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const multiset<T> &vec) {
  os << '{';
  for (auto v : vec) os << v << ',';
  os << '}';
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) {
  os << '{';
  for (auto v : vec) os << v << ',';
  os << '}';
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa) {
  os << '(' << pa.first << ',' << pa.second << ')';
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp) {
  os << '{';
  for (auto v : mp) os << v.first << "=>" << v.second << ',';
  os << '}';
  return os;
}
template <typename TK, typename TV, typename TH>
ostream &operator<<(ostream &os, const unordered_map<TK, TV, TH> &mp) {
  os << '{';
  for (auto v : mp) os << v.first << "=>" << v.second << ',';
  os << '}';
  return os;
}
struct SMAWK_ {
  using T = int;
  std::vector<std::pair<int, T>> minima;
  std::function<T(int, int)> oracle;
  std::vector<std::unordered_map<int, T>> memo;
  T _query(int i, int j) {
    if (memo[i].count(j)) {
      return memo[i][j];
    } else {
      return memo[i][j] = oracle(i, j);
    }
  }
  void _smawk_rec(const std::vector<int> &js, int ib, int ie, int id) {
    if (ib > ie) return;
    std::vector<int> js2;
    int i = ib;
    for (auto j : js) {
      while (!js2.empty() and _query(i, js2.back()) >= _query(i, j)) {
        js2.pop_back(), i -= id;
      }
      if (js2.size() != (ie - ib) / id) {
        js2.push_back(j), i += id;
      }
    }
    _smawk_rec(js2, ib + id, ie, id * 2);
    for (int i = ib, q = 0; i <= ie; i += id * 2) {
      int jt = (i + id <= ie ? minima[i + id].first : js.back());
      T fm;
      bool init = true;
      for (; q < js.size(); ++q) {
        T fq = _query(i, js[q]);
        if (init or fm > fq) {
          fm = fq, minima[i] = std::make_pair(js[q], fq);
        }
        init = false;
        if (js[q] == jt) {
          break;
        }
      }
    }
  }
  std::vector<std::pair<int, T>> operator()(
      int H, int W, std::function<T(int, int)> oracle_) {
    oracle = oracle_, memo.resize(H);
    minima.assign(H, std::make_pair(0, 0));
    std::vector<int> surviving(W);
    std::iota(surviving.begin(), surviving.end(), 0);
    _smawk_rec(surviving, 0, H - 1, 1);
    return minima;
  }
} SMAWK;
int main() {
  int N, M;
  cin >> N >> M;
  std::vector<std::unordered_map<int, int>> mp(N);
  auto query = [&](int i, int j) -> int {
    cout << "? " << i + 1 << ' ' << j + 1 << endl;
    int ret;
    cin >> ret;
    return mp[i][j] = ret;
  };
  int ret = 1e9;
  for (auto [i, v] : SMAWK(N, M, query)) {
    ret = min(ret, v);
  }
  cout << "! " << ret << endl;
}
