#include <bits/stdc++.h>
#pragma GCC optimize(2)
const int N = 702, M = 2e6 + 6;
int n, m;
struct Edge {
  int s, t, nxt;
  Edge(int s, int t, int nxt) : s(s), t(t), nxt(nxt) {}
  Edge() { nxt = -1; }
};
struct Graph {
  int cnt, hd[N], deg[N];
  bool am[N][N];
  long long p2c[N][N];
  Edge ed[M];
  Graph() {
    cnt = 0;
    memset(hd, -1, sizeof(hd));
    memset(p2c, 0, sizeof(p2c));
    memset(am, 0, sizeof(am));
    memset(deg, 0, sizeof(deg));
  }
  void addEdge(int x, int y) {
    ed[++cnt] = Edge(x, y, hd[x]);
    am[x][y] = true;
    hd[x] = cnt;
    deg[x]++;
  }
  void getP2c(int x) {
    for (register int y = 1; y <= n; y++)
      if (am[x][y])
        for (register int z = 1; z <= n; z++)
          if (am[y][z]) p2c[x][z]++;
  }
  long long solve1() {
    long long res = 0;
    for (int i = 1; i <= n; i++) getP2c(i);
    for (int i = 1; i <= m * 2; i += 2)
      for (int j = 1; j <= n; j++) {
        int a = ed[i].s, b = ed[i].t;
        if (a == j || b == j) continue;
        res += (p2c[j][a] - am[j][b]) * (p2c[j][b] - am[j][a]);
      }
    return res;
  }
  long long solve2() {
    long long res = 0;
    for (int i = 1; i <= m * 2; i += 2)
      for (int j = 1; j <= n; j++) {
        int a = ed[i].s, b = ed[i].t;
        if (a == j || b == j) continue;
        res += (am[a][j] && am[b][j]) ? deg[j] - 2 : 0;
      }
    return res;
  }
} gra;
int read() {
  char ch = getchar();
  int res = 0;
  while (ch < '0' || '9' < ch) ch = getchar();
  while ('0' <= ch && ch <= '9') res *= 10, res += ch - '0', ch = getchar();
  return res;
}
int main() {
  int t0 = clock();
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int a = read(), b = read();
    gra.addEdge(a, b);
    gra.addEdge(b, a);
  }
  long long ans = (gra.solve1() - gra.solve2()) / 5;
  std::cout << ans << std::endl;
  return 0;
}
