#include<bits/stdc++.h>
#define int long long
#define fast register int
using namespace std;
const int N=2e6+100;
int n,m,t1,t2;
inline int pows(int x){return 1ll*x*x;}
struct G{
int head[N],nxt[N<<1],to[N<<1],tot;
void addedge(int b,int e){
nxt[++tot]=head[b]; head[b]=tot; to[tot]=e;
nxt[++tot]=head[e]; head[e]=tot; to[tot]=b;
}
}G,QWQ;
int dfn[N],low[N],st[N],top,idx,cnt,sz[N],sznow;
void tarjan(int u){
sz[u]=-1; ++sznow;
dfn[u]=low[u]=++cnt;
st[++top]=u;
for (fast i=G.head[u];i;i=G.nxt[i]){
if (!dfn[G.to[i]]){
tarjan(G.to[i]);
low[u]=min(low[u],low[G.to[i]]);
if (dfn[u]<=low[G.to[i]]){
++idx; int v;
do{
v=st[top--],
QWQ.addedge(v,idx),
++sz[idx];
}while(v!=G.to[i]);
++sz[idx];
QWQ.addedge(u,idx);
}
}
else low[u]=min(low[u],dfn[G.to[i]]);
}
}
int ans,sz2[N];
void dfs(int u,int fa){
sz2[u]=u<=n;
int cnt1=0;
for (fast i=QWQ.head[u];i;i=QWQ.nxt[i]){
if (QWQ.to[i]!=fa){
dfs(QWQ.to[i],u);
cnt+=1ll*sz2[QWQ.to[i]]*sz2[u];
sz2[u]+=sz2[QWQ.to[i]];
}
}
cnt1+=1ll*sz2[u]*(sznow-sz2[u]);
cnt1<<=1;
ans+=1ll*sz[u]*cnt1;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>n>>m;
idx=n;
for (fast i=1;i<=m;i++){
cin>>t1>>t2;
G.addedge(t1,t2);
}
for (fast i=1;i<=n;i++){
if (!dfn[i]){
sznow=0;
top=0;
tarjan(i);
dfs(i,0);
}
}
cout<<ans;
return 0;
}