#include #include #define rep(i, l, n) for (int i = (l); i < (n); i++) #define max(p, q) ((p) > (q) ? (p) : (q)) using namespace std; using namespace atcoder; using ll = long long; template using V = vector; template using VV = V >; int bool_sum(V&a) { int res = 0; rep(i, 0, a.size()) { if (a[i]) { res++; } } return res; } VV SCC_to_DAG(int n, VV&route, VV&scc) { VV dag(scc.size(), V(0)); V group(n); rep(i, 0, scc.size()) { rep(j, 0, scc[i].size()) { group[scc[i][j]] = i; } } rep(i, 0, n) { rep(j, 0, route[i].size()) { int a = group[i]; int b = group[route[i][j]]; if (a != b) { dag[a].push_back(b); } } } return dag; } int main(void) { int n, m; cin >> n >> m; VV route(n, V(0)); scc_graph ss(n); rep(i, 0, m) { int a, b; cin >> a >> b; a--; b--; ss.add_edge(a, b); route[a].push_back(b); } VV scc = ss.scc(); if (scc.size() <= 1) { cout << 0 << endl; return 0; } VV dag = SCC_to_DAG(n, route, scc); int ds = dag.size(); V source(ds, true); V sink(ds, true); rep(i, 0, ds) { rep(j, 0, dag[i].size()) { source[i] = sink[dag[i][j]] = false; } } int ans = max(bool_sum(source), bool_sum(sink)); cout << ans << endl; return 0; }