#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
struct edge
{
int nxt,to;
}e[400001],E[400001];
int head[100001],tot=0;
int Head[100001],Tot=0;
int dfn[100001],low[100001],vistime=0;
int s[100001],top=0;
int d[100001],idx;
int sz[100001],tree_sz=0;
long long ans=0;
void add(int u,int v)
{
tot++;
e[tot].nxt=head[u];
e[tot].to=v;
head[u]=tot;
}
void Add(int u,int v)
{
Tot++;
E[Tot].nxt=Head[u];
E[Tot].to=v;
Head[u]=Tot;
}
void tarjan(int u)
{
d[u]=-1;
dfn[u]=low[u]=++vistime;
s[++top]=u;
tree_sz++;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])
{
int k;
idx++;
Add(u,idx);
Add(idx,u);
d[idx]++;
do
{
k=s[top];
top--;
Add(k,idx);
Add(idx,k);
d[idx]++;
}
while(k!=v);
}
}
else
{
low[u]=min(low[u],dfn[v]);
}
}
}
void dfs(int u,int f)
{
sz[u]=u<=n;
long long sum=0;
for(int i=Head[u];i;i=E[i].nxt)
{
int v=E[i].to;
if(v!=f)
{
dfs(v,u);
sum+=(long long)(sz[v]*sz[u]);
sz[u]+=sz[v];
}
}
sum+=(long long)(sz[u]*(tree_sz-sz[u]));
sum*=2;
ans+=(long long)(d[u]*sum);
}
int main()
{
scanf("%d%d",&n,&m);
idx=n;
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
{
tree_sz=0;
top=0;
tarjan(i);
dfs(i,0);
}
}
printf("%lld",ans);
return 0;
}