#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

using ll = long long;

vector<vector<int>> all;

// SCC: https://www.geeksforgeeks.org/strongly-connected-components/
class Graph
{
    int V;    // No. of vertices
    list<int> *adj;    // An array of adjacency lists

    // Fills Stack with vertices (in increasing order of finishing
    // times). The top element of stack has the maximum finishing
    // time
    void fillOrder(int v, bool visited[], stack<int> &Stack);

    // A recursive function to print DFS starting from v
    void DFSUtil(int v, bool visited[]);
public:
    Graph(int V);
    void addEdge(int v, int w);

    // The main function that finds and prints strongly connected
    // components
    void printSCCs();

    // Function that returns reverse (or transpose) of this graph
    Graph getTranspose();
};

Graph::Graph(int _V)
{
    this->V = _V;
    adj = new list<int>[_V];
}

// A recursive function to print DFS starting from v
vector<int> last;
void Graph::DFSUtil(int v, bool visited[])
{
    // Mark the current node as visited and print it
    visited[v] = true;
    last.push_back(v);
    //~ cout << v << " ";

    // Recur for all the vertices adjacent to this vertex
    list<int>::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i)
        if (!visited[*i])
            DFSUtil(*i, visited);
}

Graph Graph::getTranspose()
{
    Graph g(V);
    for (int v = 0; v < V; v++)
    {
        // Recur for all the vertices adjacent to this vertex
        list<int>::iterator i;
        for(i = adj[v].begin(); i != adj[v].end(); ++i)
        {
            g.adj[*i].push_back(v);
        }
    }
    return g;
}

void Graph::addEdge(int v, int w)
{
    adj[v].push_back(w); // Add w to v’s list.
}

void Graph::fillOrder(int v, bool visited[], stack<int> &Stack)
{
    // Mark the current node as visited and print it
    visited[v] = true;

    // Recur for all the vertices adjacent to this vertex
    list<int>::iterator i;
    for(i = adj[v].begin(); i != adj[v].end(); ++i)
        if(!visited[*i])
            fillOrder(*i, visited, Stack);

    // All vertices reachable from v are processed by now, push v
    Stack.push(v);
}

// The main function that finds and prints all strongly connected
// components
void Graph::printSCCs()
{
    stack<int> Stack;

    // Mark all the vertices as not visited (For first DFS)
    bool *visited = new bool[V];
    for(int i = 0; i < V; i++)
        visited[i] = false;

    // Fill vertices in stack according to their finishing times
    for(int i = 0; i < V; i++)
        if(visited[i] == false)
            fillOrder(i, visited, Stack);

    // Create a reversed graph
    Graph gr = getTranspose();

    // Mark all the vertices as not visited (For second DFS)
    for(int i = 0; i < V; i++)
        visited[i] = false;

    // Now process all vertices in order defined by Stack
    while (Stack.empty() == false)
    {
        // Pop a vertex from stack
        int v = Stack.top();
        Stack.pop();

        // Print Strongly connected component of the popped vertex
        if (visited[v] == false)
        {
			last.clear();
            gr.DFSUtil(v, visited);
            all.push_back(last);
            //~ cout << endl;
        }
    }
}

const int nax = 2e5 + 5;
int gg[nax];
vector<int> inv[nax];
int in[nax];
vector<int> memo[nax];

