#include <bits/stdc++.h>   using namespace std;   using ll = int64_t;   template <typename T, typename U>   ostream& operator<<(ostream& _s, pair<T, U> _t) {     _s <<  (  << _t.first <<  ,  << _t.second <<  ) ;     return _s;   }   template <typename T, typename U>   istream& operator>>(istream& _s, pair<T, U>& _t) {     _s >> _t.first >> _t.second;     return _s;   }   template <typename T>   ostream& operator<<(ostream& _s, vector<T> _t) {     for (int i = 0; i < (int)(_t.size()); i++) _s << (i ?     :   ) << _t[i];     return _s;   }   template <typename T>   istream& operator>>(istream& _s, vector<T>& _t) {     for (int i = 0; i < (int)(_t.size()); i++) _s >> _t[i];     return _s;   }   vector<int> val, comp, z, cont;   int Time, ncomps;   template <class G, class F>   int dfs(int j, G& g, F f) {     int low = val[j] = ++Time, x;     z.push_back(j);     for (auto& e : g[j])       if (comp[e] < 0) low = min(low, val[e] ?: dfs(e, g, f));     if (low == val[j]) {       do {         x = z.back();         z.pop_back();         comp[x] = ncomps;         cont.push_back(x);       } while (x != j);       f(cont);       cont.clear();       ncomps++;     }     return val[j] = low;   }   template <class G, class F>   void scc(G& g, F f) {     int n = g.size();     val.assign(n, 0);     comp.assign(n, -1);     Time = ncomps = 0;     for (int i = 0; i < (int)(n); i++)       if (comp[i] < 0) dfs(i, g, f);   }   void tassert(bool cond) {     if (!cond) {       while (1 < 2) {       }     }   }   void answer(int x) {     cout <<  !   << (x + 1) << endl;     cout << flush;     exit(0);   }   bool ask(int a, int b) {     cout <<  ?   << (a + 1) <<     << (b + 1) << endl;     cout << flush;     int res;     cin >> res;     if (res == -1) {       exit(123);     }     return bool(res);   }   int main() {     int n, m;     cin >> n >> m;     vector<vector<int>> g(n);     for (int i = 0; i < (int)(m); i++) {       int x, y;       cin >> x >> y;       g[x - 1].push_back(y - 1);     }     vector<vector<int>> comps;     scc(g, [&](vector<int>& v) { comps.push_back(v); });     vector<unordered_set<int>> cg(ncomps);     for (int a = 0; a < (int)(n); a++) {       for (int b : g[a]) {         if (comp[a] != comp[b]) {           cg[comp[a]].insert(comp[b]);         }       }     }     vector<int> indeg(ncomps, 0);     for (int aa = 0; aa < (int)(ncomps); aa++) {       for (int bb : cg[aa]) {         indeg[bb]++;       }     }     unordered_set<int> heads;     for (int aa = 0; aa < (int)(ncomps); aa++) {       if (indeg[aa] == 0) {         heads.insert(aa);       }     }     int head = *heads.begin();     int cap = comps[head].back();     comps[head].pop_back();     auto update = [&](int aa) {       if (comps[aa].size() == 0) {         heads.erase(aa);         for (int bb : cg[aa]) {           tassert(comps[bb].size() > 0);           indeg[bb]--;           if (indeg[bb] == 0) {             heads.insert(bb);           }         }       }     };     while (true) {       assert(heads.size());       if (heads.size() == 1) {         answer(cap);       }       auto head2it = heads.begin();       if (head == (*head2it)) {         head2it++;       }       int head2 = *head2it;       tassert(!cg[head].count(head2));       int cap2 = comps[head2].back();       comps[head2].pop_back();       bool ok = ask(cap, cap2);       if (!ok) {         update(head);         head = head2;         cap = cap2;       } else {         update(head2);       }     }   }