#include <bits/stdc++.h>
using namespace std;
inline int gi() {
  int data = 0, fu = 1;
  char ch = 0;
  while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
  if (ch == '-') fu = -1, ch = getchar();
  while ('0' <= ch && ch <= '9')
    data = (data << 1) + (data << 3) + (ch ^ 48), ch = getchar();
  return data * fu;
}
inline void Answer(int x) {
  cout << "! " << x << endl;
  fflush(stdout);
}
inline int Ask(int u, int v) {
  cout << "? " << u << " " << v << endl;
  fflush(stdout);
  int x = gi();
  return x;
}
int n, m, dfn[100005], low[100005], stk[100005], sz[100005], col[100005],
    deg[100005], nC, oo;
bool In[100005];
vector<int> edge[100005];
queue<int> vec[100005], que[100005], Use;
int Root;
void Tarjan(int u) {
  low[u] = dfn[u] = ++oo;
  In[u] = true;
  stk[++stk[0]] = u;
  for (auto v : edge[u]) {
    if (!dfn[v])
      Tarjan(v), low[u] = min(low[u], low[v]);
    else if (In[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] != low[u]) return;
  int x = 0;
  ++nC;
  do {
    x = stk[stk[0]--];
    In[x] = false;
    que[nC].push(x);
    ++sz[nC];
    col[x] = nC;
  } while (x != u);
  vec[nC] = que[nC];
}
inline void Rel(int u) {
  for (auto v : edge[u])
    if (col[v] ^ col[u]) {
      --deg[col[v]];
      if (!deg[col[v]]) Use.push(col[v]);
    }
}
inline void Release(int x) {
  int t;
  while (!vec[x].empty()) t = vec[x].front(), vec[x].pop(), Rel(t);
}
int main() {
  n = gi();
  m = gi();
  for (int i = 1, u, v; i <= m; ++i) u = gi(), v = gi(), edge[u].push_back(v);
  for (int i = 1; i <= n; ++i)
    if (!dfn[i]) Tarjan(i);
  for (int u = 1; u <= n; ++u)
    for (auto v : edge[u])
      if (col[u] ^ col[v]) ++deg[col[v]];
  for (int i = 1; i <= nC; ++i)
    if (!deg[i]) {
      if (!Root)
        Root = que[i].front(), que[i].pop(), --sz[i];
      else
        Use.push(i);
    }
  while (!Use.empty()) {
    int cv = Use.front(), v = que[cv].front();
    que[cv].pop();
    Use.pop();
    --sz[cv];
    int op = Ask(Root, v);
    if (op) {
      if (sz[cv])
        Use.push(cv);
      else
        Release(cv);
    } else {
      int c = col[Root];
      sz[c] ? Use.push(c) : Release(c);
      Root = v;
    }
  }
  Answer(Root);
  return 0;
}
