#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <cassert>

#define int long long
#define MOD7 1000000007
#define MOD9 1000000009

#define rep(i, n) for (int i = 0; i < (n); i++)
#define itrep(i, a) for (auto i = (a).begin(); i != (a).end(); i++)
#define REP(i, a, n) for (int i = (a); i <= (n); i++)
#define all(a) (a).begin(), (a).end()
#define mp(a, b) make_pair((a), (b))

using namespace std;

int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, -1, 0, 1 };

template<class T> void inputVector(vector<T>& v, int n) {
    v.resize(n);
    for (int i = 0; i < v.size(); i++) cin >> v[i];
}

unsigned long randXor() {
    static unsigned long x = 123456789, y = 362436069, z = 521288629, w = 88675123;
    unsigned long t = (x ^ (x << 11));
    x = y;
    y = z;
    z = w;
    return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}

class SegmentTree {
private:
    struct Info {
        int value, index;

        Info() {}

        Info(int value, int index) {
            this->value = value;
            this->index = index;
        }
    };

    Info func(Info a, Info b) {
        return a.value <= b.value ? a : b;
    }

    int bottomSt, bottomEd;
    vector<Info> a;
    vector<int> rs, re;
    vector<Info> cand;

    Info set(int n) {
        int left = 2 * n + 1;
        int right = 2 * n + 2;
        if (left <= a.size() - 1) {
            a[n] = func(set(left), set(right));
            rs[n] = rs[left];
            re[n] = re[right];
        }
        return a[n];
    }

    void search(int s, int t, int n) {
        if (s <= rs[n] && re[n] <= t) {
            cand.push_back(a[n]);
            return;
        }
        int left = 2 * n + 1;
        int right = 2 * n + 2;
        if (s <= re[left]) search(s, t, left);
        if (rs[right] <= t) search(s, t, right);
    }

public:
    SegmentTree() {}

    SegmentTree(vector<int> &v) {
        bottomEd = 0;
        for (int i = 1, plus = 1; plus < v.size(); i++) {
            plus *= 2;
            bottomEd += plus;
        }
        a.resize(bottomEd + 1);
        rs.resize(bottomEd + 1);
        re.resize(bottomEd + 1);

        Info invalid = Info(0, -1);
        bottomSt = bottomEd / 2;

        for (int i = bottomSt; i <= bottomEd; i++) {
            int j = i - bottomEd / 2;
            a[i] = j < v.size() ? Info(v[j], j) : invalid;
            rs[i] = j;
            re[i] = j;
        }

        set(0);
    }

    int get(int index) {
        return a[bottomSt + index].value;
    }

    void update(int index, int x) {
        int pt = bottomSt + index;
        Info X = Info(x, index);
        a[pt] = X;
        while (pt > 0) {
            pt = (pt - 1) / 2;
            a[pt] = func(a[2 * pt + 1], a[2 * pt + 2]);
        }
    }

    Info find(int s, int t) {
        cand.clear();
        search(s, t, 0);
        Info ret = cand[0];
        for (int i = 1; i < cand.size(); i++) {
            ret = func(ret, cand[i]);
        }
        return ret;
    }
};

class Info {
public:
    int minValue;
    int minArg;
    int start, end;

    Info() {}

    Info(int value, int arg, int start, int end) {
        minValue = value;
        minArg = arg;
        this->start = start;
        this->end = end;
    }

    bool operator<(const Info &a) const {
        return minValue > a.minValue;
    }
};

struct Node {
    int id;
    int deg;
    unordered_set<int> nexts, nextsBackup;

    Node(int id) : id(id), deg(0) {
    }

    void init() {
        nexts = nextsBackup;
        deg = 0;
    }
};

const int INF = INT_MAX / 4;
vector<pair<int, int>> imp;

int N, M;
vector<Node> nodes;

void connect(int a, int b, vector<pair<int, int>> &ret, SegmentTree &tree, int &left) {
    nodes[a].nexts.erase(b);
    nodes[b].nexts.erase(a);
    nodes[a].deg++;
    ret.push_back(mp(a, b));
    tree.update(a, tree.get(a) - 1);
    tree.update(b, tree.get(b) - 1);
    left--;
}

vector<pair<int, int>> solve() {
    rep(i, N) nodes[i].init();

    vector<int> cnt(N);
    rep(i, N) cnt[i] = nodes[i].nexts.size();
    SegmentTree tree(cnt);

    int left[2] = {M, M};

    vector<pair<int, int>> ret;
    unordered_set<int> visited;
    rep(_, N) {
        int target = tree.find(0, N - 1).index;
        visited.insert(target);
        tree.update(target, INF);

        vector<pair<int, int>> prs; // nexts size, index
        for (auto &next : nodes[target].nexts) {
            int size = nodes[target].nexts.size();
            if (size == 0) continue;
            prs.push_back(mp(size, next));
        }
        sort(all(prs));

        rep(i, prs.size()) {
            auto &pr = prs[i];
            if (left[0] == 0) {
                if (nodes[target].deg % 2) return imp;
                if (nodes[pr.second].nexts.size() == 1 && nodes[pr.second].deg % 2 == 0) return imp;
                connect(pr.second, target, ret, tree, left[1]);
            } else if (left[1] == 0) {
                if (nodes[pr.second].nexts.size() == 1 && nodes[pr.second].deg % 2) return imp;
                connect(target, pr.second, ret, tree, left[0]);
            } else if (nodes[pr.second].nexts.size() == 1) {
                if (nodes[pr.second].deg % 2) connect(pr.second, target, ret, tree, left[1]);
                else connect(target, pr.second, ret, tree, left[0]);
            } else {
                if (i + 1 == prs.size()) {
                    if (nodes[target].deg % 2) connect(target, pr.second, ret, tree, left[0]);
                    else connect(pr.second, target, ret, tree, left[1]);
                } else {
                    if (randXor() % 2) connect(target, pr.second, ret, tree, left[0]);
                    else connect(pr.second, target, ret, tree, left[1]);
                }
            }
        }
    }

    if (ret.size() != M) return imp;
    for (auto &node : nodes) {
        if (node.deg % 2) return imp;
    }

    return ret;
}

signed main() {
    cin >> N >> M;

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

    rep(i, N) nodes.push_back(Node(i));

    rep(i, M) {
        int a, b;
        cin >> a >> b;
        a--; b--;
        nodes[a].nexts.insert(b);
        nodes[b].nexts.insert(a);
    }

    rep(i, N) {
        nodes[i].nextsBackup = nodes[i].nexts;
    }

    vector<pair<int, int>> v;

    int cnt = 0;
    while (v.empty() && cnt < 5) {
        v = solve();
        if (cnt == 0) v.clear();
        cnt++;
    }

    if (v.empty()) cout << -1 << endl;
    else {
        for (auto &pr : v) {
            cout << pr.first + 1 << " " << pr.second + 1 << endl;
        }
    }

    return 0;
}



Measured memory_bytes: 52964