#include<fstream>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
ifstream f("triplete.in");
ofstream g("triplete.out");
vector <int> G[5000], G2[5000];
int use[5000];
int n, m, nrt;
void citire()
{
int i, x, y;
f>>n>>m;
for(i=1; i<=m; i++){
f>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
}
void DFS_Recon(int nod, int tata)
{
use[nod] = 1;
int vecin, i;
vector <int> ::iterator it;
for(it = G[nod].begin(); it != G[nod].end(); it++){
vecin = *it;
if(!use[vecin]){
G2[tata].push_back(vecin);
DFS_Recon(vecin, nod);
}
}
}
bool cautare(int nod, int val)
{
int st = 0, dr = G[nod].size() - 1, mid;
while(st <= dr)
{
mid = (st+dr)/2;
if(G[nod][mid] == val)
return 1;
if(G[nod][mid] < val)
st = mid + 1;
if(G[nod][mid] > val)
dr = mid - 1;
}
return 0;
}
void rez()
{
int i, v2;
vector <int> ::iterator it;
for(i=1; i<=n; i++){
sort(G[i].begin(), G[i].end());
for(it = G2[i].begin(); it != G2[i].end(); it++){
v2 = *it;
nrt += cautare(i, v2);
}
}
g<<nrt<<"\n";
}
int main()
{
citire();
DFS_Recon(1, 0);
rez();
return 0;
}