#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int SIZE = 1e6 + 10;
vector<int> e[SIZE];
vector<pair<int, int> > pp;
bool used[SIZE];
int id, order[SIZE], num;
void dfs(int x) {
  used[x] = 1;
  num++;
  for (int i = 0; i < (((int)(e[x]).size())); ++i) {
    int y = e[x][i];
    pp.push_back(make_pair(x, y));
    if (used[y]) continue;
    dfs(y);
  }
  order[x] = id++;
}
struct Union_Find {
  int d[SIZE];
  void init(int n) {
    for (int i = 0; i < (n); ++i) d[i] = i;
  }
  int find(int x) { return (x != d[x]) ? (d[x] = find(d[x])) : x; }
  bool uu(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return 0;
    d[x] = y;
    return 1;
  }
} U;
vector<int> gg[SIZE];
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  U.init(n);
  for (int i = 0; i < (m); ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    x--;
    y--;
    U.uu(x, y);
    e[x].push_back(y);
  }
  for (int i = 0; i < (n); ++i) gg[U.find(i)].push_back(i);
  int an = 0;
  for (int i = 0; i < (n); ++i) {
    if (((int)(gg[i]).size())) {
      pp.clear();
      num = 0;
      for (int k = 0; k < (((int)(gg[i]).size())); ++k)
        if (!used[gg[i][k]]) dfs(gg[i][k]);
      an += num - 1;
      bool suc = 1;
      for (int i = 0; i < (((int)(pp).size())); ++i) {
        if (order[pp[i].first] < order[pp[i].second]) suc = 0;
      }
      if (!suc) an++;
    }
  }
  printf("%d\n", an);
  return 0;
}
