#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
//#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
struct UnionFind {
    vector<int> par; // 親ノード
    vector<int> rank; // ランク

    UnionFind(int n = 1) {
        init(n);
    }

    void init(int n = 1) {
        par.resize(n); rank.resize(n);
        for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0;
    }

    int root(int x) {
        if (par[x] == x) {
            return x;
        }
        else {
            int r = root(par[x]);
            return par[x] = r;
        }
    }

    bool issame(int x, int y) {
        return root(x) == root(y);
    }

    bool merge(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (rank[x] < rank[y]) swap(x, y);
        if (rank[x] == rank[y]) ++rank[x];
        par[y] = x;
        return true;
    }
};

struct Edge
{
public:
    Edge(int to, int dir) : to(to), dir(dir) {}
    int to;
    int dir;
};

using Edges = vector<Edge>;
using Graph = vector<Edges>;

void DFS(Graph& g, int curr, int prev, vector<bool>& visited)
{
    visited[curr] = true;

    for (const auto& e : g[curr])
    {
        if (e.dir == 0)
        {
            if (visited[e.to])
            {
                continue;
            }
            
            DFS(g, e.to, curr, visited);
        }
    }

    if (prev == -1)
    {
        return;
    }

    int outNum = 0;
    for (const auto& e : g[curr])
    {
        if (e.dir == 1)
        {
            ++outNum;
        }
    }

    if (outNum % 2 == 0)
    {
        for (auto& e : g[curr])
        {
            if (e.to == prev)
            {
                e.dir = -1;

                for (auto& f : g[prev])
                {
                    if (f.to == curr)
                    {
                        f.dir = 1;
                        break;
                    }
                }

                break;
            }
        }
    }
    else
    {
        for (auto& e : g[curr])
        {
            if (e.to == prev)
            {
                e.dir = 1;

                for (auto& f : g[prev])
                {
                    if (f.to == curr)
                    {
                        f.dir = -1;
                        break;
                    }
                }
                
                break;
            }
        }
    }
}

void _main()
{
    int N, M;
    cin >> N >> M;
    Graph g(N);
    UnionFind uf(N);
    rep(i, 0, M)
    {
        int A, B;
        cin >> A >> B;
        --A; --B;

        if (uf.issame(A, B))
        {
            g[A].emplace_back(B, 1);
            g[B].emplace_back(A, -1);
        }
        else
        {
            uf.merge(A, B);

            g[A].emplace_back(B, 0);
            g[B].emplace_back(A, 0);
        }
    }

    if (M % 2 != 0)
    {
        cout << -1 << endl;
        return;
    }

    vector<bool> visited(N, false);
    DFS(g, 0, -1, visited);

    rep(i, 0, N)
    {
        for (const auto& e : g[i])
        {
            if (e.dir == 1)
            {
                cout << i + 1 << " " << e.to + 1 << endl;
            }
        }
    }
}


Measured memory_bytes: 14336