#include <bits/stdc++.h>
using namespace std;
int id[300010], sz[300010], dg[300010];
vector<int> adj[300010], comp[300010];
void ufinit(int n) {
  for (int i = 0; i < (n); ++i) id[i] = i, sz[i] = 1;
}
int uffind(int i) {
  if (i == id[i]) return i;
  return id[i] = uffind(id[i]);
}
void ufunion(int v, int w) {
  v = uffind(v);
  w = uffind(w);
  if (v == w) return;
  if (sz[v] > sz[w]) swap(v, w);
  id[v] = w;
  if (sz[v] == sz[w]) sz[w]++;
}
int main() {
  int n, m;
  scanf(" %d %d", &n, &m);
  ufinit(n);
  for (int i = 0; i < (m); ++i) {
    int a, b;
    scanf(" %d %d", &a, &b);
    a--;
    b--;
    dg[a]++;
    adj[b].push_back(a);
    ufunion(a, b);
  }
  for (int i = 0; i < (n); ++i) comp[uffind(i)].push_back(i);
  int ans = 0;
  for (int i = 0; i < (n); ++i) {
    int sz = comp[i].size();
    if (!sz) continue;
    queue<int> q;
    int nvis = 0;
    for (int j = 0; j < (sz); ++j) {
      int x = comp[i][j];
      if (dg[x] == 0) {
        q.push(x);
      }
    }
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      nvis++;
      for (int j = 0; j < (adj[u].size()); ++j) {
        int pu = adj[u][j];
        dg[pu]--;
        if (dg[pu] == 0) {
          q.push(pu);
        }
      }
    }
    if (nvis == sz)
      ans += sz - 1;
    else
      ans += sz;
  }
  printf("%d\n", ans);
  return 0;
}
