#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define sp <<" "<<
#define endl "\n"
void solve() {
    int n, m; cin >> n >> m;
    vector<int> spot(2*m), oth(2*m, -1);
    vector<vector<int>> at(n);
    for (int i = 0; i < 2*m; i++) {
        cin >> spot[i];
        if (--spot[i] == -1) continue;
        at[spot[i]].push_back(i);
    }
    int cnt = 0;
    unordered_set<int> top;
    vector<vector<int>> bot(n), tob(n);
    vector<int> empty, below, above, link;
    auto flatten = [&](int x, int i) -> void {
        int j = oth[i];
        if (bot[x].size() == 1) {
            below.push_back(x);
        } else if (top.count(j)) {
            link.push_back(x);
        }
        bot[x].push_back(i);
    };
    auto combine = [&](int x, int i) -> void {
        int j = oth[i];
        if (bot[x].size() == 1) {
            link.push_back(x);
        } else if (top.count(j)) {
            above.push_back(x);
        }
        top.insert(i);
        tob[x].push_back(i);
    };
    for (int i = 0; i < n; i++) {
        int u = at[i].front(), v = at[i].back();
        if (u/2 == v/2) continue;
        oth[u] = v, oth[v] = u;
    }
    for (int i = 0; i < 2*m; i+=2) {
        int a = spot[i], b = spot[i+1];
        if (a == -1 and b == -1) {
            empty.push_back(i);
            continue;
        }
        if (a != -1 and b == -1) {
            flatten(a, i);
            continue;
        }
        if (a == -1) continue;
        if (a == b) {
            cnt += 2;
            continue;
        }
        combine(b, i+1);
    }
    vector<pair<int, int>> moves;
    int prev = -1;
    while (cnt != 2*n and prev != cnt) {
        prev = cnt;
        while (!below.empty()) {
            int x = below.back(); below.pop_back();
            int u = at[x].front(), v = at[x].back();
            spot[u|1] = spot[u];
            spot[v] = -1;
            moves.emplace_back(v, u|1);
            cnt += 2;
            break;
        }
        while (!link.empty()) {
            int x = link.back(); link.pop_back();
            int u = bot[x].front(), v = oth[u];
            spot[u|1] = spot[u];
            spot[v] = -1;
            moves.emplace_back(v, u|1);
            flatten(spot[v^1], v^1);
            cnt += 2;
            break;
        }
        while (!above.empty()) {
            int x = above.back(); above.pop_back();
            int u = tob[x].front(), v = tob[x].back();
            if (empty.empty()) {
                cout << -1 << endl;
                return;
            }
            int l = empty.back(); empty.pop_back();
            spot[l] = spot[u];
            spot[u] = -1;
            moves.emplace_back(u, l);
            flatten(spot[u^1], u^1);
            spot[l|1] = spot[v];
            spot[v] = -1;
            moves.emplace_back(v, l|1);
            flatten(spot[v^1], v^1);
            cnt += 2;
            break;
        }
    }
    for (int i = 0; i < 2*m; i+=2) {
        if (spot[i] != spot[i+1]) {
            cout << -1 << endl;
            return;
        }
    }
    
    cout << moves.size() << endl;
    for (auto &[x, y] : moves) {
        cout << (x/2 + 1) sp (y/2 + 1) << endl;
    }
}
signed main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |