#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:36777216")
using namespace std;
const int N = 2e5 + 7;
const int M = N * N * 2;
const int MOD = 1e9 + 7;
const int INF = 1e9 + 7;
const double EPS = 1e-8;
struct Edge {
  int v, next;
} e[N << 1];
int first[N], ecnt;
void Addedge(int u, int v) {
  e[++ecnt].v = v, e[ecnt].next = first[u], first[u] = ecnt;
}
int f[N], deg[N], n, m, u, v, tot;
int getf(int x) { return f[x] == x ? f[x] : f[x] = getf(f[x]); }
queue<int> Q;
vector<int> vec[N];
int main() {
  cin >> n >> m;
  tot = n;
  memset(first, -1, sizeof(first));
  ecnt = -1;
  for (int i = 1; i <= n; i++) {
    f[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &u, &v);
    Addedge(u, v);
    deg[v]++;
    int fu = getf(u), fv = getf(v);
    if (fu == fv) continue;
    f[fu] = fv;
    tot--;
  }
  for (int i = 1; i <= n; i++) {
    if (deg[i] == 0) Q.push(i);
  }
  while (!Q.empty()) {
    int u = Q.front();
    Q.pop();
    for (int i = first[u]; i != -1; i = e[i].next) {
      int v = e[i].v;
      deg[v]--;
      if (deg[v] == 0) Q.push(v);
    }
  }
  int ans = n - tot;
  for (int i = 1; i <= n; i++) {
    int ff = getf(i);
    vec[ff].push_back(i);
  }
  for (int i = 1; i <= n; i++) {
    if (vec[i].size() == 0) continue;
    for (int j = 0; j < vec[i].size(); j++) {
      if (deg[vec[i][j]] != 0) {
        ans++;
        break;
      }
    }
  }
  printf("%d\n", ans);
}
