#include <bits/stdc++.h>   const int maxn = 2005;   const int inf = 1e9;   using namespace std;   vector<pair<int, int>> G[maxn];   vector<int> C[maxn], v;   bool critical[maxn * maxn];   vector<int> seen, sum, col, depth, up;   void dfs(int node, int ind) {     seen[node] = 1;     int minFromSons = inf;     up[node] = depth[node];     for (auto tmp : G[node]) {       if (seen[tmp.first] && tmp.second != ind)         up[node] = min(up[node], depth[tmp.first]);       else if (!seen[tmp.first]) {         depth[tmp.first] = depth[node] + 1;         dfs(tmp.first, tmp.second);         minFromSons = min(minFromSons, up[tmp.first]);       }     }     up[node] = min(up[node], minFromSons);     if (minFromSons >= depth[node] && ind != -1) {       critical[ind] = 1;     }   }   void dfsColor(int node, int color) {     col[node] = color;     v[color]++;     for (auto tmp : G[node]) {       if (critical[tmp.second] == 1 && col[tmp.first] == 0) continue;       if (critical[tmp.second] == 1 && col[tmp.first]) {         C[col[tmp.first]].push_back(color);         C[color].push_back(col[tmp.first]);         continue;       } else if (col[tmp.first] == 0)         dfsColor(tmp.first, color);     }   }   void dfsSub(int node) {     seen[node] = 1;     sum[node] = v[node];     for (auto tmp : C[node])       if (!seen[tmp]) {         dfsSub(tmp);         sum[node] += sum[tmp];       }   }   int main() {     ios_base ::sync_with_stdio(false);     int n, m;     cin >> n >> m;     for (int i = 0; i < m; ++i) {       int a, b;       cin >> a >> b;       G[a].push_back(make_pair(b, i));       G[b].push_back(make_pair(a, i));     }     seen = vector<int>(n + 1, 0);     depth = vector<int>(n + 1, 0);     up = vector<int>(n + 1, 0);     dfs(1, -1);     int c = 0;     col = vector<int>(n + 1, 0);     v = vector<int>(n + 1, 0);     int all = 0;     for (int i = 1; i <= n; ++i)       if (col[i] == 0) {         ++c;         dfsColor(i, c);         all += v[c] * v[c];       }     int ans = 0;     for (int i = 1; i <= c; ++i) {       seen = vector<int>(c + 1, 0);       sum = vector<int>(c + 1, 0);       dfsSub(i);       int tmp = 0;       for (int j = 1; j <= c; ++j) tmp += sum[j] * v[j];       vector<int> can(n + 1, 0);       can[0] = 1;       for (auto tmp : C[i]) {         for (int j = n; j >= 0; --j)           if (can[j] && j + sum[tmp] <= n) can[j + sum[tmp]] = 1;       }       int res = -1;       for (int j = (n - v[i]) / 2; j >= 0; --j)         if (can[j]) {           res = j;           break;         }       tmp += res * (n - v[i] - res);       ans = max(ans, tmp);     }     cerr << all <<   n ;     cout << ans <<   n ;   }   