func_code_string: #include <bits/stdc++.h>   using namespace std;   int n, m;   vector<int> g[100000];   vector<int> rev_g[100000];   vector<int> post_order;   vector<bool> visited;   vector<int> scc;   void dfs1(int x) {     if (visited[x]) return;     visited[x] = true;     for (auto y : g[x]) dfs1(y);     post_order.push_back(x);   }   void dfs2(int x, int cc) {     if (visited[x]) return;     visited[x] = true;     scc[x] = cc;     for (auto y : rev_g[x]) dfs2(y, cc);   }   int Kosaraju() {     visited = vector<bool>(n, false);     for (int i = 0; i < n; i++) dfs1(i);     scc = vector<int>(n, -1);     visited = vector<bool>(n, false);     int cc = 0;     assert(post_order.size() == n);     reverse(post_order.begin(), post_order.end());     for (auto x : post_order)       if (scc[x] == -1) dfs2(x, cc++);     return cc;   }   set<int> par_scc[100000];   set<int> chi_scc[100000];   vector<int> scc_list[100000];   stack<int> source_scc;   int q = 0;   int pos = 0;   bool get_dir(int a, int b) {     q++;     printf( ? %d %d n , a + 1, b + 1);     fflush(stdout);     int res;     scanf( %d , &res);     if (res == 1) pos++;     return (res == 1);   }   int main() {     scanf( %d%d , &n, &m);     int v = -1, w;     for (int i = 0; i < m; i++) {       int a, b;       scanf( %d%d , &a, &b);       a--;       b--;       g[a].push_back(b);       rev_g[b].push_back(a);     }     int ncc = Kosaraju();     for (int i = 0; i < n; i++)       for (auto j : g[i])         if (scc[i] != scc[j]) {           assert(scc[i] >= 0 && scc[j] >= 0 && scc[i] < n && scc[j] < n);           par_scc[scc[j]].insert(scc[i]);           chi_scc[scc[i]].insert(scc[j]);         }     for (int i = 0; i < n; i++) scc_list[scc[i]].push_back(i);     for (int i = 0; i < ncc; i++)       if (par_scc[i].empty()) source_scc.push(i);     int cur_scc = source_scc.top();     int cur_i = 0;     int cur_size = scc_list[cur_scc].size();     source_scc.pop();     int nxt_scc, nxt_i, nxt_size;     while (!source_scc.empty()) {       nxt_scc = source_scc.top();       nxt_i = 0;       nxt_size = scc_list[nxt_scc].size();       source_scc.pop();       while (cur_i < cur_size && nxt_i < nxt_size) {         if (!get_dir(scc_list[cur_scc][cur_i], scc_list[nxt_scc][nxt_i])) {           swap(cur_scc, nxt_scc);           swap(cur_i, nxt_i);           swap(cur_size, nxt_size);         }         nxt_i++;       }       assert(nxt_i == nxt_size);       for (auto x : chi_scc[nxt_scc]) {         par_scc[x].erase(nxt_scc);         if (par_scc[x].empty()) source_scc.push(x);       }     }     printf( ! %d n , scc_list[cur_scc][cur_i] + 1);     fflush(stdout);     return 0;   }   