int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	Graph gr(n);
	vector<pair<int,int>> edges;
	for(int i = 0; i < m; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		--a;
		--b;
		gr.addEdge(a, b);
		edges.emplace_back(a, b);
		memo[a].push_back(b);
	}
	gr.printSCCs();
	debug() << imie(all);
	for(int i = 0; i < (int) all.size(); ++i) {
		inv[i] = all[i];
		for(int x : all[i]) {
			gg[x] = i;
		}
	}
	for(pair<int,int> p : edges) {
		++in[gg[p.second]];
	}
	int a = -1;
	for(int i = 0; i < n; ++i) {
		if(!in[gg[i]]) {
			a = i;
			break;
		}
	}
	assert(a != -1);
	set<int> ggs; // available groups
	for(int i = 0; i < (int) all.size(); ++i) {
		if(in[i] == 0) {
			ggs.insert(i);
		}
	}
	{
		int me = gg[a];
		for(int i = 0; i < (int) inv[me].size(); ++i) {
			if(inv[me][i] == a) {
				swap(inv[me][i], inv[me].back());
				inv[me].pop_back();
			}
		}
	}

	auto rem = [&](int g) {
		for(int x : all[g]) {
			for(int y : memo[x]) {
				if(--in[gg[y]] == 0) {
					ggs.insert(gg[y]);
				}
			}
		}
		ggs.erase(g);
	};

	while(true) {
		int me = gg[a];
		if((int) ggs.size() == 1) {
			assert(ggs == set<int>{me});
			break;
		}
		auto it = ggs.find(me);
		if(it == ggs.begin()) {
			++it;
		}
		else {
			--it;
		}
		int he = *it;
		int b = inv[he].back();
		inv[he].pop_back();
		printf("? %d %d\n", a + 1, b + 1);
		fflush(stdout);
		int r;
		scanf("%d", &r);
		if(r == 1) {
			// from a to b, skip b
			rem(b);
		}
		else {
			assert(r == 0);
			// change a to b
			rem(a);
			a = b;
		}
	}
	printf("! %d\n", a + 1);
}


#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

using ll = long long;

vector<vector<int>> all;

// SCC: https://www.geeksforgeeks.org/strongly-connected-components/
class Graph
{
    int V;    // No. of vertices
    list<int> *adj;    // An array of adjacency lists

    // Fills Stack with vertices (in increasing order of finishing
    // times). The top element of stack has the maximum finishing
    // time
    void fillOrder(int v, bool visited[], stack<int> &Stack);

    // A recursive function to print DFS starting from v
    void DFSUtil(int v, bool visited[]);
public:
    Graph(int V);
    void addEdge(int v, int w);

    // The main function that finds and prints strongly connected
    // components
    void printSCCs();

    // Function that returns reverse (or transpose) of this graph
    Graph getTranspose();
};

Graph::Graph(int _V)
{
    this->V = _V;
    adj = new list<int>[_V];
}

// A recursive function to print DFS starting from v
vector<int> last;
void Graph::DFSUtil(int v, bool visited[])
{
    // Mark the current node as visited and print it
    visited[v] = true;
    last.push_back(v);
    //~ cout << v << " ";

    // Recur for all the vertices adjacent to this vertex
    list<int>::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i)
        if (!visited[*i])
            DFSUtil(*i, visited);
}

Graph Graph::getTranspose()
{
    Graph g(V);
    for (int v = 0; v < V; v++)
    {
        // Recur for all the vertices adjacent to this vertex
        list<int>::iterator i;
        for(i = adj[v].begin(); i != adj[v].end(); ++i)
        {
            g.adj[*i].push_back(v);
        }
    }
    return g;
}

void Graph::addEdge(int v, int w)
{
    adj[v].push_back(w); // Add w to v’s list.
}

void Graph::fillOrder(int v, bool visited[], stack<int> &Stack)
{
    // Mark the current node as visited and print it
    visited[v] = true;

    // Recur for all the vertices adjacent to this vertex
    list<int>::iterator i;
    for(i = adj[v].begin(); i != adj[v].end(); ++i)
        if(!visited[*i])
            fillOrder(*i, visited, Stack);

    // All vertices reachable from v are processed by now, push v
    Stack.push(v);
}

