// Slower C++ solution:
#include <bits/stdc++.h>

#define int long long

#define mod (int)(1e9+7)

#define inf (int)(3e18+7)

#define rep(i,n) for(int i=0;i<n;i++)

#define REP(i,n) for(int i=1;i<n;i++)

#define P pair<int,int>

#define PiP pair<int,pair<int,int>>

#define all(v) v.begin(),v.end()

#define mkp make_pair

#define mkt make_tuple

#define prique(T) priority_queue<T,vector<T>,greater<T>>

#define vecunique(vec) sort(vec.begin(), vec.end());decltype(vec)::iterator result = std::unique(vec.begin(), vec.end());vec.erase(result, vec.end())

using namespace std;



bool prime(int x) {

	for (int i = 2; i * i <= x; i++) {

		if (x % i == 0)return false;

	}

	return x > 1;

}

int gcd(int x, int y) {

	if (y == 0)return x;

	return gcd(y, x % y);

}

int lcm(int x, int y) {

	return x / gcd(x, y) * y;

}

int kai(int x, int y) {

	int res = 1;

	for (int i = x - y + 1; i <= x; i++) {

		res *= i; res %= mod;

	}

	return res;

}

int mod_pow(int x, int y) {

	int res = 1;

	while (y > 0) {

		if (y & 1) {

			res = res * x % mod;

		}

		x = x * x % mod;

		y >>= 1;

	}

	return res;

}

int comb(int x, int y) {

	if (y > x)return 0;

	return kai(x, y) * mod_pow(kai(y, y), mod - 2) % mod;

}

/*--------Library Zone!--------*/



int n, m;

vector<int>G[114514];

int a[114514], b[114514];

int depth[114514], par[114514];

int hon[114514];

vector<P>ans;

set<P>st;

void dfs(int x) {

	rep(i, G[x].size()) {

		int to = G[x][i];

		if (depth[to] == -1) {

			par[to] = x; depth[to] = depth[x] + 1;

			st.insert({ min(to,x),max(to,x) });

			dfs(to);

		}

	}

}

signed main() {

	cin >> n >> m;

	if (m % 2) {

		cout << -1 << endl; return 0;

	}

	rep(i, m) {

		cin >> a[i] >> b[i];

		a[i]--; b[i]--;

		G[a[i]].push_back(b[i]);

		G[b[i]].push_back(a[i]);

	}

	REP(i, n)depth[i] = -1;

	dfs(0);

	rep(i, m) {

		if (st.find(make_pair(min(a[i], b[i]), max(a[i], b[i]))) == st.end()) {

			ans.push_back({ a[i],b[i] });

			hon[a[i]]++;

		}

	}

	vector<P>kouho;

	rep(i, n) {

		kouho.push_back({ depth[i],i });

	}

	sort(all(kouho), greater<>());

	rep(i, n - 1) {

		if (hon[kouho[i].second] % 2) {

			ans.push_back({ kouho[i].second,par[kouho[i].second] });

		}

		else {

			ans.push_back({ par[kouho[i].second],kouho[i].second });

			hon[par[kouho[i].second]]++;

		}

	}

	for (auto p : ans)cout << p.first + 1 << " " << p.second + 1 << endl;

}

// Faster C++ solution for the same problem (measured speedup: 1.106472537053604x):
#include<bits/stdc++.h>

using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<n;i++)

#define REP(i,n) for(int i=1;i<n;i++)

#define all(v) v.begin(),v.end()

#define P pair<int,int>

#define len(s) (int)s.size()

#define pb push_back



template<class T> inline bool chmin(T &a, T b){

	if(a>b){a=b;return true;}

	return false;

}

template<class T> inline bool chmax(T &a, T b){

	if(a<b){a=b;return true;}

	return false;

}

constexpr int mod = 1e9+7;

constexpr int inf = 3e18;



int N,M,dist[100005];

vector<P>G[100005];

bool used[100005],used2[100005];

void bfs(){

	queue<int>que;

	REP(i,N)dist[i]=inf;

	dist[0]=0;que.push(0);

	while(!que.empty()){

		int i=que.front();que.pop();

		for(auto j:G[i]){

			if(dist[j.first]==inf){

				dist[j.first]=dist[i]+1;

				que.push(j.first);

			}

		}

	}

}

int cnt[100005];

void dfs(int x){

	used[x]=true;

	for(auto i:G[x])if(!used[i.first]&&dist[i.first]==dist[x]+1)dfs(i.first);

	vector<int>v;

	for(auto i:G[x]){

		if(dist[i.first]==dist[x]&&!used2[i.second]){

			cout<<x+1<<" "<<i.first+1<<endl;

			used2[i.second]=true;

			cnt[x]++;

		}else if(dist[i.first]==dist[x]-1){

			v.pb(i.first);

		}

	}

	if((cnt[x]+len(v))&1){

		rep(i,len(v)-1){

			cout<<x+1<<" "<<v[i]+1<<endl;

		}

		cout<<v.back()+1<<" "<<x+1<<endl;

		cnt[v.back()]++;

	}else {

		for(int i:v){

			cout<<x+1<<" "<<i+1<<endl;

		}

	}

}

signed main(){

	cin>>N>>M;

	if(M%2){

		cout<<-1<<endl;return 0;

	}

	rep(i,M){

		int a,b;cin>>a>>b;a--;b--;

		G[a].pb({b,i});G[b].pb({a,i});

	}

	bfs();

	dfs(0);

}