#include <bits/stdc++.h>
using namespace std;
const int MAX_N = (int)(1e5) + 10;
struct DSU {
  int father[MAX_N];
  DSU() {}
  DSU(int n) {
    for (int i = 0; i < n; i++) {
      father[i] = i;
    }
  }
  int find(int a) {
    int ret = a;
    while (father[ret] != ret) ret = father[ret];
    while (father[a] != a) {
      int b = a;
      a = father[a];
      father[b] = ret;
    }
    return ret;
  }
  void merge(int a, int b) { father[find(a)] = father[find(b)]; }
};
int n, m;
bool circle[MAX_N];
vector<int> edge[MAX_N];
int degree[MAX_N];
void add_edge(int a, int b) {
  edge[a].push_back(b);
  degree[b]++;
}
void bfs(int node_num, vector<int> edge[]) {
  queue<int> q;
  for (int i = 0; i < node_num; i++) {
    if (degree[i] == 0) {
      q.push(i);
    }
  }
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < (int)edge[u].size(); i++) {
      int v = edge[u][i];
      if (degree[v] == 0) {
        continue;
      }
      degree[v]--;
      if (degree[v] == 0) {
        q.push(v);
      }
    }
  }
}
int main() {
  scanf("%d%d", &n, &m);
  DSU dsu = DSU(n);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    add_edge(a, b);
    dsu.merge(a, b);
  }
  bfs(n, edge);
  for (int i = 0; i < n; i++) {
    if (degree[i]) {
      circle[dsu.find(i)] = true;
    }
  }
  int ans = n;
  for (int i = 0; i < n; i++) {
    if (dsu.father[i] == i && !circle[i]) {
      ans--;
    }
  }
  printf("%d\n", ans);
  return 0;
}
