#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/rope>
using namespace std;
using namespace chrono;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
mt19937 rng(high_resolution_clock::now().time_since_epoch().count());
mt19937_64 rngll(high_resolution_clock::now().time_since_epoch().count());
template<typename T> T ctmax(T &x, const T &y){ return x = max(x, y); }
template<typename T> T ctmin(T &x, const T &y){ return x = min(x, y); }
template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

struct binary_lift: vector<vector<int>>{
	int N, root, lg;
	vector<vector<int>> up;
	vector<int> depth;
	binary_lift(int N, int root): N(N), root(root), lg(ceil(log2(N))), depth(N), up(N, vector<int>(lg + 1)){
		this->resize(N);
	}
	void insert(int u, int v){ (*this)[u].push_back(v), (*this)[v].push_back(u); }
	void init(){ dfs(root, root); }
	void dfs(int u, int p){
		up[u][0] = p;
		for(int i = 1; i <= lg; ++ i) up[u][i] = up[up[u][i - 1]][i - 1];
		for(auto &v: (*this)[u]) if(v != p){
			depth[v] = depth[u] + 1;
			dfs(v, u);
		}
	}
	int lca(int u, int v){
		if(depth[u] < depth[v]) std::swap(u, v);
		u = trace_up(u, depth[u] - depth[v]);
		for(int d = lg; d >= 0; -- d) if(up[u][d] != up[v][d]) u = up[u][d], v = up[v][d];
		return u == v ? u : up[u][0];
	}
	int dist(int u, int v){
		return depth[u] + depth[v] - 2 * depth[lca(u, v)];
	}
	int trace_up(int u, int dist){
		if(dist >= depth[u] - depth[root]) return root;
		for(int d = lg; d >= 0; -- d) if(dist & (1 << d)) u = up[u][d];
		return u;
	}
};

int main(){
	cin.tie(0)->sync_with_stdio(0);
	int n, m;
	cin >> n >> m;
	if(m % 2){
		cout << "-1";
		return 0;
	}
	vector<vector<pair<int, int>>> adj(n);
	vector<int> deg(n), cnt(n);
	vector<pair<int, int>> res(m);
	for(int i = 0; i < m; ++ i){
		int u, v;
		cin >> u >> v, -- u, -- v;
		adj[u].emplace_back(v, i), adj[v].emplace_back(u, i);
		res[i] = {u, v};
		++ cnt[u];
	}
	vector<int> visited(n);
	binary_lift lift(n, 0);
	function<void(int)> dfs = [&](int u){
		visited[u] = true;
		for(auto i = 0; i < int(adj[u].size()); ++ i){
			int v, e;
			tie(v, e) = adj[u][i];
			if(!visited[v]){
				lift.insert(u, v);
				dfs(v);
			}
		}
	};
	dfs(0);
	lift.init();
	vector<int> mark;
	for(auto u = 0; u < n; ++ u){
		if(cnt[u] % 2){
			mark.push_back(u);
		}
	}
	fill(cnt.begin(), cnt.end(), 0);
	for(auto i = 0; i < int(mark.size()); i += 2){
		int u = mark[i], v = mark[i + 1], w = lift.lca(u, v);
		++ cnt[u], ++ cnt[v], cnt[w] -= 2;
	}
	fill(visited.begin(), visited.end(), false);
	function<void(int, int)> solve = [&](int u, int p){
		visited[u] = true;
		for(auto i = 0; i < int(adj[u].size()); ++ i){
			int v, e;
			tie(v, e) = adj[u][i];
			if(!visited[v]){
				solve(v, e);
				cnt[u] += cnt[v];
			}
		}
		if(cnt[u] % 2){
			swap(res[p].first, res[p].second);
		}
	};
	solve(0, -1);
	for(auto i = 0; i < m; ++ i){
		cout << res[i].first + 1 << " " << res[i].second + 1 << "\n";
	}
	cout << "\n";
	return 0;
}

/*

*/

////////////////////////////////////////////////////////////////////////////////////////
//                                                                                    //
//                                   Coded by Aeren                                   //
//                                                                                    //
////////////////////////////////////////////////////////////////////////////////////////

Measured memory_bytes: 34560