#include <cstddef>
#include <utility>
#include <queue>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
namespace loquat {
using vertex_t = size_t;
}
namespace loquat {
namespace edge_param {
struct to_ {
	vertex_t to;
	explicit to_(vertex_t t = 0)
		: to(t)
	{ }
};
}
namespace detail {
template <typename T, typename... Params>
struct edge_param_wrapper : public T, edge_param_wrapper<Params...> {
};
template <typename T>
struct edge_param_wrapper<T> : public T {
	template <typename U>
	explicit edge_param_wrapper(U&& x)
		: T(std::forward<U>(x))
	{ }
};
}
template <typename... Params>
struct edge : public detail::edge_param_wrapper<edge_param::to_, Params...> {
	template <typename... Args>
	explicit edge(Args&&... args)
		: detail::edge_param_wrapper<edge_param::to_, Params...>(
			std::forward<Args>(args)...)
	{ }
};
}
namespace loquat {
template <typename EdgeType>
class adjacency_list {
public:
	using edge_type = EdgeType;
	using edge_list = std::vector<edge_type>;
private:
	std::vector<std::vector<EdgeType>> m_edges;
public:
	explicit adjacency_list(size_t n)
		: m_edges(n)
	{ }
	const edge_list& operator[](vertex_t u) const {
		return m_edges[u];
	}
	template <typename... Args>
	void add_edge(vertex_t from, Args&&... args){
		m_edges[from].emplace_back(std::forward<Args>(args)...);
	}
};
}
namespace loquat {
class disjoint_set {
public:
	using value_type = size_t;
private:
	std::vector<value_type> m_parents;
	std::vector<value_type> m_ranks;
public:
	explicit disjoint_set(size_t n)
		: m_parents(n)
		, m_ranks(n)
	{
		for(size_t i = 0; i < n; ++i){
			m_parents[i] = i;
		}
	}
	value_type find(size_t x){
		if(m_parents[x] == x){ return x; }
		m_parents[x] = find(m_parents[x]);
		return m_parents[x];
	}
	value_type unite(size_t x, size_t y){
		x = find(x);
		y = find(y);
		if(x == y){ return x; }
		if(m_ranks[x] < m_ranks[y]){
			m_parents[x] = y;
			return y;
		}else if(m_ranks[x] > m_ranks[y]){
			m_parents[y] = x;
			return x;
		}else{
			m_parents[y] = x;
			++m_ranks[x];
			return x;
		}
	}
	bool same(size_t x, size_t y){
		return find(x) == find(y);
	}
};
}
using namespace std;
using edge = loquat::edge<>;
using pii = pair<int, int>;
bool solve(
	vector<pii>& picks,
	vector<bool>& vis,
	int u, int p,
	const loquat::adjacency_list<edge>& g)
{
	vis[u] = true;
	bool done = false;
	for(const auto& e : g[u]){
		const int v = e.to;
		if(vis[v]){ continue; }
		const auto f = solve(picks, vis, v, u, g);
		if(!f){ done = !done; }
	}
	if(!done && p >= 0){ picks.emplace_back(u, p); }
	return done;
}
int main(){
	ios_base::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	vector<vector<int>> a(n, vector<int>(n));
	for(int i = 0; i < m; ++i){
		int u, v;
		cin >> u >> v;
		--u; --v;
		a[u][v] = a[v][u] = 1;
	}
	loquat::adjacency_list<edge> g(n), cg(n);
	for(int u = 0; u < n; ++u){
		for(int v = 0; v < n; ++v){
			if(u == v){ continue; }
			(a[u][v] ? g : cg).add_edge(u, v);
		}
	}
	if(n % 2 == 0){
		vector<pii> picks;
		vector<bool> vis(n);
		for(int r = 0; r < n; ++r){
			if(vis[r]){ continue; }
			if(!solve(picks, vis, r, -1, cg)){
				cout << -1 << endl;
				return 0;
			}
		}
		for(const auto& p : picks){
			const int u = p.first;
			const int v = p.second;
			a[u][v] = a[v][u] = 2;
		}
		loquat::disjoint_set ds(n);
		for(int u = 0; u < n; ++u){
			for(int v = u + 1; v < n; ++v){
				if(a[u][v] != 2){ ds.unite(u, v); }
			}
		}
		bool accept = true;
		for(int v = 0; v < n; ++v){
			if(!ds.same(0, v)){ accept = false; }
		}
		if(!accept){
			cout << -1 << endl;
			return 0;
		}
	}
	vector<pii> solution;
	for(int u = 0; u < n; ++u){
		for(int v = u + 1; v < n; ++v){
			if(a[u][v] == 0){ solution.emplace_back(u, v); }
		}
	}
	cout << solution.size() << endl;
	for(const auto& p : solution){
		cout << p.first + 1 << " " << p.second + 1 << endl;
	}
	return 0;
}



Measured memory_bytes: 3388