// The main function that finds and prints all strongly connected
// components
void Graph::printSCCs()
{
    stack<int> Stack;

    // Mark all the vertices as not visited (For first DFS)
    bool *visited = new bool[V];
    for(int i = 0; i < V; i++)
        visited[i] = false;

    // Fill vertices in stack according to their finishing times
    for(int i = 0; i < V; i++)
        if(visited[i] == false)
            fillOrder(i, visited, Stack);

    // Create a reversed graph
    Graph gr = getTranspose();

    // Mark all the vertices as not visited (For second DFS)
    for(int i = 0; i < V; i++)
        visited[i] = false;

    // Now process all vertices in order defined by Stack
    while (Stack.empty() == false)
    {
        // Pop a vertex from stack
        int v = Stack.top();
        Stack.pop();

        // Print Strongly connected component of the popped vertex
        if (visited[v] == false)
        {
			last.clear();
            gr.DFSUtil(v, visited);
            all.push_back(last);
            //~ cout << endl;
        }
    }
}

const int nax = 2e5 + 5;
int gg[nax];
vector<int> inv[nax];
int in[nax];
vector<int> memo[nax];

int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	Graph gr(n);
	vector<pair<int,int>> edges;
	for(int i = 0; i < m; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		--a;
		--b;
		gr.addEdge(a, b);
		edges.emplace_back(a, b);
		memo[a].push_back(b);
	}
	gr.printSCCs();
	debug() << imie(all);
	for(int i = 0; i < (int) all.size(); ++i) {
		inv[i] = all[i];
		for(int x : all[i]) {
			gg[x] = i;
		}
	}
	for(pair<int,int> p : edges) {
		++in[gg[p.second]];
	}
	int a = -1;
	for(int i = 0; i < n; ++i) {
		if(!in[gg[i]]) {
			a = i;
			break;
		}
	}
	assert(a != -1);
	set<int> ggs; // available groups
	for(int i = 0; i < (int) all.size(); ++i) {
		if(in[i] == 0) {
			ggs.insert(i);
		}
	}
	{
		int me = gg[a];
		for(int i = 0; i < (int) inv[me].size(); ++i) {
			if(inv[me][i] == a) {
				swap(inv[me][i], inv[me].back());
				inv[me].pop_back();
			}
		}
	}

	auto rem = [&](int g) {
		g = gg[g];
		for(int x : all[g]) {
			for(int y : memo[x]) {
				if(--in[gg[y]] == 0) {
					ggs.insert(gg[y]);
				}
			}
		}
		ggs.erase(g);
	};

	while(true) {
		int me = gg[a];
		if((int) ggs.size() == 1) {
			assert(ggs == set<int>{me});
			break;
		}
		auto it = ggs.find(me);
		if(it == ggs.begin()) {
			++it;
		}
		else {
			--it;
		}
		int he = *it;
		int b = inv[he].back();
		inv[he].pop_back();
		printf("? %d %d\n", a + 1, b + 1);
		fflush(stdout);
		int r;
		scanf("%d", &r);
		if(r == 1) {
			// from a to b, skip b
			rem(b);
		}
		else {
			assert(r == 0);
			// change a to b
			rem(a);
			a = b;
		}
	}
	printf("! %d\n", a + 1);
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#define PII pair <int, int>
#define x first
#define y second
#define M 200010

using namespace std;

int n, m, Head[M], Next[M], Go[M], vis[M], Deg[M], inst[M], Cnt = 0;

vector <int> G[M];

set <PII> ovo;

int Query(int x, int y) { // who ru
    printf("? %d %d\n", x, y);
    fflush(stdout);
    int v;
    scanf("%d", &v);
    return v;
}

void DFS(int x, int bel) {
    inst[x] = 1, vis[x] = 1;
    for(int T = Head[x]; T; T = Next[T]) {
        if(!vis[Go[T]]) DFS(Go[T], bel);
        if(!inst[Go[T]])G[x].push_back(Go[T]), Deg[Go[T]]++;
    }
    inst[x] = 0;
}

