Imagine a city with n junctions and m streets. Junctions are numbered from 1 to n.

In order to increase the traffic flow, mayor of the city has decided to make each street one-way. This means in the street between junctions u and v, the traffic moves only from u to v or only from v to u. 

The problem is to direct the traffic flow of streets in a way that maximizes the number of pairs (u, v) where 1 ≤ u, v ≤ n and it is possible to reach junction v from u by passing the streets in their specified direction. Your task is to find out maximal possible number of such pairs.

Input

The first line of input contains integers n and m, (<image>), denoting the number of junctions and streets of the city.

Each of the following m lines contains two integers u and v, (u ≠ v), denoting endpoints of a street in the city.

Between every two junctions there will be at most one street. It is guaranteed that before mayor decision (when all streets were two-way) it was possible to reach each junction from any other junction.

Output

Print the maximal number of pairs (u, v) such that that it is possible to reach junction v from u after directing the streets.

Examples

Input

5 4
1 2
1 3
1 4
1 5


Output

13


Input

4 5
1 2
2 3
3 4
4 1
1 3


Output

16


Input

2 1
1 2


Output

3


Input

6 7
1 2
2 3
1 3
1 4
4 5
5 6
6 4


Output

27

Note

In the first sample, if the mayor makes first and second streets one-way towards the junction 1 and third and fourth streets in opposite direction, there would be 13 pairs of reachable junctions: {(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (2, 1), (3, 1), (1, 4), (1, 5), (2, 4), (2, 5), (3, 4), (3, 5)}
#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
inline void smin(T &a, U b) {
  if (a > b) a = b;
}
template <typename T, typename U>
inline void smax(T &a, U b) {
  if (a < b) a = b;
}
template <class T>
inline void gn(T &first) {
  char c, sg = 0;
  while (c = getchar(), (c > '9' || c < '0') && c != '-')
    ;
  for ((c == '-' ? sg = 1, c = getchar() : 0), first = 0; c >= '0' && c <= '9';
       c = getchar())
    first = (first << 1) + (first << 3) + c - '0';
  if (sg) first = -first;
}
template <class T>
inline void print(T first) {
  if (first < 0) {
    putchar('-');
    return print(-first);
  }
  if (first < 10) {
    putchar('0' + first);
    return;
  }
  print(first / 10);
  putchar(first % 10 + '0');
}
int power(int a, int b, int m, int ans = 1) {
  for (; b; b >>= 1, a = 1LL * a * a % m)
    if (b & 1) ans = 1LL * ans * a % m;
  return ans;
}
int adj[2222][2222], deg[2222];
int vst[2222], low[2222], bel[2222], st[2222];
int cnt, top, ind;
int ans;
int val[2222];
int tot[2222];
int gas[2222];
void dfs(int u, int pre = -1) {
  vst[u] = low[u] = ++ind;
  st[++top] = u;
  for (int i = 0; i < deg[u]; i++) {
    int v = adj[u][i];
    if (!vst[v])
      dfs(v, u), low[u] = min(low[u], low[v]);
    else if (v != pre)
      low[u] = min(low[u], vst[v]);
  }
  if (vst[u] == low[u]) {
    ++cnt;
    while (1) {
      bel[st[top]] = cnt;
      val[cnt]++;
      if (st[top--] == u) break;
    }
  }
}
int E;
vector<int> ADJ[2222];
void add(int u, int v) {
  ADJ[u].push_back(v);
  ADJ[v].push_back(u);
}
void DFS(int u, int fa = 0) {
  int v;
  for (int i = 0; i < ((int)ADJ[u].size()); i++) {
    v = ADJ[u][i];
    if (v == fa) continue;
    DFS(v, u);
    tot[u] += tot[v];
    gas[u] += gas[v];
  }
  gas[u] += tot[u] * val[u];
  tot[u] += val[u];
}
int sv[2222];
int flag[2222];
int n;
void solve(int u, int fa = 0) {
  int v;
  sv[u] = sv[fa] + val[fa] * (n - tot[u] - val[fa]);
  sv[u] += (gas[fa] - gas[u] - (tot[fa] - val[fa]) * val[fa]);
  sv[1] = 0;
  int tmp = val[u] * (n - val[u]) + sv[u];
  memset(flag, 0, sizeof flag);
  flag[0] = 1;
  for (int i = 0; i < ((int)ADJ[u].size()); i++) {
    v = ADJ[u][i];
    if (v != fa) {
      tmp += gas[v];
      for (int i = n; i >= 0; i--)
        if (flag[i]) flag[i + tot[v]] = 1;
    } else {
      for (int i = n; i >= 0; i--)
        if (flag[i]) flag[i + n - tot[u]] = 1;
    }
  }
  int mx = 0;
  for (int i = 1; i <= n; i++)
    if (flag[i]) smax(mx, i * (n - val[u] - i));
  tmp += mx;
  smax(ans, tmp);
  for (int i = 0; i < ((int)ADJ[u].size()); i++) {
    v = ADJ[u][i];
    if (v == fa) continue;
    solve(v, u);
  }
}
int main() {
  int m;
  cin >> n >> m;
  tot[0] = n;
  for (int i = 0, u, v; i < m; i++) {
    gn(u);
    gn(v);
    adj[u][deg[u]++] = v;
    adj[v][deg[v]++] = u;
  }
  dfs(1);
  for (int i = 1; i <= n; i++) {
    int u = i, v, bu, bv;
    for (int j = 0; j < deg[u]; j++) {
      v = adj[u][j];
      bu = bel[u];
      bv = bel[v];
      if (bu != bv) add(bu, bv);
    }
  }
  for (int i = 1; i <= cnt; i++)
    if (((int)ADJ[i].size())) {
      sort(ADJ[i].begin(), ADJ[i].end());
      ADJ[i].resize(unique(ADJ[i].begin(), ADJ[i].end()) - ADJ[i].begin());
    }
  DFS(1);
  solve(1);
  for (int i = 1; i <= cnt; i++) {
    ans += val[i] * val[i];
  }
  cout << ans << endl;
  return 0;
}
