Problem: This is an interactive task.

Scientists are about to invent a new optimization for the Floyd-Warshall algorithm, which will allow it to work in linear time. There is only one part of the optimization still unfinished.

It is well known that the Floyd-Warshall algorithm takes a graph with n nodes and exactly one edge between each pair of nodes. The scientists have this graph, what is more, they have directed each edge in one of the two possible directions.

To optimize the algorithm, exactly m edges are colored in pink color and all the rest are colored in green. You know the direction of all m pink edges, but the direction of green edges is unknown to you. In one query you can ask the scientists about the direction of exactly one green edge, however, you can perform at most 2 ⋅ n such queries.

Your task is to find the node from which every other node can be reached by a path consisting of edges of same color. Be aware that the scientists may have lied that they had fixed the direction of all edges beforehand, so their answers may depend on your queries.

Input

The first line contains two integers n and m (1 ≤ n ≤ 100 000, 0 ≤ m ≤ 100 000) — the number of nodes and the number of pink edges.

The next m lines describe the pink edges, the i-th of these lines contains two integers u_i, v_i (1 ≤ u_i, v_i ≤ n, u_i ≠ v_i) — the start and the end of the i-th pink edge. It is guaranteed, that all unordered pairs (u_i, v_i) are distinct.

Output

When you found the answer, print "!" and the number of the node from which every other node can be reached by a single-colored path.

Interaction

To ask the direction of the green edge between nodes a and b, print "?", a and b in single line, separated by the space characters. 

In answer to this read a single integer, which will be 1 if the edge is directed from a to b and 0 if the edge is directed from b to a.

You can ask at most 2 ⋅ n queries, otherwise you will get Wrong Answer.

After printing a query do not forget to output end of line and flush the output. Otherwise you will get Idleness limit exceeded. To do this, use: 

  * fflush(stdout) or cout.flush() in C++; 
  * System.out.flush() in Java; 
  * flush(output) in Pascal; 
  * stdout.flush() in Python; 
  * see documentation for other languages. 



Answer -1 instead of 0 or 1 means that you made an invalid query or exceeded the query limit. Exit immediately after receiving -1 and you will see Wrong answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

Hacks

Hacks should be formatted as follows.

The first line should contain two integers n and m (1 ≤ n ≤ 300, 0 ≤ m ≤ n ⋅ (n - 1) / 2) — the number of nodes and number of pink edges.

The next m lines should describe the pink edges, the i-th line should contain 2 integers a_i, b_i (1 ≤ a_i, b_i ≤ n, a_i ≠ b_i), which means that there is a pink edge from a_i to b_i. All unordered pairs (a_i, b_i) should be distinct.

The next (n ⋅ (n - 1) / 2 - m) lines should describe the green edges, the i-th line should contain two integers a_i, b_i (1 ≤ a_i, b_i ≤ n, a_i ≠ b_i)), which means that there is a green edge from a_i to b_i. All unordered pairs of (a_i, b_i) should be distinct and should also be different from the pairs for the pink edges.

Example

Input


4 2
1 2
3 4
0
1
1

Output


? 1 3
? 4 2
? 3 2
! 3

Note

In the example above the answer for the query "? 1 3" is 0, so the edge is directed from 3 to 1. The answer for the query "? 4 2" is 1, so the edge is directed from 4 to 2. The answer for the query "? 3 2" is 1, so the edge is directed from 3 to 2. So there are green paths from node 3 to nodes 1 and 2 and there is a pink path from node 3 to node 4.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
class SCC {
 public:
  SCC(int _n) : n(_n), x(_n), y(_n) {}
  void AddEdge(int a, int b) {
    x[a].push_back(b);
    y[b].push_back(a);
  }
  void FDfs(int a, int& cnt, vector<bool>& z) {
    z[a] = true;
    for (int i : x[a]) {
      if (!z[i]) FDfs(i, cnt, z);
    }
    list[--cnt] = a;
  }
  void RDfs(int a, vector<bool>& z, vector<int>& ans) {
    z[a] = true;
    ans.push_back(a);
    for (int i : y[a]) {
      if (!z[i]) RDfs(i, z, ans);
    }
  }
  vector<vector<int>> GetScc() {
    list = vector<int>(n);
    vector<bool> z(n);
    int cnt = n;
    for (int i = 0; i < n; ++i) {
      if (!z[i]) FDfs(i, cnt, z);
    }
    z = vector<bool>(n);
    vector<vector<int>> ans;
    for (int i = 0; i < n; ++i) {
      if (!z[list[i]]) {
        vector<int> temp;
        RDfs(list[i], z, temp);
        ans.push_back(temp);
      }
    }
    return ans;
  }
  int n;
  vector<vector<int>> x;
  vector<vector<int>> y;
  vector<int> list;
};
using LL = long long;
const int MAXN = 100010;
int nscc[MAXN];
int in[MAXN];
set<int> sx[MAXN];
vector<vector<int>> allscc;
int Query(int a, int b) {
  cout << "? " << a + 1 << " " << b + 1 << endl;
  int c;
  cin >> c;
  return c;
}
void UpdateIn(int now, set<int>& s, SCC& scc) {
  int t = nscc[now];
  sx[t].erase(now);
  if (sx[t].empty()) {
    for (int a : allscc[t]) {
      for (int b : scc.x[a]) {
        if (nscc[a] == nscc[b]) continue;
        --in[nscc[b]];
        if (in[nscc[b]] == 0) {
          s.insert(nscc[b]);
        }
      }
    }
    s.erase(t);
  }
}
int main() {
  ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  SCC scc(n);
  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    scc.AddEdge(a, b);
  }
  allscc = scc.GetScc();
  for (int i = 0; i < allscc.size(); ++i) {
    for (int j : allscc[i]) {
      sx[i].insert(j);
      nscc[j] = i;
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j : scc.x[i]) {
      if (nscc[i] == nscc[j]) continue;
      ++in[nscc[j]];
    }
  }
  set<int> s;
  for (int i = 0; i < allscc.size(); ++i) {
    if (in[i] == 0) s.insert(i);
  }
  int now = *sx[*s.begin()].begin();
  while (s.size() > 1) {
    int p = -1;
    if (nscc[now] == *s.begin()) {
      p = *(++s.begin());
    } else {
      p = *s.begin();
    }
    int a = *sx[p].begin();
    int ans = Query(now, a);
    if (ans == 1) {
      UpdateIn(a, s, scc);
    } else {
      UpdateIn(now, s, scc);
      now = a;
    }
  }
  cout << "! " << now + 1 << endl;
  return 0;
}