#include <stdio.h>  
#include <algorithm>  
#include <assert.h>
#include <bitset>
#include <cmath>  
#include <complex>  
#include <deque>  
#include <functional>  
#include <iostream>  
#include <limits.h>  
#include <map>  
#include <math.h>  
#include <queue>  
#include <set>  
#include <stdlib.h>  
#include <string.h>  
#include <string>  
#include <time.h>  
#include <unordered_map>  
#include <unordered_set>  
#include <vector>  
#include <chrono>
#include <random>
#include <time.h>
#include <fstream>
#define ll long long
#define rep2(i,a,b) for(ll i=a;i<=b;++i)
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep3(i,a,b) for(ll i=a;i>=b;i--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pq priority_queue<int>
#define pqg priority_queue<int,vector<int>,greater<int>>
#define pb push_back
#define vec vector<int>
#define vecll vector<ll>
#define vecpii vector<pii>
#define endl "\n"
#define all(c) begin(c),end(c)
using namespace std;
int in() {int x;scanf("%d",&x);return x;}
ll lin() {ll x;scanf("%lld",&x);return x;}

#define INF 1e9+7
#define LLINF 1e18+7
#define N 250000
ll MOD=1e9+7;


vector<vector<pii> > G(N);
vector<int> sta(N,-2);
vec used(N);
vector<pii> ed;
vector<int> res(N);
struct UnionFind{
    vector<int> par,sizes;
    UnionFind(int n):par(n+1),sizes(n+1,1){
        rep2(i,1,n)par[i]=i;
    }
    int find(int x){
        return (x==par[x]?x:par[x]=find(par[x]));
    }
    void unite(int x,int y){
        x=find(x);y=find(y);
        if(x==y)return ;
        if(sizes[x]<sizes[y]){
            swap(x,y);
        }
        par[y]=x;
        sizes[x]+=sizes[y];
    }
    bool same(int x,int y) {return (find(x)==find(y));}
    int size(int x) {return sizes[find(x)];}
};
void dfs(int x,int p,int rs){
    int t=0;
    vector<pii> s;
    for(auto e:G[x]){
        if(e.first!=p&&sta[e.second]!=-2)s.pb(e);
    }
    if(s.size()==0){
        if(rs)
        res[x]++;
        return;
    }
    else{
        rep(i,s.size()-1){
            sta[s[i].second]=x;
            dfs(s[i].first,x,0);
        }
        if((s.size()+rs)%2){
            sta[s[s.size()-1].second]=s[s.size()-1].first;
            dfs(s[s.size()-1].first,x,1);
        }
        else{
            sta[s[s.size()-1].second]=x;
            dfs(s[s.size()-1].first,x,0);
        }
    }
}

int dfs2(int x,int p,int num){
    for(auto e:G[x]){
        if(e.first!=p&&sta[e.second]>0){
            res[x]+=dfs2(e.first,x,e.second);
        }
    }
    res[x]%=2;
    if(res[x]&&p!=0){
        if(sta[num]==x)sta[num]=p;
        else sta[num]=x;
    }
    return res[x];
}
main(){
    int n=in(),m=in();
    rep(i,m){
        int a=in(),b=in();
        G[a].pb({b,i});
        G[b].pb({a,i});
        ed.pb({a,b});
    }
    UnionFind uf(n);
    rep(i,m){
        if(!uf.same(ed[i].first,ed[i].second)){
            uf.unite(ed[i].first,ed[i].second);
            sta[i]=0;
        }
    }
    dfs(1,0,0);
    rep(i,m){
        if(sta[i]==-2){
            sta[i]=-ed[i].first;
            res[ed[i].first]++;
        }
    }
    dfs2(1,0,0);
    if(m%2){
        cout<<-1;
    }
    else{
        rep(i,m){
            cout<<abs(sta[i])<<" ";
            if(abs(sta[i])==ed[i].first)cout<<ed[i].second;
            else cout<<ed[i].first;
            cout<<endl;
        }
    }
}



Measured memory_bytes: 26868