#include <bits/stdc++.h>
using namespace std;

#ifdef Hwang_Baek_I
#define debug(args...) { string _102_ = #args; error(_102_.begin(), _102_.end(), args); }
void error(string::iterator it, string::iterator IT);
template<typename T, typename... Args>
void error(string::iterator it, string::iterator IT, T a, Args... args);
#else
#define debug(args...) 102
#endif

const int N = 770;

int chk[N][N];

int n;
int color[N];
int ones, twos;

void dfs(int u) {
	if (color[u] == 1) ones++;
	else twos++;
	for (int i = 1; i <= n; i++) {
		if (i != u && chk[u][i] == 0) {
			if (color[i]) {
				if (color[i] == color[u]) {
					cout << -1 << endl;
					exit(0);
				}
			} else {
				color[i] = 3 - color[u];
				dfs(i);
			}
		}
	}
}

int ans[N], tmp[N];

int main() {
#ifdef Hwang_Baek_I
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int m; cin >> n >> m;
	while (m--) {
		int u, v; cin >> u >> v;
		chk[u][v] = 1;
		chk[v][u] = 1;
	}
	int A = 0, B = 0;
	vector<pair<int, int>> v;
	for (int i = 1; i <= n; i++) {
		if (color[i]) continue;
		color[i] = 1;
		ones = twos = 0;
		dfs(i);
		debug(ones, twos);
		if (ones > twos) swap(ones, twos);
		v.emplace_back(ones, twos);
		A += ones, B += twos;
	}
	ans[0] = 1;
	for (auto it : v) {
		memset(tmp, 0, sizeof tmp);
		for (int i = 0; i < N; i++) if (i + it.first < N && ans[i]) tmp[i + it.first] = 1;
		for (int i = 0; i < N; i++) if (i + it.second < N && ans[i]) tmp[i + it.second] = 1;
		for (int i = 0; i < N; i++) ans[i] = tmp[i];
	}
	long long ret = LLONG_MAX;
	for (int i = 0; i < N; i++) if (ans[i]) {
		ret = min<long long>(ret, i * (i - 1) / 2 + (n - i) * (n - i - 1) / 2);
	}
	cout << ret << endl;
	return 0;
}









#ifdef Hwang_Baek_I
string to_string(const string &s) { return '"' + s + '"'; }
string to_string(const char* s) { return to_string((string)s); }
template<int N>
string to_string(bitset<N> v) { string res = ""; for (int i = 0; i < N; i++) res += ('0' + v[i]); return res; }
string to_string(char x) { string ret = ""; ret.push_back(x); return ret; }
template<typename T>
string to_string(T x) { string ret = ""; for (auto it : x) ret += to_string(it) + ", "; ret.pop_back(); ret.pop_back(); return ret; }
template<typename T, typename U>
string to_string(pair<T, U> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }
template<typename T, typename U, typename V>
string to_string(tuple<T, U, V> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")"; }
template <typename T, typename U, typename V, typename W>
string to_string(tuple<T, U, V, W> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";}
void error(string::iterator it, string::iterator IT) { cerr << endl; }
template<typename T, typename... Args>
void error(string::iterator it, string::iterator IT, T a, Args... args) {
	cerr << "<";
	int cnt = 0;
	while (it != IT) {
		if (*it == '(' || *it == '[' || *it == '<') cnt++;
		if (*it == ')' || *it == ']' || *it == '>') cnt--;
		if (cnt == 0 && *it == ',') break;
		if (*it != ' ') cerr << *it;
		it++;
	}
	cerr << " = " << to_string(a) << "> ";
	error(++it, IT, args...);
}
#endif



Measured memory_bytes: 2432