#include // clang-format off using namespace std;constexpr int INF=1001001001;constexpr long long INFll=1001001001001001001;namespace viewer{template string f(T i){string s=(i==INF||i==INFll?"inf":to_string(i));s=string(max(0,3-int(s.size())),' ')+s;return s;} templateauto v(T&x,string end)->decltype(cerr<void v(const pair&p,string end="\n"){cerr<<"(";v(p.first,", ");v(p.second,")"+end);}templatevoid v(const tuple&t,string end="\n"){auto[a,b]=t;cerr<<"(";v(a,", ");v(b,")"+end);}templatevoid v(const tuple&t,string end="\n"){auto[a,b,c]=t;cerr<<"(";v(a,", ");v(b,", ");v(c,")"+end);}templatevoid v(const tuple&t,string end="\n"){auto[a,b,c,d]=t;cerr<<"(";v(a,", ");v(b,", ");v(c,", ");v(d,")"+end);} templatevoid v(const vector&vx,string);templateauto ve(int,const vector&vx)->decltype(cerr<auto ve(bool,const vector &vx){cerr << "{\n";for(const T&x:vx)cerr<<" ",v(x,",");cerr<<"}\n";}templatevoid v(const vector&vx, string){ve(0,vx);}templatevoid v(const deque&s,string e){vectorz(s.begin(),s.end());v(z,e);} templatevoid v(const set&s,string e){vectorz(s.begin(),s.end());v(z,e);}templatevoid v(const multiset&s,string e){vectorz(s.begin(),s.end());v(z,e);}templatevoid v(const unordered_set&s,string e){vectorz(s.begin(),s.end());v(z,e);}templatevoid v(const priority_queue&p,string e){priority_queueq=p;vectorz;while(!q.empty()){z.push_back(q.top());q.pop();}v(z,e);} templatevoid v(const map&m,string e){cerr<<"{"<<(m.empty()?"":"\n");for(const auto&kv:m){cerr<<" [";v(kv.first,"");cerr<<"] : ";v(kv.second,"");cerr<<"\n";}cerr<<"}"+e;}templatevoid _view(int n,string s,T&var){cerr<<"\033[1;32m"<void grid(T _){}void grid(const vector>&vvb){cerr<<"\n";for(const vector&vb:vvb){for(const bool&b:vb)cerr<<(b?".":"#");cerr<<"\n";}} void _debug(int,string){}templatevoid _debug(int n,string S,H h,T... t){int i=0,cnt=0;for(;iap;mint re=a;for(long long r=1;r, vector> topological_sort( const vector>& adj) { const int node_num = (int)adj.size(); vector indeg(node_num); for (int i = 0; i < node_num; i++) for (int to : adj[i]) ++indeg[to]; vector start_nodes, topological_ord; for (int i = 0; i < node_num; i++) if (indeg[i] == 0) start_nodes.push_back(i); vector start_nodes_for_ret = start_nodes; while (!start_nodes.empty()) { int p = start_nodes.back(); start_nodes.pop_back(); topological_ord.emplace_back(p); for (int to : adj[p]) if (--indeg[to] == 0) start_nodes.push_back(to); } return {topological_ord, start_nodes_for_ret}; } // -1 if the graph has a loop int longest_path_of_DAG(const vector>& adj) { auto [ord, start_nodes] = topological_sort(adj); if (ord.size() != adj.size()) return -1; vector dp(adj.size()); for (int v : ord) { for (int nv : adj[v]) { chmax(dp[nv], dp[v] + 1); } } return *max_element(dp.begin(), dp.end()); } int main() { cin.tie(0); ios::sync_with_stdio(false); int N, Q; cin >> N >> Q; vector> ABs(Q); for (int i = 0; i < Q; i++) { int A; int B; cin >> A >> B; A--; B--; ABs[i] = make_pair(A, B); } auto is_ok = [&](long long x) -> bool { // write here (変数名の衝突に要注意!!!) vector> adj(N); for (int i = 0; i < x; i++) { auto [a, b] = ABs[i]; adj[a].push_back(b); } auto [ord, sn] = topological_sort(adj); bool is_DAG = ((int)ord.size() == N); return !is_DAG; }; long long ok, ng; ok = Q; ng = 0; while (abs(ok - ng) > 1) { long long mid = (ok + ng) / 2; if (is_ok(mid)) { ok = mid; } else { ng = mid; } } if (ok == Q) { cout << -1 << endl; } else { cout << ok << endl; } return 0; }