#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
ostream& operator<<(ostream& out, pair<T1, T2> a) {
  return (out << "(" << a.first << "; " << a.second << ")");
}
const int nmax = 1000 * 1000;
const int inf = 1000 * 1000 * 1000;
const int mod = 1000 * 1000 * 1000 + 7;
const long long infl = 1000ll * 1000ll * 1000ll * 1000ll * 1000ll * 1000ll;
int n, m, x, y, used1[nmax], answer = 0;
vector<int> a[nmax], b[nmax], cur;
bool f, used[nmax];
void dfs1(int v) {
  used[v] = true;
  cur.push_back(v);
  for (int i = 0; i < (int)a[v].size(); i++)
    if (!used[a[v][i]]) dfs1(a[v][i]);
}
void dfs2(int v) {
  used1[v] = 1;
  for (int i = 0; i < (int)b[v].size(); i++)
    if (used1[b[v][i]] == 0)
      dfs2(b[v][i]);
    else if (used1[b[v][i]] == 1)
      f = true;
  used1[v] = 2;
}
int main() {
  assert(scanf("%d%d", &n, &m));
  for (int i = 0; i < m; i++) {
    assert(scanf("%d%d", &x, &y));
    x--, y--;
    a[x].push_back(y);
    a[y].push_back(x);
    b[x].push_back(y);
  }
  for (int i = 0; i < n; i++) {
    if (!used[i]) {
      cur.clear();
      dfs1(i);
      f = false;
      for (int j = 0; j < (int)cur.size(); j++)
        if (used1[cur[j]] == 0) dfs2(cur[j]);
      answer += (int)cur.size() - 1;
      if (f) answer++;
    }
  }
  printf("%d\n", answer);
}
