#include <bits/stdc++.h>
#define maxe 500050
#define maxv 100050
using namespace std;
vector<int> G[maxe];
int n, m;
int cnts = 1;
int low[maxv];
int dfn[maxv];
int belong[maxv];
int s[maxv];
int top = 0;
int cnt = 0, tot = 0;
int num[maxv];
int outdegree[maxv];
bool vis[maxv];
void tarjan(int x) {
int c;
low[x] = dfn[x] = ++cnt;
s[++top] = x;
vis[x] = true;
for (int u = 0; u < G[x].size(); u++) {
c = G[x][u];
if (!dfn[c]) {
tarjan(c);
low[x] = min(low[x], low[c]);
} else if (vis[c]) {
low[x] = min(low[x], dfn[c]);
}
}
if (dfn[x] == low[x]) {
tot++;
c = -1;
while (x != c) {
c = s[top--];
belong[c] = tot;
num[tot]++;
vis[c] = false;
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
if (u == v)
continue;
G[u].push_back(v);
}
for (int i = 1; i <= n; i++) {
if (!dfn[i]) {
tarjan(i);
}
}
for (int i = 1; i <= n; i++) {
for (int u = 0; u < G[i].size(); u++) {
if (belong[G[i][u]] != belong[i]) {
outdegree[belong[i]]++;
}
}
}
int res = 0, ans;
for (int i = 1; i <= tot; i++) {
if (outdegree[i] == 0) {
res++;
ans = i;
}
}
cout << res;
return 0;
}