void solve(){
int N, M; cin >> N >> M;
vector<pii> edges;
vector<bitset<2500>> con(N);
rep(i, 0, M){
int u, v; cin >> u >> v;
u--; v--;
edges.push_back({u, v});
con[u][v] = 1;
con[v][u] = 1;
}
vector<ll> cnt1(N);
rep(i, 0, N) cnt1[i] = con[i].count();
vector<vector<bitset<2500>>> con2(N, vector<bitset<2500>>(N));
rep(i, 0, N) rep(j, i+1, N) con2[i][j] = con2[j][i] = con[i]&con[j];
vector<vector<ll>> cnt2(N, vector<ll>(N));
rep(i, 0, N) rep(j, i+1, N) cnt2[i][j] = cnt2[j][i] = con2[i][j].count();
auto calc = [&](int v1, int v2, int v3, int v4) -> ll {
auto &b1 = con[v1], &b2 = con[v2], &b3 = con[v3];
ll n1 = cnt1[v1] - (con[v1][v2] + con[v1][v3] + con[v1][v4]);
ll n2 = cnt1[v2] - (con[v2][v1] + con[v2][v3] + con[v2][v4]);
ll n3 = cnt1[v3] - (con[v3][v1] + con[v3][v2] + con[v3][v4]);
ll n12 = cnt2[v1][v2] - (con2[v1][v2][v3] + con2[v1][v2][v4]);
ll n23 = cnt2[v2][v3] - (con2[v2][v3][v1] + con2[v2][v3][v4]);
ll n31 = cnt2[v3][v1] - (con2[v3][v1][v2] + con2[v3][v1][v4]);
bitset<2500> b123 = b1&b2&b3;
ll n123 = b123.count() - b123[v4];
return n1*n2*n3 - (n12*n3 + n23*n1 + n31*n2) + 2*n123;
};
ll ans = 0;
rep(i, 0, M) rep(j, i+1, M){
auto [a, b] = edges[i];
auto [c, d] = edges[j];
if(a == c || a == d || b == c || b == d) continue;
if((!con[a][c] || !con[b][d]) && (!con[a][d] || !con[b][c])) continue;
ll ret = 0;
ret += calc(a, b, c, d);
ret += calc(b, c, d, a);
ret += calc(c, d, a, b);
ret += calc(d, a, b, c);
if(con[a][c] && con[b][d]) ans += ret;
if(con[a][d] && con[b][c]) ans += ret;
}
cout << ans/2;
}