#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define all(a) (a).begin(),(a).end()
#ifdef DEBUG
template<class T>
ostream& operator << (ostream &out,vector<T> a){
out<<'[';
for(T x:a)out<<x<<',';
return out<<']';
}
template<class T>
vector<T> ary(T *a,int l,int r){
return vector<T>{a+l,a+1+r};
}
template<class T>
void debug(T x){
cerr<<x<<endl;
}
template<class T,class...S>
void debug(T x,S...y){
cerr<<x<<' ',debug(y...);
}
#else
#define debug(...) void()
#endif
using ull=unsigned long long;
const int N=1e5+10;
int n,m,cur[N],rk[N],deg[N];
pair<int,int>e[N];
vector<int>to[N];
int idx;
ull f[N];
ll ans;
void solve(){
for(int u=1;u<=m;u++){
ans+=__builtin_popcountll(f[e[i].first]&f[e[i].second]);
}
fill(f,f+1+n,0);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
e[i]={u,v},deg[u]++,deg[v]++;
}
iota(cur,cur+1+n,0);
sort(cur+1,cur+1+n,[&](int x,int y){
return deg[x]<deg[y];
});
for(int i=1;i<=n;i++)rk[cur[i]]=i;
for(int i=1;i<=m;i++){
auto &[u,v]=e[i];
if(rk[u]<rk[v])swap(u,v);
to[u].push_back(v);
}
for(int u=1;u<=n;u++){
static int from[N];
for(int v:to[u])from[v]=u;
for(int v:to[u]){
for(int w:to[v])if(from[w]==u){
f[w]|=1ull<<idx;
}
if(++idx==64)solve(),idx=0;
}
}
solve();
cout<<ans<<endl;
return 0;
}