#include <iostream>
#include <vector>
#include <set>
using namespace std;
struct vertex{
int used,colour;
vector<int>graph,graph_transposed;
};
void dfs_g(int v, vector<vertex>&components, vector<int>&list){
components[v].used = 1;
for (int i = 0; i < components[v].graph.size(); i++){
if(components[components[v].graph[i]].used!=1) dfs_g(components[v].graph[i],components,list);
}
list.push_back(v);
}
void dfs_tg(int v, int color, vector<vertex>&components){
components[v].used=2;
components[v].colour=color;
for (int i=0; i<components[v].graph_transposed.size(); i++){
if (components[components[v].graph_transposed[i]].used != 2)dfs_tg(components[v].graph_transposed[i],color,components);
}
}
int main(){
int n,m,color=0,answer=0;
cin>>n>>m;
vector<int>list(n);
vector<vertex>components(n);
set<int>ribs[10000];
for(int i=0; i<m; i++){
int a,b;
cin>>a>>b;
components[a-1].graph.push_back(b-1);
components[b-1].graph_transposed.push_back(a-1);
}
for (int i=0; i<n; i++){
if (components[i].used!=1)dfs_g(i,components,list);
}
for (int i=list.size()-1; i>=0; i--){
if (components[list[i]].used != 2){
dfs_tg(list[i], color, components);
color++;
}
}
for(int i=0; i<n; i++){
for(int j=0; j<components[i].graph.size(); j++){
if(components[i].colour!=components[components[i].graph[j]].colour){
ribs[components[i].colour].insert(components[components[i].graph[j]].colour);
}
}
}
for(int i=0; i<10000; i++)answer+=ribs[i].size();
cout<<answer;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8c2V0PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCB2ZXJ0ZXh7CQkJCiAgICBpbnQgdXNlZCxjb2xvdXI7CiAgICB2ZWN0b3I8aW50PmdyYXBoLGdyYXBoX3RyYW5zcG9zZWQ7Cn07Cgp2b2lkIGRmc19nKGludCB2LCB2ZWN0b3I8dmVydGV4PiZjb21wb25lbnRzLCB2ZWN0b3I8aW50PiZsaXN0KXsKICAgIGNvbXBvbmVudHNbdl0udXNlZCA9IDE7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IGNvbXBvbmVudHNbdl0uZ3JhcGguc2l6ZSgpOyBpKyspewogICAgICAgIGlmKGNvbXBvbmVudHNbY29tcG9uZW50c1t2XS5ncmFwaFtpXV0udXNlZCE9MSkgZGZzX2coY29tcG9uZW50c1t2XS5ncmFwaFtpXSxjb21wb25lbnRzLGxpc3QpOwogICAgfQogICAgbGlzdC5wdXNoX2JhY2sodik7Cn0KCnZvaWQgZGZzX3RnKGludCB2LCBpbnQgY29sb3IsIHZlY3Rvcjx2ZXJ0ZXg+JmNvbXBvbmVudHMpewogICAgY29tcG9uZW50c1t2XS51c2VkPTI7CiAgICBjb21wb25lbnRzW3ZdLmNvbG91cj1jb2xvcjsKICAgIGZvciAoaW50IGk9MDsgaTxjb21wb25lbnRzW3ZdLmdyYXBoX3RyYW5zcG9zZWQuc2l6ZSgpOyBpKyspewogICAgICAgIGlmIChjb21wb25lbnRzW2NvbXBvbmVudHNbdl0uZ3JhcGhfdHJhbnNwb3NlZFtpXV0udXNlZCAhPSAyKWRmc190Zyhjb21wb25lbnRzW3ZdLmdyYXBoX3RyYW5zcG9zZWRbaV0sY29sb3IsY29tcG9uZW50cyk7CiAgICB9Cn0KCmludCBtYWluKCl7CglpbnQgbixtLGNvbG9yPTAsYW5zd2VyPTA7CiAgICBjaW4+Pm4+Pm07Cgl2ZWN0b3I8aW50Pmxpc3Qobik7Cgl2ZWN0b3I8dmVydGV4PmNvbXBvbmVudHMobik7CglzZXQ8aW50PnJpYnNbMTAwMDBdOwogICAgZm9yKGludCBpPTA7IGk8bTsgaSsrKXsKICAgICAgICBpbnQgYSxiOwogICAgICAgIGNpbj4+YT4+YjsKICAgICAgICBjb21wb25lbnRzW2EtMV0uZ3JhcGgucHVzaF9iYWNrKGItMSk7CiAgICAgICAgY29tcG9uZW50c1tiLTFdLmdyYXBoX3RyYW5zcG9zZWQucHVzaF9iYWNrKGEtMSk7CiAgICB9CgogICAgZm9yIChpbnQgaT0wOyBpPG47IGkrKyl7CiAgICAgICAgaWYgKGNvbXBvbmVudHNbaV0udXNlZCE9MSlkZnNfZyhpLGNvbXBvbmVudHMsbGlzdCk7CiAgICB9CiAgICBmb3IgKGludCBpPWxpc3Quc2l6ZSgpLTE7IGk+PTA7IGktLSl7CiAgICAgICAgaWYgKGNvbXBvbmVudHNbbGlzdFtpXV0udXNlZCAhPSAyKXsKICAgICAgICAJZGZzX3RnKGxpc3RbaV0sIGNvbG9yLCBjb21wb25lbnRzKTsKICAgICAgICAJY29sb3IrKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaW50IGk9MDsgaTxuOyBpKyspewogICAgICAgIGZvcihpbnQgaj0wOyBqPGNvbXBvbmVudHNbaV0uZ3JhcGguc2l6ZSgpOyBqKyspewogICAgICAgICAgICBpZihjb21wb25lbnRzW2ldLmNvbG91ciE9Y29tcG9uZW50c1tjb21wb25lbnRzW2ldLmdyYXBoW2pdXS5jb2xvdXIpewogICAgICAgICAgICAgICAgcmlic1tjb21wb25lbnRzW2ldLmNvbG91cl0uaW5zZXJ0KGNvbXBvbmVudHNbY29tcG9uZW50c1tpXS5ncmFwaFtqXV0uY29sb3VyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGZvcihpbnQgaT0wOyBpPDEwMDAwOyBpKyspYW5zd2VyKz1yaWJzW2ldLnNpemUoKTsKICAgIGNvdXQ8PGFuc3dlcjsKICAgIHJldHVybiAwOwp9