#include <bits/stdc++.h>
using namespace std;
const int nmax = 2e5;
int n, m;
int b[nmax + 5], t[nmax + 5];
vector<pair<int,int>> l[nmax + 5];
int sel[nmax + 5];
int nr = 0;
int found = 0;
bool open = false;
vector<pair<int,int>> rez;
bool over(int a)
{
    if(l[a].front().second != 1 || l[a].back().second != 1)
    {
        return false;
    }
    return true;
}
void dfs(int nod, int poz, bool lvl)
{
    if(lvl == 0 && t[poz] == 0)
    {
        open = true;
    }
    if(over(nod) && sel[nod] == 0)
    {
        ++found;
    }
    if(!sel[nod])
    {
        ++nr;
    }
    ++sel[nod];
    if(sel[nod] == 1)
    {
        for(auto it : l[nod])
        {
            if(poz == it.first && lvl == it.second)
            {
                continue;
            }
            dfs(nod, it.first, it.second);
        }
    }
    if(lvl == 0)
    {
        if(t[poz] != 0 && !sel[t[poz]])
        {
            dfs(t[poz], poz, 1);
        }
    }
    else
    {
        if(b[poz] != 0  && !sel[b[poz]])
        {
            dfs(b[poz], poz, 0);
        }
    }
}
bool make_move_0()
{
    int val = 0;
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 0 && !t[l[i].front().first] && l[i].back().second == 0 && !t[l[i].back().first])
        {
            val = i;
            break;
        }
    }
    if(val)
    {
        int poz = l[val].front().first;
        rez.push_back({l[val].back().first, poz});
        b[l[val].back().first] = 0;
        t[poz] = val;
        l[val].clear();
        l[val].push_back({poz, 0});
        l[val].push_back({poz, 1});
        return true;
    }
    int poz_from = 0, poz_to = 0;
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 0 && !t[l[i].front().first] && l[i].back().second == 1)
        {
            val = i;
            poz_from = l[i].back().first;
            poz_to = l[i].front().first;
            break;
        }
        if(l[i].back().second == 0 && !t[l[i].back().first] && l[i].front().second == 1)
        {
            val = i;
            poz_from = l[i].front().first;
            poz_to = l[i].back().first;
            break;
        }
    }
    if(val)
    {
        rez.push_back({poz_from, poz_to});
        t[poz_from] = 0;
        t[poz_to] = val;
        l[val].clear();
        l[val].push_back({poz_to, 0});
        l[val].push_back({poz_to, 1});
        return true;
    }
    return false;
}
bool make_move_1()
{
    int poz_empty = 0;
    for(int i=1;i<=m;i++)
    {
        if(!b[i])
        {
            poz_empty = i;
            break;
        }
    }
    if(!poz_empty)
    {
        return false;
    }
    int poz = 0;
    int val = 0;
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 0 && !t[l[i].front().first] && l[i].back().second == 0 && l[t[l[i].back().first]].front().second == 1 && l[t[l[i].back().first]].back().second == 1)
        {
            val = t[l[i].back().first];
            poz = l[i].back().first;
            break;
        }
        if(l[i].back().second == 0 && !t[l[i].back().first] && l[i].front().second == 0 && l[t[l[i].front().first]].front().second == 1 && l[t[l[i].front().first]].back().second == 1)
        {
            val = t[l[i].front().first];
            poz = l[i].front().first;
            break;
        }
    }
    if(val)
    {
        rez.push_back({poz, poz_empty});
        t[poz] = 0;
        b[poz_empty] = val;
        for(int i=0;i<2;i++)
        {
            if(l[val][i].first == poz)
            {
                l[val][i].first = poz_empty;
                l[val][i].second = 0;
                break;
            }
        }
        return true;
    }
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 1 && l[i].back().second == 0 && l[t[l[i].back().first]].front().second == 1 && l[t[l[i].back().first]].back().second == 1)
        {
            val = t[l[i].back().first];
            poz = l[i].back().first;
            break;
        }
        if(l[i].back().second == 1 && l[i].front().second == 0 && l[t[l[i].front().first]].front().second == 1 && l[t[l[i].front().first]].back().second == 1)
        {
            val = t[l[i].front().first];
            poz = l[i].front().first;
            break;
        }
    }
    if(val)
    {
        rez.push_back({poz, poz_empty});
        t[poz] = 0;
        b[poz_empty] = val;
        for(int i=0;i<2;i++)
        {
            if(l[val][i].first == poz)
            {
                l[val][i].first = poz_empty;
                l[val][i].second = 0;
                break;
            }
        }
        return true;
    }
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 0 && l[i].back().second == 0 && t[l[i].front().first] == t[l[i].back().first])
        {
            val = t[l[i].back().first];
            poz = l[i].back().first;
            break;
        }
    }
    if(val)
    {
        rez.push_back({poz, poz_empty});
        t[poz] = 0;
        b[poz_empty] = val;
        for(int i=0;i<2;i++)
        {
            if(l[val][i].first == poz)
            {
                l[val][i].first = poz_empty;
                l[val][i].second = 0;
                break;
            }
        }
        return true;
    }
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 0 && !t[l[i].front().first] && l[i].back().second == 0)
        {
            val = t[l[i].back().first];
            poz = l[i].back().first;
            break;
        }
        if(l[i].back().second == 0 && !t[l[i].back().first] && l[i].front().second == 0)
        {
            val = t[l[i].front().first];
            poz = l[i].front().first;
            break;
        }
    }
    if(val)
    {
        rez.push_back({poz, poz_empty});
        t[poz] = 0;
        b[poz_empty] = val;
        for(int i=0;i<2;i++)
        {
            if(l[val][i].first == poz)
            {
                l[val][i].first = poz_empty;
                l[val][i].second = 0;
                break;
            }
        }
        return true;
    }
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 1 && l[i].back().second == 0)
        {
            val = t[l[i].back().first];
            poz = l[i].back().first;
            break;
        }
        if(l[i].back().second == 1 && l[i].front().second == 0)
        {
            val = t[l[i].front().first];
            poz = l[i].front().first;
            break;
        }
    }
    if(val)
    {
        rez.push_back({poz, poz_empty});
        t[poz] = 0;
        b[poz_empty] = val;
        for(int i=0;i<2;i++)
        {
            if(l[val][i].first == poz)
            {
                l[val][i].first = poz_empty;
                l[val][i].second = 0;
                break;
            }
        }
        return true;
    }
    return false;
}
bool make_move_2()
{
    int poz_empty = 0;
    for(int i=1;i<=m;i++)
    {
        if(!b[i])
        {
            poz_empty = i;
            break;
        }
    }
    if(!poz_empty)
    {
        return false;
    }
    int val = 0;
    int poz1 = 0, poz2 = 0;
    for(int i=1;i<=n;i++)
    {
        if(l[i].front().second == 1 && l[i].back().second == 1)
        {
            val = i;
            poz1 = l[i].front().first;
            poz2 = l[i].back().first;
            break;
        }
    }
    if(val)
    {
        rez.push_back({poz1, poz_empty});
        rez.push_back({poz2, poz_empty});
        t[poz1] = t[poz2] = 0;
        b[poz_empty] = t[poz_empty] = val;
        l[val].clear();
        l[val].push_back({poz_empty, 0});
        l[val].push_back({poz_empty, 1});
        return true;
    }
    return false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
#ifdef home
    freopen("nr.in","r",stdin);
    freopen("nr.out","w",stdout);
#endif // home
    cin>>n>>m;
    bool done = true;
    for(int i=1; i<=m; i++)
    {
        cin>>b[i]>>t[i];
        l[b[i]].push_back({i, 0});
        l[t[i]].push_back({i, 1});
        if(t[i] != b[i])
        {
            done = false;
        }
    }
    if(n == m && !done)
    {
        cout<<-1<<'\n';
        return 0;
    }
    if(n > 1000)
    {
        bool ok = false;
        int rez = 0;
        for(int i=1; i<=m; i++)
        {
            nr = 0;
            found = 0;
            open = false;
            if(t[i] != 0 && !sel[t[i]])
            {
                dfs(t[i], i, 1);
            }
            else if(b[i] != 0 && !sel[b[i]])
            {
                dfs(b[i], i, 0);
            }
            if(nr <= 1)
            {
                continue;
            }
            rez += (nr + (found > 1) * (found - 1) + 1);
            if(found > 1)
            {
                ok = true;
            }
        }
        if(ok && m == n + 1)
        {
            cout<<-1<<'\n';
            return 0;
        }
        cout<<rez<<'\n';
        return 0;
    }
    while(true)
    {
        int cnt_left = 0;
        for(int i=1;i<=n;i++)
        {
            if(l[i].front().first == l[i].back().first)
            {
                continue;
            }
            ++cnt_left;
        }
        if(cnt_left == 0)
        {
            break;
        }
        if(make_move_0())
        {
            continue;
        }
        if(make_move_1())
        {
            continue;
        }
        if(make_move_2())
        {
            continue;
        }
        cout<<-1<<'\n';
        return 0;
    }
    cout<<rez.size()<<'\n';
    for(auto it : rez)
    {
        cout<<it.first<<' '<<it.second<<'\n';
    }
    return 0;
}
| # | 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... |