#include <bits/stdc++.h>
using namespace std;
vector<int> adj[(100005)];
int N, M;
pair<int, int> edges[(100005)];
int num_comp;
int comp[(100005)];
int num_members[(100005)];
int visited[(100005)];
bool cycle[(100005)];
void dfs(int at) {
  num_members[num_comp]++;
  comp[at] = num_comp;
  visited[at] = true;
  for (int v : adj[at]) {
    if (!visited[v]) {
      dfs(v);
    }
  }
}
void dfs2(int at) {
  visited[at] = 1;
  for (int v : adj[at]) {
    if (visited[v] == 0) {
      dfs2(v);
    } else if (visited[v] == 1) {
      cycle[comp[at]] = true;
    }
  }
  visited[at] = 2;
}
int main() {
  int u, v;
  scanf("%d %d", &N, &M);
  for (int(i) = 0; (i) < (M); ++(i)) {
    scanf("%d %d", &u, &v);
    edges[i] = {u, v};
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (int i = 1; i <= N; i++) {
    if (!visited[i]) {
      num_comp++;
      dfs(i);
    }
  }
  for (int i = 1; i <= N; i++) adj[i].clear();
  for (int(i) = 0; (i) < (M); ++(i)) {
    adj[edges[i].first].push_back(edges[i].second);
  }
  memset(visited, 0, sizeof(visited));
  for (int i = 1; i <= N; i++) {
    if (!visited[i]) {
      dfs2(i);
    }
  }
  int ans = 0;
  for (int i = 1; i <= num_comp; i++) {
    if (cycle[i])
      ans += num_members[i];
    else
      ans += num_members[i] - 1;
  }
  printf("%d\n", ans);
  return 0;
}
