#include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; static const double EPS = 1e-9; static const double PI = acos(-1.0); #define REP(i, n) for (int i = 0; i < (int)(n); i++) #define FOR(i, s, n) for (int i = (s); i < (int)(n); i++) #define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++) #define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++) #define MEMSET(v, h) memset((v), h, sizeof(v)) typedef int Weight; struct Edge { int src; int dest; Weight weight; Edge(int src, int dest, Weight weight) : src(src), dest(dest), weight(weight) {;} bool operator<(const Edge &rhs) const { if (weight != rhs.weight) { return weight > rhs.weight; } if (src != rhs.src) { return src < rhs.src; } return dest < rhs.dest; } }; typedef vector Edges; typedef vector Graph; typedef vector Array; typedef vector Matrix; void PrintMatrix(const Matrix &matrix) { for (int y = 0; y < (int)matrix.size(); y++) { for (int x = 0; x < (int)matrix[y].size(); x++) { printf("%d ", matrix[y][x]); } puts(""); } } void SccDfs(const Graph &g, int from, vector &visit, vector &st) { visit[from] = 1; for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) { if (visit[it->dest]) { continue; } SccDfs(g, it->dest, visit, st); } st.push_back(from); } vector > Scc(const Graph &g) { const int n = g.size(); vector > ret; Graph revg(n); for (int i = 0; i < n; i++) { for (Edges::const_iterator it = g[i].begin(); it != g[i].end(); it++) { revg[it->dest].push_back(Edge(it->dest, i, it->weight)); } } vector st; vector visit(n, 0); for (int i = 0; i < n; i++) { if (visit[i]) { continue; } SccDfs(g, i, visit, st); } visit = vector(n, 0); for (int i = n - 1; i >= 0; i--) { int index = st[i]; if (visit[index]) { continue; } vector nret; SccDfs(revg, index, visit, nret); ret.push_back(nret); } return ret; } int group[10000]; Graph g; int main() { int n, m; while (scanf("%d %d", &n, &m) > 0 && n > 0) { g = Graph(n); REP(i, m) { int from, to; scanf("%d %d", &from, &to); from--; to--; g[from].push_back(Edge(from, to, 0)); } int ans = 0; vector > scc = Scc(g); REP(i, scc.size()) { FORIT(it, scc[i]) { group[*it] = i; } } FORIT(it1, scc) { if (it1->size() == 1) { continue; } ans += 1 - it1->size(); FORIT(it2, *it1) { int from = *it2; FORIT(it3, g[from]) { int to = it3->dest; ans += group[from] == group[to]; } } } printf("%d\n", ans); } }