#define _CRT_SECURE_NO_WARNINGS
#define MOD 1000000007
#include <iostream>
#include <vector>
#include <list>
#include <set>
#include <bitset>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <string>
#include <functional>
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <utility>
#include <unordered_map>
#include <cmath>
#include <chrono>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

typedef pair<ll, ll> P;
struct edge { ll to, cost; };

#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define RFOR(i,a,b) for(ll i=(a);i>(b);i--)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) RFOR(i,n,-1)

inline ll madd(ll a, ll b) {
	a %= MOD;b %= MOD;
	return (a + b) % MOD;
}
inline ll msub(ll a, ll b) {
	a %= MOD;b %= MOD;
	a += MOD;
	return (a - b) % MOD;
}
inline ll mmul(ll a, ll b) {
	a %= MOD;b %= MOD;
	return (a*b) % MOD;
}
inline ll mpow(ll a, ll r) {
	long long res = 1;
	while (r > 0) {
		if (r & 1) res = res * a % MOD;
		a = a * a % MOD;
		r >>= 1;
	}
	return res;
}
inline ll minv(ll a) {
	a %= MOD;
	ll b = MOD, u = 0, v = 1;
	while (a) {
		ll t = b / a;
		b -= t * a; swap(a, b);
		u -= t * v; swap(u, v);
	}
	if (u < 0) u += MOD;
	return u;
}
inline ll mdiv(ll a, ll b) {
	a %= MOD;
	a *= minv(b);
	return a%MOD;
}

struct UnionFind {
	vector<int> data;
	UnionFind(int size) : data(size, -1) { }
	bool unite(int x, int y) {
		x = root(x); y = root(y);
		if (x != y) {
			if (data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
		}
		return x != y;
	}
	bool same(int x, int y) {
		return root(x) == root(y);
	}
	int root(int x) {
		return data[x] < 0 ? x : data[x] = root(data[x]);
	}
	int size(int x) {
		return -data[root(x)];
	}
};

/*int V;
vector<edge> G[MAX_V];
int d[MAX_V]:
void dijkstra(int s) {
priority_queue<P, vector<P>, greater<P>> q;
fill(d, d + V, INF);


}*/


//ll fact[100001], fact_inv[100001];
/*
ll combi(int a, int b) {
	return mmul(fact[a], mmul(fact_inv[b], fact_inv[a - b]));
}
*/
int main(void) {
	//fact[0] = 1;
	//fact_inv[0] = 1;
	/*REP(i, 100000) {
		fact[i + 1] = mmul(fact[i], i + 1);
		fact_inv[i + 1] = minv(fact[i + 1]);
	}*/
	int n, m, c, d,donecnt=0;
	cin >> n >> m;

	vector<int> is_ok(n, 1);
	vector<P> res;
	vector<vector<int>> v(n);
	vector<vector<int>> nodes(n);
	vector<int> depth(n);
	vector<bool> visited(n, false), visited2(n, false);
	queue<int> q;

	UnionFind uf(n);

	REP(i, m) {
		cin >> c >> d;c--;d--;
		if (uf.same(c, d)) {
			is_ok[c] *= -1;
			res.push_back(P(c+1, d+1));
		}
		else {
			v[c].push_back(d);
			v[d].push_back(c);
			//edgnum[c]++;
			//edgnum[d]++;
			uf.unite(c, d);
		}
	}
	q.push(0);
	depth[0] = 0;
	visited[0] = true;
	int maxdep = 0;
	while(!q.empty()){
		int ind = q.front();
		q.pop();
		for (int e : v[ind]) {
			if (!visited[e]) {
				visited[e] = true;
				q.push(e);
				depth[e] = depth[ind] + 1;
				nodes[depth[e]].push_back(e);
				maxdep = max(maxdep, depth[e]);
			}
		}
	}
	RFOR(i, maxdep, 0) {
		for (int e : nodes[i]) {
			visited2[e] = true;
			for (int ee : v[e]) {
				if (!visited2[ee]) {
					if (is_ok[e] == 1) {
						is_ok[ee] *= -1;
						res.push_back(P(ee+1, e+1));
					}
					else {
						res.push_back(P(e+1, ee+1));
					}
				}
			}
		}
	}
	if (is_ok[0] == 1) {
		for (P p : res) {
			cout << p.first << " " << p.second << endl;
		}
	}
	else {
		cout << -1 << endl;
	}


	return 0;
}

Measured memory_bytes: 14836