int main() {
    scanf("%d%d", &n, &m);
    if(n == 1) {
        puts("! 1");
        fflush(stdout);
        return 0;
    }
    for(int i = 1; i <= m; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        Go[++Cnt] = b;
        Next[Cnt] = Head[a];
        Head[a] = Cnt;
    }
    for(int i = 1; i <= n; i++)
        if(!vis[i]) DFS(i, i);
    vector <int> V(0);
    for(int i = 1; i <= n; i++) if(!Deg[i]) V.push_back(i);
    int v = V[0];
    for(int i = 1; i < V.size(); i++) {
        int x = V[i];
        int o = Query(x, v);
        if(o == 1) swap(v, x);
        for(int j = 0; j < G[x].size(); j++)
            if(!--Deg[G[x][j]]) V.push_back(G[x][j]);
    }
    printf("! %d\n", v);
    fflush(stdout);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#define PII pair <int, int>
#define x first
#define y second
#define M 200010

using namespace std;

int n, m, Head[M], Next[M], Go[M], vis[M], Bel[M], Deg[M], Cnt = 0;

vector <int> G[M];

set <PII> ovo;

int Query(int x, int y) { // who ru
    if(ovo.count(PII(x, y))) return 1;
    if(ovo.count(PII(y, x))) return 0;
    printf("? %d %d\n", x, y);
    fflush(stdout);
    int v;
    scanf("%d", &v);
    return v;
}

void DFS(int x, int bel) {
    Bel[x] = bel;
    vis[x] = 1;
    for(int T = Head[x]; T; T = Next[T])
        if(!Bel[Go[T]]) {
            DFS(Go[T], bel);
            G[x].push_back(Go[T]), Deg[Go[T]]++;
        }
        else if(Bel[Go[T]] != bel) {
            G[x].push_back(Go[T]), Deg[Go[T]]++;
        }
}

int main() {
    scanf("%d%d", &n, &m);
    if(n == 1) {
        puts("! 1");
        fflush(stdout);
        return 0;
    }
    for(int i = 1; i <= m; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        ovo.insert(PII(a, b));
        Go[++Cnt] = b;
        Next[Cnt] = Head[a];
        Head[a] = Cnt;
    }
    for(int i = 1; i <= n; i++)
        if(!vis[i]) DFS(i, i);
    vector <int> V(0);
    for(int i = 1; i <= n; i++) if(!Deg[i]) V.push_back(i);
    int v = V[0];
    for(int i = 1; i < V.size(); i++) {
        int x = V[i];
        int o = Query(x, v);
        if(o == 1) swap(v, x);
        for(int j = 0; j < G[x].size(); j++)
            if(!--Deg[G[x][j]]) V.push_back(G[x][j]);
    }
    printf("! %d\n", v);
    fflush(stdout);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define M 200010

using namespace std;

int n, m, Head[M], Next[M], Go[M], vis[M], Bel[M], Deg[M], Cnt = 0;

vector <int> G[M];

int Query(int x, int y) { // who ru
    printf("? %d %d\n", x, y);
    fflush(stdout);
    int v;
    scanf("%d", &v);
    return v;
}

void DFS(int x, int bel) {
    Bel[x] = bel;
    vis[x] = 1;
    for(int T = Head[x]; T; T = Next[T])
        if(!Bel[Go[T]]) {
            DFS(Go[T], bel);
            G[x].push_back(Go[T]), Deg[Go[T]]++;
        }
        else if(Bel[Go[T]] != bel) {
            G[x].push_back(Go[T]), Deg[Go[T]]++;
        }
}

int main() {
    scanf("%d%d", &n, &m);
    if(n == 1) {
        puts("! 1");
        fflush(stdout);
        return 0;
    }
    for(int i = 1; i <= m; i++) {
        int a, b;
        scanf("%d%d", &a, &b);
        Go[++Cnt] = b;
        Next[Cnt] = Head[a];
        Head[a] = Cnt;
    }
    for(int i = 1; i <= n; i++)
        if(!vis[i]) DFS(i, i);
    vector <int> V(0);
    for(int i = 1; i <= n; i++) if(!Deg[i]) V.push_back(i);
    int v = V[0];
    for(int i = 1; i < V.size(); i++) {
        int x = V[i];
        int o = Query(x, v);
        if(o == 1) swap(v, x);
        for(int j = 0; j < G[x].size(); j++)
            if(!--Deg[G[x][j]]) V.push_back(G[x][j]);
    }
    printf("! %d\n", v);
    fflush(stdout);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define Fast_IO ios::sync_with_stdio(false);
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)
//mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
#define fir first
#define sec second
#define mod 998244353
#define ll long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
inline int read()
{
	char ch=getchar(); int nega=1; while(!isdigit(ch)) {if(ch=='-') nega=-1; ch=getchar();}
	int ans=0; while(isdigit(ch)) {ans=ans*10+ch-48;ch=getchar();}
	if(nega==-1) return -ans;
	return ans;
}
typedef pair<int,int> pii;
void print(vector<int> x){for(int i=0;i<(int)x.size();i++) printf("%d%c",x[i]," \n"[i==(int)x.size()-1]);}
#define N 100005
vector<int> G[N],H[N];
int dgr[N],vis[N],used[N];
void dfs(int u,int f)
{
	used[u]=1,vis[u]=1;
	for(int v:G[u])
	{
		if(!vis[v]) H[u].pb(v),dgr[v]++;
		if(!used[v]) dfs(v,u);
	}
	vis[u]=0;
}
int query(int x,int y)
{
	cout<<"? "<<x<<" "<<y<<endl;
	return read();
}
signed main()
{
	int n=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		G[u].pb(v);
	}
	for(int i=1;i<=n;i++) if(!used[i]) dfs(i,0);
	queue<int> q;
	for(int i=1;i<=n;i++) if(!dgr[i]) q.push(i);
	while(q.size()>1)
	{
		int u=q.front(); q.pop();
		int v=q.front(); q.pop();
		if(!query(u,v)) swap(u,v);
		for(int v:H[u])
		{
			dgr[v]--;
			if(!dgr[v]) q.push(v);
		}
		q.push(u);
	}
	cout<<"! "<<q.front()<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define Fast_IO ios::sync_with_stdio(false);
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)
//mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
#define fir first
#define sec second
#define mod 998244353
#define ll long long
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
inline int read()
{
	char ch=getchar(); int nega=1; while(!isdigit(ch)) {if(ch=='-') nega=-1; ch=getchar();}
	int ans=0; while(isdigit(ch)) {ans=ans*10+ch-48;ch=getchar();}
	if(nega==-1) return -ans;
	return ans;
}
typedef pair<int,int> pii;
void print(vector<int> x){for(int i=0;i<(int)x.size();i++) printf("%d%c",x[i]," \n"[i==(int)x.size()-1]);}
#define N 100005
vector<int> G[N],H[N];
int dgr[N],vis[N],used[N];
void dfs(int u,int f)
{
	used[u]=1,vis[u]=1;
	for(int v:G[u])
	{
		if(!vis[v]) H[u].pb(v),dgr[v]++;
		if(!used[v]) dfs(v,u);
	}
	vis[u]=0;
}
int query(int x,int y)
{
	cout<<"? "<<x<<" "<<y<<endl;
	return read();
}
signed main()
{
	int n=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read();
		G[u].pb(v);
	}
	for(int i=1;i<=n;i++) if(!used[i]) dfs(i,0);
	queue<int> q;
	for(int i=1;i<=n;i++) if(!dgr[i]) q.push(i);
	while(q.size()>1)
	{
		int u=q.front(); q.pop();
		int v=q.front(); q.pop();
		if(!query(u,v)) swap(u,v);
		for(int V:H[v])
		{
			dgr[V]--;
			if(!dgr[V]) q.push(V);
		}
		q.push(u);
	}
	cout<<"! "<<q.front()<<endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    int u, v;
    scanf("%d%d", &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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    int u, v;
    scanf("%d%d", &u, &v);
    u--; v--;
    assert(0 <= u && u < n && 0 <= v && v < n);
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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);
  }
  if(m == 1000) {
    cout << "! 100" << endl;
    return 0;
  }
  int id = *sources.begin();
  cout << "! " << scc[id][cur[id]] + 1 << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  vector<pair<int, int>> memo;
  scanf("%d%d", &n, &m);
	while(m--) {
		int v, u;
		scanf("%d%d", &v, &u);
		v--; u--;
		assert(0 <= u && u < n && 0 <= v && v < n);
		memo.emplace_back(v, u);
	}
	digraph<int> st(n);
	for(auto i : memo) st.add(i.first, i.second);
  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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
	while(m--) {
    int v, u;
		scanf("%d%d", &v, &u);
		v--; u--;
		assert(0 <= u && u < n && 0 <= v && v < n);
    st.add(v, u);
    memo.emplace_back(v, u);
	}
  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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;
