//In the name of Allah (swt)
/*


 T sort / plano ax
 == [g o t c p]
// 我爱雨，花，食物，空气，水，都赞美真主   由 埃姆兰 制造


 upper_bound = find the last positon where n could be inserted
 lower_boudn = find the first position where n could be inserted
 lambda = [](int x){return x<10;}



 STL Algorithm Non- modifying----
--------------------------------

 vector<int> vec = {9,60,90,8,45,87,90,69,55,7};

    --- 1 counting
 int n = count(vec.begin(),vec.end(),69); // 2
 int m = count_if(vec.begin(),vec.end(),[](int x){return x<10;});//3 ->9,7,8

    --- 2 Min and Max
 itr = max_element(vec.begin(),vec.end()); // 90
//it returns the first max value

 itr = max_element(vec.begin(),vec.end(),[](int x,int y){return (x%10)<(y%10);});// 9
// which number has the biggest last digit---
...Most Algorithms have a simple form and a generalized form

itr = min_element(vec.begin(),vec.end()); // 7
// generalized form : min_element()

pair_of_itr = minmax_element(vec.begin(),vec.end(),[](int x,int y){return (x%10)<(y%10);}); //60 69

    ...3 linear search (used when the data is not sorted
// return the first match
 itr = find(vec.begin(),v.end(),

 itr = find_if(vec.begin(),vec.end(),[](int x){return x>80;});

 itr = find_if_not(vec.begin(),vec.end(),[](int x){return x>80;});

 itr = search_n(vec.begin(),vec.end(),2,69);
//Generalized form: search_n();

//search subrange
 vector<int> sub = {45,87,90};

 itr = search(vec.begin(),vec.end(),sub.begin(),sub.end());
        // search first subrange
 itr = find_end(vec.begin(),vec.end(),sub.begin(),sub.end());
........// search last subrange
//     generalized form: search(), fidn_end()

....Search any_of
 vector<int> items = {87,69};
 itr = find_first_of(vec.begin(),vec.end(),items.begin(),items.end());
      // Search any one of the item in items
 itr = find_first_of(vec.begin(),vec.end(),items.begin(),items.end(),[](int x,int y){return x==y*4});
 //     search any item in items that satisfy: x==y*4

// Search Adjacent
itr = adjacent_find(vec.begin(),vec.end()); // find two adjacent that are same
itr = adjacent_find(vec.begin(),vec.end(),[](int x,int y){return x==y*4}); // find two adjacent that are same
//           find two adjacent items that satisfy : s==y*4

//    4


//    5 check Attributes
is_sorted(vec.begin(),vec.end());//check if vec is sorted

itr = is_sorted_until(vec.begin(),vec.end());
// itr points to first place to where elements are no longer sorted
// generalizedforms: is_sorted(), is_sorted_until()

is_partitioned(vec.begin(),vec.end())[](int x){return x>80;});
// check if vec is partitioned according to the condition of (x>80)

if_heap(vec.begin(),vec.end()); // check if vec is a heap
itr = is_heap_until(vec.begin(),vec.end());
// find the first place where it is no longer a heap
//

//    All Any None
all_of(vec.begin(),vec.end(),[](int x){return x>80;});
// If any of vec is bigger than 80

any_of(vec.begin(),vec.end(),[](int x){return x>80});
//if any of vec is bigger than 80

none_of(vec.begin(),vec.end(),[](int x){return x>80;});
// if none of vec is bigger than 80

*/


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define endl "\n"
#define int long long
int temp[2005]={0};
vector<vector<int>>G;
void dfs(int v)
{
    if(temp[v]==1)return;
    temp[v]=1;
    for(auto vv:G[v]){
        dfs(vv);
    }
}


void kick()
{
    int n,m;
    cin>>n>>m;
    G.resize(n);

    for (int i=0; i<m ; i++)
    {
        int x,y;
        cin>>x>>y;
       G[x-1].pb(y-1);
    }
    int ans = 0;

    for (int i=0; i<n ; i++)
    {
        for(int j=0; j<n; j++)temp[j]=0;

        //temp[i]=1;
        dfs(i);
        for (int j=0; j<n ; j++)
        {
            if(temp[j]==1)ans++;
        }

    }

    cout<<ans<<endl;

}
int32_t main()

{


        kick();

    }



#include<bits/stdc++.h>
#define int long long
#define ll int
#define itn int
#define ld long double
#define all(c) c.begin(),c.end()
#define vi vector<int>
#define vvi vector<vector<int>>
#define pii pair<int,int>
#define rep(i, n) for(int  i = 0 ; i < n ; i++ )
#define repu(i, a, b) for(int i = a; i <=b; ++i)
#define repd(i, a, b) for(int i = a; i >=b; --i)
#define trav(a, x) for(auto& a : x)
#define sz(x) (int)(x).size()
#define fst first
#define snd second
#define mp make_pair
#define pb push_back

using namespace std;

const long long MOD = 1000000007;
void dfs(int root, vvi &adj, vi& vis){
    if(vis[root]) return;
    vis[root]=1;
    trav(x,adj[root]){
        if(!vis[x]) dfs(x,adj,vis);
    }
}

void solve()
{
    int n, m;
    cin >> n >> m;

    vvi adj(n+1);
    rep(i,m){
        int x,y;
        cin >> x >> y;
        adj[x].pb(y);
    }
    int ans = 0;
    repu(i,1,n){
        vi vis(n+1,0);
        dfs(i,adj,vis);
        int tmp  = 0;
        trav(x, vis){
            tmp+=x;
        }
        ans += tmp;
    }
    cout << ans << endl;
}

signed main(){
    
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif

    ll t = 1;
    // cin >> t;
    rep(z,t){
        solve();
    }

    cerr << "Time : " << (double)clock() / (double)CLOCKS_PER_SEC << "s\n";
    
    return 0; 
}