#include <bits/stdc++.h>
// Graph.h start--------------------------------------------
#pragma once

#include <vector>

using Weight = long long;

struct Vertex;
using Vertices = std::vector<Vertex>;
struct Edge;
using Edges = std::vector<Edge>;

struct Vertex
{
	const int id;
	Edges edges;
	std::vector<int> ids_dst;

	Vertex(const int id);
	Vertex(const Vertex &rhs);
	void add_edge(const Edge &e);
};

struct Edge
{
	const int id_src, id_dst;
	Weight weight;

	Edge(const int id_src, const int id_dst, const Weight weight);
	Edge(const Edge &rhs);
};

struct Graph
{
	Vertices vertices;
	Edges edges;

	Graph(const int nvertices);
	Graph();
	Graph(const Graph &rhs);
	void add_edge(const Edge &edge);
	void add_edge(const int id_src, const int id_dst, const Weight w);
};

//----------------------------------------------------------

using namespace std;

Vertex::Vertex(const int id) : id(id) {}
Vertex::Vertex(const Vertex &rhs) : id(rhs.id), edges(rhs.edges), ids_dst(rhs.ids_dst) {}
void Vertex::add_edge(const Edge &e)
{
	edges.push_back(e);
	ids_dst.push_back(e.id_dst);
}

Edge::Edge(const int id_src, const int id_dst, const Weight weight) : id_src(id_src), id_dst(id_dst), weight(weight) {}
Edge::Edge(const Edge &rhs) : id_src(rhs.id_src), id_dst(rhs.id_dst), weight(rhs.weight) {}
bool operator<(const Edge &e1, const Edge &e2)
{
	return e1.weight != e2.weight ? e1.weight > e2.weight : // !!INVERSE!!
			   e1.id_src != e2.id_src ? e1.id_src < e2.id_src : e1.id_dst < e2.id_dst;
}

Graph::Graph(const int nvertices)
{
	for (int id = 0; id < nvertices; id++)
		vertices.push_back(Vertex(id));
}
Graph::Graph() : Graph(0) {}
Graph::Graph(const Graph &rhs) : vertices(rhs.vertices), edges(rhs.edges) {}
void Graph::add_edge(const Edge &edge)
{
	edges.push_back(edge);
	vertices[edge.id_src].add_edge(edge);
}
void Graph::add_edge(const int id_src, const int id_dst, const Weight w = 1)
{
	add_edge(Edge(id_src, id_dst, w));
}

// Graph.h end----------------------------------------------

using namespace std;

using ll = long long int;
using pii = pair<int, int>;

int main()
{
    int N, M;
    cin >> N >> M;
    vector<int> A(M), B(M);
    for (int i = 0; i < M; i++)
    {
        cin >> A[i] >> B[i];
        A[i]--;
        B[i]--;
    }

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

    Graph g(N);
    for (int i = 0; i < M; i++)
    {
        g.add_edge(A[i], B[i]);
        g.add_edge(B[i], A[i]);
    }

    // make tree
    stack<int> stack_nodes;
    vector<int> parents(N);
    Edges edges_unnecessary;
    {
        int id_root = 0;
        vector<bool> is_visited(N, false);
        queue<int> q;
        is_visited[id_root] = true;
        q.push(id_root);
        parents[id_root] = -1;
        while (!q.empty())
        {
            const int id_src = q.front();
            q.pop();
            for (const Edge edge : g.vertices[id_src].edges)
            {
                const int id_dst = edge.id_dst;
                if (is_visited[id_dst])
                {
                    edges_unnecessary.push_back(edge);
                }
                else
                {
                    is_visited[id_dst] = true;
                    q.push(id_dst);
                    stack_nodes.push(id_dst);
                    parents[id_dst] = id_src;
                }
            }
        }
    }

    // allot directions for unnecessary edges

    // cout << "stack_nodes" << endl;
    // while (!stack_nodes.empty())
    // {
    //     int n = stack_nodes.top();
    //     stack_nodes.pop();
    //     cout << n << " ";
    // }
    // cout << endl;
    // cout << "parents" << endl;
    // for (const int parent : parents)
    // {
    //     cout << parent << " ";
    // }
    // cout << endl;
    // cout << "edges_unnecessary" << endl;
    // for (const Edge edge : edges_unnecessary)
    // {
    //     cout << edge.id_src << " " << edge.id_dst << endl;
    // }
    // cout << endl;
    vector<int> states_node(N, 0);
    Graph g_ans(N);
    {
        set<pii> set_used;
        for (const Edge edge : edges_unnecessary)
        {
            const int id_src = edge.id_src, id_dst = edge.id_dst;
            if (parents[id_src] == id_dst)
                continue;
            const int id_small = min(id_src, id_dst), id_big = max(id_src, id_dst);
            if (set_used.insert(pii(id_small, id_big)).second)
            {
                states_node[id_small]++;
                g_ans.add_edge(id_small, id_big);
            }
        }
    }

    // decide directions for edges of tree
    while (!stack_nodes.empty())
    {
        const int id_child = stack_nodes.top();
        const int id_parent = parents[id_child];
        stack_nodes.pop();
        int id_src, id_dst;
        if ((states_node[id_child] % 2) != 0)
        {
            id_src = id_child;
            id_dst = id_parent;
        }
        else
        {
            id_src = id_parent;
            id_dst = id_child;
        }
        states_node[id_src]++;
        g_ans.add_edge(id_src, id_dst);
    }

    for (const Edge &edge : g_ans.edges)
    {
        cout << edge.id_src + 1 << " " << edge.id_dst + 1 << endl;
    }

    return 0;
}

Measured memory_bytes: 37356