#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m;
vector<long long> g[N];
vector<long long> rg[N];
vector<long long> vs;
bool used[N];
int cmp[N], cmpsize[N];
void add_edge(int from, int to) {
  g[from].push_back(to);
  rg[to].push_back(from);
}
void dfs(int v) {
  used[v] = 1;
  for (int i = 0; i < (((int)(g[v]).size())); i++) {
    if (!used[g[v][i]]) dfs(g[v][i]);
  }
  vs.push_back(v);
}
void rdfs(int v, int k) {
  used[v] = 1;
  cmp[v] = k;
  for (int i = 0; i < (((int)(rg[v]).size())); i++) {
    if (!used[rg[v][i]]) rdfs(rg[v][i], k);
  }
}
int scc() {
  memset(used, 0, sizeof(used));
  vs.clear();
  for (int v = 0; v < (n); v++) {
    if (!used[v]) dfs(v);
  }
  memset(used, 0, sizeof(used));
  int k = 0;
  for (int i = ((int)(vs).size()) - 1; i >= 0; i--) {
    if (!used[vs[i]]) rdfs(vs[i], k++);
  }
  return k;
}
int dfs2(int v) {
  used[v] = 1;
  int res = cmpsize[cmp[v]] == 1;
  for (int i = 0; i < (((int)(g[v]).size())); i++)
    if (!used[g[v][i]]) {
      res &= dfs2(g[v][i]);
    }
  for (int i = 0; i < (((int)(rg[v]).size())); i++)
    if (!used[rg[v][i]]) {
      res &= dfs2(rg[v][i]);
    }
  return res;
}
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 0; i < (m); i++) {
    int a, b;
    cin >> a >> b;
    add_edge(a - 1, b - 1);
  }
  scc();
  memset(cmpsize, 0, sizeof(cmpsize));
  for (int i = 0; i < (n); i++) {
    cmpsize[cmp[i]]++;
  }
  memset(used, 0, sizeof(used));
  int ans = n;
  for (int i = 0; i < (n); i++)
    if (!used[i]) {
      ans -= dfs2(i);
    }
  cout << ans << endl;
}
