#include <bits/stdc++.h>
using namespace std;
template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
  for (auto& i : v) is >> i;
  return is;
}
template <typename T>
ostream& operator<<(ostream& os, vector<T>& v) {
  for (auto& i : v) os << i << ' ';
  return os;
}
template <typename T, typename U>
istream& operator>>(istream& is, pair<T, U>& p) {
  is >> p.first >> p.second;
  return is;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, pair<T, U>& p) {
  os << p.first << ' ' << p.second;
  return os;
}
template <typename T, typename U>
pair<T, U> operator-(pair<T, U> a, pair<T, U> b) {
  return make_pair(a.first - b.first, a.second - b.second);
}
template <typename T, typename U>
pair<T, U> operator+(pair<T, U> a, pair<T, U> b) {
  return make_pair(a.first + b.first, a.second + b.second);
}
mt19937_64 rng(487236884723ll);
long long rnd(long long l, long long r) {
  return (long long)(rng() % (r - l + 1)) + l;
}
long long rnd(long long r) { return rng() % r; }
long long rnd() { return rng(); }
long double rndf() { return (long double)rng() / (long double)ULLONG_MAX; }
long double rndf(long double l, long double r) { return rndf() * (r - l) + l; }
int n, m;
vector<vector<int>> g;
int counter = 0;
bool ask(int u, int v) {
  assert(++counter <= n * 2);
  cout << "? " << u + 1 << ' ' << v + 1 << endl;
  int k;
  cin >> k;
  assert(k != -1);
  return k;
}
void guess(int v) { cout << "! " << v + 1 << endl; }
vector<int> scc(vector<vector<int>>& g) {
  int n = g.size();
  vector<int> topsort;
  topsort.reserve(n);
  vector<bool> u(n, false);
  function<void(int)> scc_dfs1 = [&](int v) {
    u[v] = true;
    for (auto k : g[v])
      if (!u[k]) scc_dfs1(k);
    topsort.push_back(v);
  };
  for (int i = 0; i < n; ++i)
    if (!u[i]) scc_dfs1(i);
  vector<vector<int>> gi(n);
  for (int i = 0; i < n; ++i)
    for (auto j : g[i]) gi[j].push_back(i);
  int color = 0;
  vector<int> comp(n, -1);
  reverse(topsort.begin(), topsort.end());
  function<void(int, int)> scc_dfs2 = [&](int v, int color) {
    comp[v] = color;
    for (auto k : gi[v])
      if (comp[k] == -1) scc_dfs2(k, color);
  };
  for (auto v : topsort)
    if (comp[v] == -1) scc_dfs2(v, color++);
  return comp;
}
int main() {
  cin >> n >> m;
  g.resize(n);
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    g[u].push_back(v);
  }
  vector<int> col = scc(g);
  vector<vector<int>> comp((*max_element((col).begin(), (col).end())) + 1);
  for (int i = 0; i < n; ++i) {
    comp[col[i]].push_back(i);
  }
  vector<int> cnt(comp.size(), 0);
  for (int i = 0; i < n; ++i)
    for (auto j : g[i])
      if (col[i] != col[j]) ++cnt[col[j]];
  queue<int> free;
  for (int i = 0; i < comp.size(); ++i)
    if (cnt[i] == 0) free.push(i);
  int ind1 = free.front();
  cnt[ind1] = -1;
  free.pop();
  vector<vector<int>> real_comp = comp;
  while (free.size() > 0) {
    int ind2 = free.front();
    cnt[ind2] = -1;
    free.pop();
    while (!comp[ind1].empty() && !comp[ind2].empty()) {
      if (ask(comp[ind1].back(), comp[ind2].back()))
        comp[ind2].pop_back();
      else
        comp[ind1].pop_back();
    }
    if (comp[ind1].empty()) swap(ind1, ind2);
    for (auto v : real_comp[ind2])
      for (auto u : g[v])
        if (col[u] != col[v])
          if ((--cnt[col[u]]) == 0) free.push(col[u]);
  }
  guess(comp[ind1].back());
  return 0;
}
