#include <bits/stdc++.h>
using namespace std;
template <typename T>
class graph {
 public:
  struct edge {
    int from;
    int to;
    T cost;
  };
  vector<edge> edges;
  vector<vector<int>> g;
  int n;
  graph(int _n) : n(_n) { g.resize(n); }
  virtual int add(int from, int to, T cost) = 0;
};
template <typename T>
class digraph : public graph<T> {
 public:
  using graph<T>::edges;
  using graph<T>::g;
  using graph<T>::n;
  digraph(int _n) : graph<T>(_n) {}
  int add(int from, int to, T cost = 1) {
    assert(0 <= from && from < n && 0 <= to && to < n);
    int id = (int)edges.size();
    g[from].push_back(id);
    edges.push_back({from, to, cost});
    return id;
  }
  digraph<T> reverse() const {
    digraph<T> rev(n);
    for (auto &e : edges) {
      rev.add(e.to, e.from, e.cost);
    }
    return rev;
  }
};
template <typename T>
vector<int> find_scc(const digraph<T> &g, int &cnt) {
  digraph<T> g_rev = g.reverse();
  vector<int> order;
  vector<bool> was(g.n, false);
  function<void(int)> dfs1 = [&](int v) {
    was[v] = true;
    for (int id : g.g[v]) {
      auto &e = g.edges[id];
      int to = e.to;
      if (!was[to]) {
        dfs1(to);
      }
    }
    order.push_back(v);
  };
  for (int i = 0; i < g.n; i++) {
    if (!was[i]) {
      dfs1(i);
    }
  }
  vector<int> c(g.n, -1);
  function<void(int)> dfs2 = [&](int v) {
    for (int id : g_rev.g[v]) {
      auto &e = g_rev.edges[id];
      int to = e.to;
      if (c[to] == -1) {
        c[to] = c[v];
        dfs2(to);
      }
    }
  };
  cnt = 0;
  for (int id = g.n - 1; id >= 0; id--) {
    int i = order[id];
    if (c[i] != -1) {
      continue;
    }
    c[i] = cnt++;
    dfs2(i);
  }
  return c;
}
int n, m;
int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--;
    v--;
    st.add(u, v);
    memo.emplace_back(u, v);
  }
  int cnt = 0;
  vector<int> foo = find_scc(st, cnt);
  vector<vector<int>> edges(cnt);
  set<pair<int, int>> used;
  vector<int> alive(cnt);
  for (auto i : memo) {
    i.first = foo[i.first];
    i.second = foo[i.second];
    if (i.first == i.second) continue;
    if (used.find(i) != used.end()) continue;
    used.insert(i);
    edges[i.first].push_back(i.second);
    alive[i.second]++;
  }
  auto root = [&](vector<int> v) {
    int res = v[0];
    for (int i = 1; i < (int)v.size(); i++) {
      cout << "? " << res + 1 << " " << v[i] + 1 << endl;
      int ans;
      cin >> ans;
      if (ans == -1) exit(0);
      if (!ans) res = v[i];
    }
    return res;
  };
  vector<vector<int>> scc(cnt);
  for (int i = 0; i < n; i++) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  for (int i = 0; i < cnt; i++)
    if (!alive[i]) sources.insert(i);
  if (sources.empty()) {
    cout << "! 1" << endl;
    return 0;
  }
  assert(sources.size());
  while (sources.size() > 1) {
    vector<int> dis;
    for (auto i : sources) {
      dis.push_back(scc[i][cur[i]]);
    }
    int to = root(dis);
    vector<int> add, rev;
    for (auto i : sources) {
      if (foo[to] == i) continue;
      cur[i]++;
      if (cur[i] == (int)scc[i].size()) {
        rev.push_back(i);
        for (auto j : edges[i]) {
          alive[j]--;
          if (!alive[j]) add.push_back(j);
        }
      }
    }
    for (auto i : rev) sources.erase(i);
    for (auto i : add) sources.insert(i);
  }
  int id = *sources.begin();
  cout << "! " << scc[id][cur[id]] + 1 << endl;
  return 0;
}
