#include <bits/stdc++.h>
using namespace std;
unsigned long long gcd(unsigned long long a, unsigned long long b) {
  return b ? gcd(b, a % b) : a;
}
unsigned long long mcm(unsigned long long a, unsigned long long b) {
  return a * b / gcd(a, b);
}
long long sq(long long a) { return a * a; }
long long pot(long long a, unsigned long long b) {
  return b ? sq(pot(a, b >> 1)) * (b & 1 ? a : 1) : 1;
}
long long potMod(long long a, unsigned long long b, unsigned long long m) {
  return b ? ((sq(potMod(a, b >> 1, m)) % m) * (b & 1 ? a : 1)) % m : 1;
}
unsigned long long roofLog2(int n) {
  unsigned long long r = 1;
  for (; r < n; r <<= 1)
    ;
  return r;
}
int n;
vector<int> graph[100005], db_graph[100005], seen;
bool db_visited[100005], visited[100005], trace[100005];
void dfs(int index) {
  if (!db_visited[index]) {
    db_visited[index] = true;
    seen.push_back(index);
    for (typeof((db_graph[index]).begin()) it = (db_graph[index]).begin();
         it != (db_graph[index]).end(); it++)
      dfs(*it);
  }
}
int dfs_cycle(int index) {
  if (trace[index]) return true;
  if (visited[index]) return false;
  trace[index] = visited[index] = true;
  int cant = 1;
  for (typeof((graph[index]).begin()) it = (graph[index]).begin();
       it != (graph[index]).end(); it++)
    if (dfs_cycle(*it)) return true;
  trace[index] = false;
  return false;
}
int main() {
  int m;
  cin >> n >> m;
  while ((m)--) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    graph[a].push_back(b);
    db_graph[a].push_back(b);
    db_graph[b].push_back(a);
  }
  int cant = 0;
  for (int i = (0); i < (n); i++)
    if (!db_visited[i]) {
      seen.clear();
      dfs(i);
      cant += seen.size();
      bool cycle = false;
      for (typeof((seen).begin()) it = (seen).begin(); it != (seen).end(); it++)
        if (!visited[*it] && dfs_cycle(*it)) {
          cycle = true;
          break;
        }
      if (!cycle) cant--;
    }
  cout << cant;
  return 0;
}
