#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
const int dir_4[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
const int dir_8[8][2] = {{1, 0},  {1, 1},   {0, 1},  {-1, 1},
                         {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};
const int kaijou[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
int par[150010], r[150010], lar[150010];
void init() {
  for (int i = 0; i < 150010; i++) {
    par[i] = i;
    r[i] = 0;
    lar[i] = 1;
  }
}
int find(int x) {
  if (x == par[x]) return x;
  return par[x] = find(par[x]);
}
bool same(int x, int y) { return find(x) == find(y); }
void unit(int x, int y) {
  if (same(x, y)) return;
  x = find(x);
  y = find(y);
  if (r[x] < r[y]) {
    par[x] = y;
    lar[y] += lar[x];
  } else {
    par[y] = x;
    lar[x] += lar[y];
    if (r[x] == r[y]) r[x]++;
  }
}
int n, m;
vector<int> G[100010];
vector<int> rG[100010];
vector<int> vec[100010];
vector<int> vs;
bool used[100010];
void dfs(int v) {
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    if (!used[G[v][i]]) dfs(G[v][i]);
  }
  vs.push_back(v);
}
int cnt(int v) {
  vs.clear();
  for (int i = 0; i < 100010; i++) used[i] = false;
  for (int i = 0; i < vec[v].size(); i++) {
    if (!used[vec[v][i]]) {
      dfs(vec[v][i]);
    }
  }
  for (int i = 0; i < 100010; i++) used[i] = false;
  for (int i = vs.size() - 1; i > 0; i--) {
    int p = vs[i];
    for (int j = 0; j < rG[p].size(); j++) {
      if (!used[rG[p][j]]) return lar[v];
    }
    used[p] = true;
  }
  return lar[v] - 1;
}
int main() {
  init();
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    G[a].push_back(b);
    rG[b].push_back(a);
    unit(a, b);
  }
  for (int i = 1; i <= n; i++) {
    vec[find(i)].push_back(i);
  }
  int ret = 0;
  bool used_[100010];
  for (int i = 0; i < 100010; i++) used_[i] = false;
  for (int i = 1; i <= n; i++) {
    if (par[i] == i) {
      ret += cnt(i);
      used_[i] = true;
    }
  }
  printf("%d\n", ret);
}
