#pragma GCC optimize ("Ofast") #pragma GCC optimize ("unroll-loops") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using Int = long long; template ostream &operator<<(ostream &os, const pair &a) { return os << "(" << a.first << ", " << a.second << ")"; }; template void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; } template bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; } template bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; } int uf[10010]; int root(int u) { return (uf[u] < 0) ? u : (uf[u] = root(uf[u])); } bool connect(int u, int v) { u = root(u); v = root(v); if (u == v) return false; if (uf[u] > uf[v]) swap(u, v); uf[u] += uf[v]; uf[v] = u; return true; } int N, M; vector X, Y; bitset<5010> dp[5010]; int main() { for (; ~scanf("%d%d", &N, &M); ) { X.resize(M); Y.resize(M); for (int i = 0; i < M; ++i) { scanf("%d%d", &X[i], &Y[i]); --X[i]; --Y[i]; } fill(uf, uf + N + N, -1); for (int i = 0; i < M; ++i) { connect(X[i], N + Y[i]); } vector as(N + N, 0), bs(N + N, 0); for (int x = 0; x < N; ++x) { ++as[root(x)]; } for (int y = 0; y < N; ++y) { ++bs[root(N + y)]; } vector> ps; for (int r = 0; r < N + N; ++r) { if (uf[r] < 0) { ps.emplace_back(as[r], bs[r]); } } sort(ps.begin(), ps.end()); const int psLen = ps.size(); // cerr<<"ps = ";pv(ps.begin(),ps.end()); for (int a = 0; a <= N; ++a) { dp[a].reset(); } dp[0][N] = true; for (int j = 0, k; j < psLen; j = k) { for (k = j; k < psLen && ps[j] == ps[k]; ++k) {} int num = k - j; for (int e = 0; num > 0; ++e) { const int t = min(1 << e, num); num -= t; const int da = t * ps[j].first; const int db = t * ps[j].second; for (int a = N - da; a >= 0; --a) { dp[a + da] |= dp[a] >> db; } } } int ans = N * N; for (int a = 0; a <= N; ++a) for (int b = 0; b <= N; ++b) { if (dp[a][b]) { chmin(ans, a * (N - b) + (N - a) * b); } } ans -= M; printf("%d\n", ans); } return 0; }