#include <bits/stdc++.h>
using namespace std;
stack<int> sk;
bool insk[100010], isok[100010];
int step, dfn[100010], low[100010], belong[100010], num[100010], tol;
struct Edge {
  int to, next;
} edge[200010];
int head[100010], tail;
void add(int from, int to) {
  edge[tail].to = to;
  edge[tail].next = head[from];
  head[from] = tail++;
}
void dfs(int from) {
  dfn[from] = low[from] = ++step;
  sk.push(from);
  insk[from] = 1;
  for (int i = head[from]; i != -1; i = edge[i].next) {
    int to = edge[i].to;
    if (dfn[to] == 0) {
      dfs(to);
      low[from] = min(low[from], low[to]);
    } else if (insk[to])
      low[from] = min(low[from], dfn[to]);
  }
  if (dfn[from] == low[from]) {
    int v;
    do {
      v = sk.top();
      sk.pop();
      insk[v] = 0;
      belong[v] = tol;
      num[tol]++;
    } while (v != from);
    if (num[tol] > 1) isok[tol] = 1;
    tol++;
  }
}
int pr[100010];
int seek(int v) { return pr[v] = v == pr[v] ? v : seek(pr[v]); }
int main() {
  int n, m;
  cin >> n >> m;
  memset(head, -1, sizeof(head));
  while (m--) {
    int a, b;
    cin >> a >> b;
    add(a, b);
  }
  for (int i = 1; i <= n; i++)
    if (!dfn[i]) dfs(i);
  for (int i = 0; i < tol; i++) pr[i] = i;
  int ans = 0;
  for (int i = 1; i <= n; i++)
    for (int j = head[i]; j != -1; j = edge[j].next) {
      int a = belong[i], b = belong[edge[j].to];
      a = seek(a);
      b = seek(b);
      if (a != b) {
        isok[a] |= isok[b];
        num[a] += num[b];
        pr[b] = a;
      }
    }
  for (int i = 0; i < tol; i++)
    if (pr[i] == i) ans += num[i] + (isok[i] ? 0 : -1);
  cout << ans;
}
