#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const long long INFLL = 1e18 + 1;
const int MAX = 200001;
const long long MOD = 1000000007;
long long inq(long long k, long long q) {
  if (q == 0) return 1;
  long long l = inq(k, q / 2);
  if (q % 2 == 0)
    return l * l % MOD;
  else
    return (l * l) % MOD * k % MOD;
}
long long gcd(long long a, long long b) {
  if (a < b) swap(a, b);
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long cubr(long long a) {
  long long l = -1, r = 1e6 + 2;
  while (l < r - 1) {
    long long mid = (l + r) / 2;
    if (mid * mid * mid > a)
      r = mid;
    else
      l = mid;
  }
  return l;
}
long long max(long long a, long long b) {
  if (a > b) return a;
  return b;
}
long long min(long long a, long long b) { return -1 * max(-a, -b); }
long long possible(long long q) {
  if (q == INF) return -1;
  return q;
}
bool correct(int x, int xx) {
  if (x < 0) return 0;
  if (x >= xx) return 0;
  return 1;
}
long long dsumm(long long x, long long k) {
  long long y = 1;
  long long z = 0;
  for (int i = 0; y < 1e18; i++) {
    z += x / y % k;
    y *= k;
  }
  return z;
}
long long dcount(long long x) {
  long long y = 1;
  long long z = 0;
  int c[100];
  for (int i = 0; i < 10; i++) c[i] = 0;
  for (int i = 0; x > 0; i++) {
    if (c[x / y % 10] == 0) z++;
    c[x / y % 10] = 1;
    x /= 10;
  }
  return z;
}
long long lg10(long long x) {
  if (x == 0) return 0;
  return lg10(x / 10) + 1;
}
long long n, m;
vector<int> graph[4000], graph2[4000];
long long ans;
long long d[5000];
long long f[4000];
long long ff[4000];
int main() {
  cin >> n >> m;
  for (int(i) = 0; (i) != (m); i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    graph[x].push_back(y);
    graph2[y].push_back(x);
  }
  long long it = 2;
  for (int b = 0; b < n; b++) {
    for (int c = b + 1; c < n; c++) {
      long long x = 0;
      long long y = 0;
      long long z = 0;
      for (int i = 0; i < graph[b].size(); i++) {
        d[graph[b][i]] = it;
      }
      for (int i = 0; i < graph[c].size(); i++) {
        if (d[graph[c][i]] == it) {
          x++;
        }
      }
      it++;
      for (int i = 0; i < graph2[b].size(); i++) {
        d[graph2[b][i]] = it;
      }
      for (int i = 0; i < graph2[c].size(); i++) {
        if (d[graph2[c][i]] == it) {
          y++;
        }
      }
      it++;
      for (int i = 0; i < graph[b].size(); i++) {
        ff[graph[b][i]] = it * 7;
      }
      for (int i = 0; i < graph[c].size(); i++) {
        if (ff[graph[c][i]] == it * 7)
          ff[graph[c][i]]++;
        else
          ff[graph[c][i]] = 0;
      }
      for (int i = 0; i < graph2[b].size(); i++) {
        if (ff[graph2[b][i]] == it * 7 + 1)
          ff[graph2[b][i]]++;
        else
          ff[graph2[b][i]] = 0;
      }
      for (int i = 0; i < graph2[c].size(); i++) {
        if (ff[graph2[c][i]] == it * 7 + 2) {
          z++;
          ff[graph2[c][i]] = 0;
        }
      }
      ans += (x - z) * (y - z) + z * (z - 1) + z * (x - z) + z * (y - z);
    }
  }
  cout << ans;
}
