#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<size_t>>;
vector<size_t> bfs(size_t s, const Graph &g) {
vector<size_t> dist(g.size(), numeric_limits<size_t>::max());
dist[s] = 0;
queue<size_t> q;
q.push(s);
while (!q.empty()) {
size_t u = q.front();
q.pop();
for (size_t v : g[u]) {
if (dist[v] == numeric_limits<size_t>::max()) {
dist[v] = dist[u] + 1;
q.push(v);
}
}
}
return dist;
}
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
size_t n, m;
cin >> n >> m;
Graph graph(n);
for (size_t i = 0; i < m; ++i) {
size_t u, v;
cin >> u >> v, --u, --v;
graph[u].emplace_back(v);
graph[v].emplace_back(u);
}
auto dist0 = bfs(0, graph), dist1 = bfs(1, graph);
if (dist0[1] < 5)
return cout << "-1\n", 0;
size_t a = 0, b = 0, c = 0, d = 0, o = 0;
for (size_t i = 0; i < n; ++i) {
if (dist0[i] == 1)
++a;
else if (dist0[i] == 2)
++b;
else if (dist1[i] == 2)
++c;
else if (dist1[i] == 1)
++d;
else if (i != 0 && i != 1)
++o;
}
auto calc = [](size_t a, size_t b, size_t c, size_t d) -> size_t {
auto c2 = [](size_t x) -> size_t { return x * (x - 1) >> 1; };
return a + c2(a) + a * b + c2(b) + b * c + c2(c) + c * d + c2(d) + d;
};
size_t ans = max(calc(a, b + o, c, d), calc(a, b, c + o, d));
cout << ans - m << '\n';
return 0;
}