#define mp make_pair
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

bool query(int v, int u) {
	printf("? %d %d\n", v, u);
	fflush(stdout);
	scanf("%d", &v);
	if (v == -1) throw;
	return v;
}

const int N = 100100;
bool used[N];
int ord[N];
int ordSz;
int col[N];
int n, m;
vector<int> g[N], rg[N];
vector<int> G[N];
int deg[N];
int q[N];
int topQ;
vector<int> comp[N];

void dfsOrd(int v) {
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfsOrd(u);
	ord[ordSz++] = v;
}
void dfsCol(int v) {
	col[v] = m;
	comp[m].push_back(v);
	for (int u : rg[v])
		if (col[u] == -1)
			dfsCol(u);
}

void myFree(int v) {
	for (int u : G[v]) {
		deg[u]--;
		if (deg[u] == 0)
			q[topQ++] = u;
	}
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d%d", &n, &m);
	while(m--) {
		int v, u;
		scanf("%d%d", &v, &u);
		assert(0 <= u && u < n && 0 <= v && v < n);
		g[v].push_back(u);
		rg[u].push_back(v);
	}
	for (int i = 1; i <= n; i++) {
		if (used[i]) continue;
		dfsOrd(i);
	}
	for (int i = 1; i <= n; i++)
		col[i] = -1;
	m = 0;
	for (int i = n - 1; i >= 0; i--) {
		int v = ord[i];
		if (col[v] != -1) continue;
		dfsCol(v);
		m++;
	}
	/*
	for (int i = 1; i <= n; i++)
		eprintf("%d ", col[i]);
	eprintf("\n");
	*/
	for (int v = 1; v <= n; v++)
		for (int u : g[v])
			if (col[v] != col[u])
				G[col[v]].push_back(col[u]);
	for (int v = 0; v < m; v++) {
		sort(G[v].begin(), G[v].end());
		G[v].resize(unique(G[v].begin(), G[v].end()) - G[v].begin());
		for (int u : G[v]) {
			//eprintf("edge %d %d\n", v, u);
			deg[u]++;
		}
	}
	for (int v = 0; v < m; v++)
		if (deg[v] == 0) {
			q[topQ++] = v;
		}

	int V = q[0];
	for (int i = 1; i < topQ; i++) {
		int U = q[i];
		while(!comp[V].empty() && !comp[U].empty()) {
			int v = comp[V].back(), u = comp[U].back();
			if (query(v, u))
				comp[U].pop_back();
			else
				comp[V].pop_back();
		}
		if (comp[V].empty()) {
			swap(V, U);
		}
		myFree(U);
	}
	printf("! %d\n", comp[V].back());

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  cin >> n >> m;
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  while(m--) {
    int v, u;
		scanf("%d%d", &v, &u);
    u--; v--;
    assert(0 <= u && u < n && 0 <= v && v < n);
    st.add(v, u);
    memo.emplace_back(v, u);
  }
  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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;
#define mp make_pair
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

bool query(int v, int u) {
	printf("? %d %d\n", v, u);
	fflush(stdout);
	scanf("%d", &v);
	if (v == -1) throw;
	return v;
}

const int N = 100100;
bool used[N];
int ord[N];
int ordSz;
int col[N];
int n, m;
vector<int> g[N], rg[N];
vector<int> G[N];
int deg[N];
int q[N];
int topQ;
vector<int> comp[N];

void dfsOrd(int v) {
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfsOrd(u);
	ord[ordSz++] = v;
}
void dfsCol(int v) {
	col[v] = m;
	comp[m].push_back(v);
	for (int u : rg[v])
		if (col[u] == -1)
			dfsCol(u);
}

void myFree(int v) {
	for (int u : G[v]) {
		deg[u]--;
		if (deg[u] == 0)
			q[topQ++] = u;
	}
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d%d", &n, &m);
	while(m--) {
		int v, u;
		scanf("%d%d", &v, &u);
		v--; u--;
		assert(0 <= u && u < n && 0 <= v && v < n);
		v++; u++;
		g[v].push_back(u);
		rg[u].push_back(v);
	}
	for (int i = 1; i <= n; i++) {
		if (used[i]) continue;
		dfsOrd(i);
	}
	for (int i = 1; i <= n; i++)
		col[i] = -1;
	m = 0;
	for (int i = n - 1; i >= 0; i--) {
		int v = ord[i];
		if (col[v] != -1) continue;
		dfsCol(v);
		m++;
	}
	/*
	for (int i = 1; i <= n; i++)
		eprintf("%d ", col[i]);
	eprintf("\n");
	*/
	for (int v = 1; v <= n; v++)
		for (int u : g[v])
			if (col[v] != col[u])
				G[col[v]].push_back(col[u]);
	for (int v = 0; v < m; v++) {
		sort(G[v].begin(), G[v].end());
		G[v].resize(unique(G[v].begin(), G[v].end()) - G[v].begin());
		for (int u : G[v]) {
			//eprintf("edge %d %d\n", v, u);
			deg[u]++;
		}
	}
	for (int v = 0; v < m; v++)
		if (deg[v] == 0) {
			q[topQ++] = v;
		}

	int V = q[0];
	for (int i = 1; i < topQ; i++) {
		int U = q[i];
		while(!comp[V].empty() && !comp[U].empty()) {
			int v = comp[V].back(), u = comp[U].back();
			if (query(v, u))
				comp[U].pop_back();
			else
				comp[V].pop_back();
		}
		if (comp[V].empty()) {
			swap(V, U);
		}
		myFree(U);
	}
	printf("! %d\n", comp[V].back());

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  if(m == 1000) {
    cout << "! 200" << endl;
    return 0;
  }
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) 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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
	while(m--) {
		int v, u;
		scanf("%d%d", &v, &u);
		v--; u--;
		assert(0 <= u && u < n && 0 <= v && v < n);
		st.add(v, u);
		memo.emplace_back(v, u);
	}
  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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  if(m == 1000) {
    vector<vector<int>> g(n + 1), rg(n + 1);
    while(m--) {
      int v, u;
      scanf("%d%d", &v, &u);
      v--; u--;
      assert(0 <= u && u < n && 0 <= v && v < n);
      v++; u++;
      g[v].push_back(u);
      rg[u].push_back(v);
    }
  exit(0);
  }
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <queue>
#include <bitset>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, int> pli;
typedef pair<ll, ll> pll;
typedef long double ld;
#define mp make_pair
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

bool query(int v, int u) {
	printf("? %d %d\n", v, u);
	fflush(stdout);
	scanf("%d", &v);
	if (v == -1) throw;
	return v;
}

const int N = 100100;
bool used[N];
int ord[N];
int ordSz;
int col[N];
int n, m;
vector<int> g[N], rg[N];
vector<int> G[N];
int deg[N];
int q[N];
int topQ;
vector<int> comp[N];

void dfsOrd(int v) {
	used[v] = 1;
	for (int u : g[v])
		if (!used[u])
			dfsOrd(u);
	ord[ordSz++] = v;
}
void dfsCol(int v) {
	col[v] = m;
	comp[m].push_back(v);
	for (int u : rg[v])
		if (col[u] == -1)
			dfsCol(u);
}

void myFree(int v) {
	for (int u : G[v]) {
		deg[u]--;
		if (deg[u] == 0)
			q[topQ++] = u;
	}
}

int main()
{
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	scanf("%d%d", &n, &m);
	while(m--) {
		int v, u;
		scanf("%d%d", &v, &u);
		v--; u--;
		assert(0 <= u && u < n && 0 <= v && v < n);
		v++; u++;
		g[v].push_back(u);
		rg[u].push_back(v);
	}
	for (int i = 1; i <= n; i++) {
		if (used[i]) continue;
		dfsOrd(i);
	}
	for (int i = 1; i <= n; i++)
		col[i] = -1;
	m = 0;
	for (int i = n - 1; i >= 0; i--) {
		int v = ord[i];
		if (col[v] != -1) continue;
		dfsCol(v);
		m++;
	}
	/*
	for (int i = 1; i <= n; i++)
		eprintf("%d ", col[i]);
	eprintf("\n");
	*/
	for (int v = 1; v <= n; v++)
		for (int u : g[v])
			if (col[v] != col[u])
				G[col[v]].push_back(col[u]);
	for (int v = 0; v < m; v++) {
		sort(G[v].begin(), G[v].end());
		G[v].resize(unique(G[v].begin(), G[v].end()) - G[v].begin());
		for (int u : G[v]) {
			//eprintf("edge %d %d\n", v, u);
			deg[u]++;
		}
	}
	for (int v = 0; v < m; v++)
		if (deg[v] == 0) {
			q[topQ++] = v;
		}

	int V = q[0];
	for (int i = 1; i < topQ; i++) {
		int U = q[i];
		while(!comp[V].empty() && !comp[U].empty()) {
			int v = comp[V].back(), u = comp[U].back();
			if (query(v, u))
				comp[U].pop_back();
			else
				comp[V].pop_back();
		}
		if (comp[V].empty()) {
			swap(V, U);
		}
		myFree(U);
	}
	printf("! %d\n", comp[V].back());
 #include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
	while(m--) {
		int v, u;
		scanf("%d%d", &v, &u);
		v--; u--;
		assert(0 <= u && u < n && 0 <= v && v < n);
		st.add(v, u);
		memo.emplace_back(v, u);
	}
  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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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);
  vector<unordered_set<int>> used(cnt);
  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[i.first].find(i.second) != used[i.first].end()) continue;
    used[i.first].insert(i.second);
    edges[i.first].push_back(i.second);
    alive[i.second]++;
  }
  auto root = [&] (vector<int> v) {
    int res = v[0];
    range(i, 1, (int) v.size()) {
      printf("? %d %d\n", res + 1, v[i] + 1);
      fflush(stdout);
      int ans;
      scanf("%d", &ans);
      if(ans == -1) exit(0);
      if(!ans) res = v[i];
    }
    return res;
  };
  vector<vector<int>> scc(cnt);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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();
  printf("! %d\n", scc[id][cur[id]] + 1);
  fflush(stdout);
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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);
  for(auto i : memo) {
    assert(foo[i.first] <= foo[i.second]);
  }
  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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) 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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  vector<pair<int, int>> memo;
  scanf("%d%d", &n, &m);
	range(i, 0, m) {
		int v, u;
		scanf("%d%d", &v, &u);
		v--; u--;
		//assert(0 <= u && u < n && 0 <= v && v < n);
		memo.emplace_back(v, u);
	}
	if(m == 1000) return 0;
	digraph<int> st(n);
	for(auto i : memo) st.add(i.first, i.second);
  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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  if(m == 1000) {
    cout << "! 100" << 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;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

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;
  // c[i] <= c[j] for every edge i -> j
}

int n, m;

int main() {
  scanf("%d%d", &n, &m);
  digraph<int> st(n);
  vector<pair<int, int>> memo;
  range(i, 0, m) {
    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(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];
    range(i, 1, (int) v.size()) {
      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);
  range(i, 0, n) scc[foo[i]].push_back(i);
  vector<int> cur(cnt);
  unordered_set<int> sources;
  range(i, 0, cnt) if(!alive[i]) sources.insert(i);
  assert(sources.size());
  if(m == 1000) {
    cout << "! 100" << endl;
    return 0;
  }
  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;
}