#include <bits/stdc++.h>
#ifdef DEBUG
#include "_debug.cpp"
#include "callable.hpp/callable.hpp"
#endif
#define endl '\n'
using namespace std;
using ll = long long;
#define N 700
bool conn[N+1][N+1] = {};
vector<int> adj[N+1];
void link(int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
}
bool vis[N+1] = {};
int p[N+1] = {};
int depth[N+1] = {};
int sz[N+1] = {};
template <typename PreFunction, typename PostFunction>
int dfs(int u, const PreFunction& pre, const PostFunction& post) {
#ifdef DEBUG
    using pre_actual_type = typename callable_traits<PreFunction>::function_type;
    using pre_expected_type = typename callable_traits<void(int)>::function_type;
    static_assert(is_same<pre_actual_type, pre_expected_type>::value, "dfs 'pre' must be void(int)");
    using post_actual_type = typename callable_traits<PostFunction>::function_type;
    using post_expected_type = typename callable_traits<void(int)>::function_type;
    static_assert(is_same<post_actual_type, post_expected_type>::value, "dfs 'post' must be void(int)");
#endif
    int ans = 1;
    vis[u] = true;
    depth[u] = depth[p[u]] + 1;
    sz[u] = 1;
    pre(u);
    for(int v : adj[u]) {
        if(not vis[v]) {
            p[v] = u;
            ans += dfs(v, pre, post);
            sz[u] += sz[v];
        }
    }
    post(u);
    return ans;
}
int dfs(int u) { return dfs(u, [](int u) {}, [](int u) {}); }
bool color[N+1];
vector<int> black_counts;
vector<int> white_counts;
vector<int> color_counts;
vector<int> color_counts_psum;
int mem[N+1][N+1];
int add_new_nodes(int x, int y, int new_x, int new_y) {
    return new_x * x + new_x * (new_x - 1) / 2
         + new_y * y + new_y * (new_y - 1) / 2;
}
int opt(int i, int x) {
    int& ans = mem[i][x];
    if(ans == -1) {
        if(i == color_counts.size()) {
            ans = 0;
        } else {
            int y = (i == 0 ? 0 : color_counts_psum[i - 1]) - x;
            ans = min(add_new_nodes(x, y, black_counts[i], white_counts[i]) + opt(i + 1, x + black_counts[i]),
                      add_new_nodes(x, y, white_counts[i], black_counts[i]) + opt(i + 1, x + white_counts[i]));
        }
    }
    return ans;
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        conn[u][v] = conn[v][u] = true;
    }
    for(int i = 1; i <= n; i++) {
        for(int j = i + 1; j <= n; j++) {
            if(not conn[i][j]) {
                link(i, j);
            }
        }
    }
    fill(vis, vis + n + 1, false);
    bool can = true;
    for(int u = 1; u <= n and can; u++) {
        if(not vis[u]) {
            color[u] = true;
            int black = 0, white = 0;
            dfs(u, [&](int u) {
                color[u] = not color[p[u]];
                (color[u] ? black : white)++;
            }, [&](int u) {
                for(int v : adj[u]) {
                    can &= color[v] != color[u];
                }
            });
            black_counts.push_back(black);
            white_counts.push_back(white);
            color_counts.push_back(black + white);
        }
    }
    if(can) {
        color_counts_psum.resize(color_counts.size());
        partial_sum(color_counts.begin(), color_counts.end(), color_counts_psum.begin());
        memset(mem, -1, sizeof mem);
        cout << opt(0, 0) << endl;
    } else {
        cout << -1 << endl;
    }
    return 0;
}


Measured memory_bytes: 3200