#include #include #include using namespace std; struct Graph { int n; std::vector> g; Graph(){} Graph(int n) : n(n){ g.resize(n); } void add_edge(int from, int to){ g[from].push_back(to); } }; struct SCC //StronglyConnectedComponents { int n; int k; std::vector> g, rg; std::vector used; std::vector cmp; std::vector vs; SCC(){} SCC(int n) : n(n){ g.resize(n); rg.resize(n); used.resize(n); cmp.resize(n); } void add_edge(int from, int to){ g[from].push_back(to); rg[to].push_back(from); } void dfs(int u){ used[u] = true; for(int v : g[u]){ if(!used[v]) dfs(v); } vs.push_back(u); } void rdfs(int u, int k){ used[u] = true; cmp[u] = k; for(int v : rg[u]){ if(!used[v]) rdfs(v, k); } } int decomposition(){ for(int i = 0; i < n; i++) used[i] = false; for(int i = 0; i < n; i++){ if(!used[i]) dfs(i); } for(int i = 0; i < n; i++) used[i] = false; k = 0; for(int i = n - 1; i >= 0; i--){ if(!used[vs[i]]){ rdfs(vs[i], k); k++; } } return k; } int decomposition(Graph &dag){ k = decomposition(); dag.n = k; dag.g.resize(k); std::map, bool> mp; for(int u = 0; u < n; u++){ for(int v : g[u]){ if(!mp[std::pair (cmp[u], cmp[v])] && cmp[u] != cmp[v]){ mp[std::pair (cmp[u], cmp[v])] = true; dag.add_edge(cmp[v], cmp[u]); } } } return k; } }; int main() { int n, m; cin >> n >> m; SCC g(n); for(int i = 0; i < m; i++){ int a, b; cin >> a >> b; a--; b--; g.add_edge(a, b); } Graph h; int k = g.decomposition(h); if(k == 1){ cout << 0 << endl; return 0; } int d[100005]{0}; for(int u = 0; u < k; u++){ for(int v : h.g[u]) d[v]++; } int c0 = 0, c1 = 0; for(int u = 0; u < k; u++){ if(h.g[u].size() == 0) c0++; if(d[u] == 0) c1++; } cout << max(c0, c1) << endl; }