#include <bits/stdc++.h>
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
using namespace std;
const int N = 3e5 + 5;
const long long mod = 1e9 + 7;
const long long INF = 1e18;
const int INFi = 0x7f7f7f7f;
long long test = 1, n, m, vis[N], rec[N], cyc[N], p[N], sz[N];
vector<long long> adj[N];
stack<long long> Stack;
void make(long long n) {
  for (int i = 1; i <= n; i++) {
    p[i] = i;
    sz[i] = 1;
  }
}
int find(long long x) { return (p[x] == x) ? x : p[x] = find(p[x]); }
void merge(long long x, long long y) {
  long long a = find(x);
  long long b = find(y);
  if (a != b) {
    if (sz[a] >= sz[b]) swap(a, b);
    p[a] = b;
    sz[b] += sz[a];
  }
}
void TSUtil(int v) {
  vis[v] = 1;
  for (auto it : adj[v])
    if (!vis[it]) TSUtil(it);
  Stack.push(v);
}
void TS() {
  for (int i = 1; i <= n; i++)
    if (!vis[i]) TSUtil(i);
  while (Stack.empty() == 0) {
    cout << Stack.top() << " ";
    Stack.pop();
  }
}
bool CycleUtil(int v) {
  if (vis[v] == 0) {
    vis[v] = 1, rec[v] = 1;
    for (auto it : adj[v]) {
      if (!vis[it] && CycleUtil(it))
        return 1;
      else if (rec[it])
        return 1;
    }
  }
  rec[v] = 0;
  return 0;
}
void Cycle() {
  for (int i = 1; i <= n; i++)
    if (CycleUtil(i)) cyc[find(i)] = 1;
}
void solve() {
  cin >> n >> m;
  make(n);
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    merge(u, v);
  }
  Cycle();
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    if (find(i) == i) {
      if (cyc[i] == 1)
        ans += sz[i];
      else
        ans += sz[i] - 1;
    }
  }
  cout << ans << " "
       << "\n";
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed;
  cout << setprecision(10);
  ;
  for (int i = 1; i <= test; i++) {
    solve();
  }
}
