#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-11;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
typedef pair<ld, ld> LDP;
typedef unsigned long long ul;
int n, m;
bool used[100][100];
struct edge { 
	int a, b;
};
vector<edge> ans;
void out() {
	cout << ans.size() << endl;
	rep(i, ans.size()) {
		if (ans[i].a > ans[i].b)swap(ans[i].a, ans[i].b);
		cout << ans[i].a+1 << " " << ans[i].b+1 << endl;
	}
}
vector<edge> v, cv;
int num[100];
bool chked[100];
vector<int> rG[100];

vector<int> G[100];
bool ban[100][100];
void dfs(int fr,int id) {
	chked[id] = true;
	rep(j, G[id].size()) {
		dfs(id,G[id][j]);
	}
	if (num[id] % 2 == 0) {
		if (fr != id) {
			num[fr]--; num[id]--;
			ans.push_back({ min(fr, id), max(fr, id) });
			ban[min(fr, id)][max(fr,id)] = true;
		}
	}
}
void make_tree(int root) {
	chked[root] = true;
	rep(j, rG[root].size()) {
		int to = rG[root][j];
		if (chked[to])continue;
		G[root].push_back(to);
		make_tree(to);
		//cout << root << " " << to << endl;
	}
}


int par[100];
int rank1[100];
void init() {
	for (int i = 0; i < n; i++) {
		par[i] = i;
		rank1[i] = 0;
	}
}
int find(int x) {
	if (par[x] == x) {
		return x;
	}
	else {
		return par[x] = find(par[x]);
	}
}
void unite(int x, int y) {
	x = find(x);
	y = find(y);
	if (x == y)return;
	if (rank1[x] < rank1[y]) {
		par[x] = y;
	}
	else {
		par[y] = x;
		if (rank1[x] == rank1[y])rank1[x]++;
	}
}
bool same(int x, int y) {
	return find(x) == find(y);
}
vector<int> atu[100];
void renketuni() {
	int z = 0;
	rep(i, ans.size()) {
		unite(ans[i].a, ans[i].b);
	}
	bool rest[100] = {};
	rep(i, n) {
		if (rest[i])continue;
		rep(j, n) {
			if (same(i, j)) {
				atu[z].push_back(j); rest[j] = true;
			}
		}
		z++;
	}
	rep(i, z) {
		Rep(j, i + 1, z) {
			rep(k, 2) {
				rep(l, 2) {
					ans.push_back({ atu[i][k],atu[j][l] });
				}
			}
		}
	}
}


int main() {
	cin >> n >> m; init();
	rep(i, m) {
		int a, b; cin >> a >> b; a--; b--; if (a > b)swap(a, b);
		v.push_back({ a,b });
		unite(a, b);
		used[a][b] = true;
	}
	rep(i, n) {
		Rep(j, i + 1, n) {
			if (!used[i][j]) {
				cv.push_back({ i,j });
			}
		}
	}
	if (n % 2) {
		rep(i, n) {
			Rep(j, i + 1, n) {
				if (!used[i][j])ans.push_back({ i,j });
			}
		}
		out();
	}
	else {
		rep(j, cv.size()) {
			rG[cv[j].a].push_back(cv[j].b);
			rG[cv[j].b].push_back(cv[j].a);
			num[cv[j].b]++;
			num[cv[j].a]++;
		}
		//rep(i, n)cout << num[i] << endl;
		rep(i, n) {
			if (rG[i].size() == 0) {
				cout << -1 << endl; return 0;
			}
			else if (rG[i].size() == n-1) {
				rep(j, n) {
					Rep(k, j + 1, n) {
						if (i == j || i == k)continue;
						if (!used[j][k]) {
							ans.push_back({ j,k });
						}
					}
				}
				if (ans.size() == 0)cout << -1 << endl;
				else {
					int x = ans[0].a, y = ans[0].b;
					ans.erase(ans.begin());
					ans.push_back({ min(i,x),max(i,x) });
					ans.push_back({ min(i,y),max(i,y) });
					out();
				}
				return 0;
			}
		}
		rep(i, n) {
			if (chked[i])continue;
			make_tree(i);
			dfs(i, i);
			//rep(j, n)cout << num[j] << endl;
			if(num[i]%2==0){
				cout << -1 << endl;
				return 0;
			}
		}
		/*rep(i, n) {
			Rep(j, i + 1, n) {
				if (ban[i][j] || used[i][j])continue;
				ans.push_back({ i,j });
			}
		}*/
		renketuni();

		out();
	}
	return 0;
}


Measured memory_bytes: 3288