#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;

using ll = long long;

const int INF = 1001001001;
const ll INF_LL = 1001001001001001001LL;

vector<int> BFS(vector<vector<int>> &Graph,int iv,int n){
  vector<int> dist(n,-1);
  queue<int> q;

  dist[iv]=0;
  q.push(iv);
  while(!q.empty()){
    int v = q.front();q.pop();
    //if(dist[v]!=-1) continue;
    
    for(auto nv : Graph[v]){
      if(dist[nv]!=-1) continue;
      
      dist[nv]=dist[v]+1;
      q.push(nv);
    } 
  }
  return dist;
}

int main(void){
  int n,m; cin >> n >> m;
  vector<vector<int>> g(n);
  rep(i,m){
    int a,b; cin >> a >> b;
    a--;b--;
    g[a].push_back(b);
  }

  vector<int> d;

  ll ans = 0;
  rep(i,n){
    d = BFS(g,i,n);
    rep(j,n){
      if(d[j] != -1) ans++;
    }
  }

  cout << ans << endl;
  
  return 0;
}

#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;

int N, M;
map<int, vector<int>> G;

void get_input();
void solve();

void dfs(vector<bool> &seen, int v);

/**
 * @brief メイン処理.
 *
 * @return int 0
 */
int main() {
    // 標準入力を取得
    get_input();

    // 求解処理
    solve();

    return 0;
}

/**
 * @brief Get the input object
 *
 */
void get_input() {
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        int a, b;
        cin >> a >> b;
        G[a].push_back(b);
    }
}

/**
 * @brief 求解処理.
 *
 */
void solve() {
    int ans = 0;
    for (int i = 1; i <= N; i++) {
        vector<bool> seen(N);
        dfs(seen, i);
        ans += accumulate(seen.begin(), seen.end(), 0);
    }

    // 結果出力
    cout << ans << endl;
}

/**
 * @brief 深さ優先探索.
 *
 * @param seen 探索済みリスト
 * @param v ノード
 */
void dfs(vector<bool> &seen, int v) {
    if (seen[v - 1]) return;

    seen[v - 1] = true;
    for (int w : G[v]) {
        dfs(seen, w);
    }
}
