Problem:
Problem H
パレード
ICPC 市では毎年7月に，ICPC City Parade Ceremony が開かれる．このお祭りでは多くの屋台が ICPC 市の路上に出店され，多くの市民が屋台を楽しんで巡る．あなたはこのお祭りを効率よく巡りたいと考えた．
ICPC 市は，1 から
N
までの番号のついた
N
か所の交差点と，
M
本の通りからなる．それぞれの通りは異なる 2 つの交差点を繋ぎ，双方向に通行可能である．複数の通りが同じ交差点の組を直接繋ぐことはない．どの 2 つの交差点についても，いくつかの通りを経由することで，互いに行き来することができる．
お祭りでは，屋台がすべての通りに出店される．お祭りを最大限楽しむためには，全ての屋台を巡るべきである．また，各屋台を何度も見物するのは飽きてしまうため，同じ屋台を 3 回以上通るのは避けたい．更に，同じ通りを連続で行き来するのは，見物したばかりの屋台を通ることになるので遠慮したい．つまり，同じ通りを 2 回通る場合には，間に別の通りを 1 つ以上挟むようにしたい．
果たしてその様な順路が存在するのかと気になったあなたは，ICPC 市の地図を元に，どの交差点の順番で通るべきか解析するプログラムを書くことにした．
ここで，順路とは，任意の交差点から始まり，今いる交差点から延びる通りを一つ選んで別の交差点へ移動することを繰り返し，任意の交差点で終わるものを指す．始めと終わりの交差点は，同じであっても，違っていてもよい．また，ある通りを移動している途中で，元いた交差点へ引き返してはならない．
Input
入力は
50
個以下のデータセットからなる．各データセットは次の形式で表される．
N
M
a
1
b
1
...
a
M
b
M
1 行目には，市の交差点の数を表す整数
N
と，通りの数を表す整数
M
が空白区切りで与えられる．
続く
M
行には， それぞれ空白で区切られた 1 以上
N
以下の相異なる整数
a
i
と
b
i
が与えられ，これは
i
番目の通りが交差点
a
i
と交差点
b
i
を繋いでいる事を表す．ここで，2 つ以上の通りが同じ交差点の組を直接繋ぐことはないことが保証される．
N
は
2
以上
20,000
以下，
M
は
1
以上
20,000
以下であることが保証される．
入力の終わりは空白区切りのゼロふたつの行で示す．
Output
各データセットに対し，問題文中の条件を満たす順路が存在するならば，順路上の交差点番号を順番に，空白区切りで一行に出力せよ．答えとしてあり得るものが複数ある場合は，どれを出力しても正解となる．もしもそのような順路が存在しないならば，代わりに -1 を一行に出力せよ．
なお，出力検証機の都合上，改行コードには LF または CR+LF のいずれかを使用せよ．他の問題と異なり，CR のみを使用した場合は誤答扱いとなる．
Sample Input
6 9
1 2
2 3
3 4
4 5
5 6
1 6
1 4
2 5
3 6
5 4
1 2
1 3
1 4
1 5
10 19
1 7
6 8
3 8
2 3
7 9
6 9
3 9
4 9
1 6
8 9
9 10
7 10
4 5
3 4
6 10
6 7
1 9
5 8
2 9
0 0
Output for the Sample Input
1 2 3 4 5 6 1 4 5 2 1 6 3
-1
4 9 6 10 9 2 3 8 9 1 6 10 7 1 9 3 4 5 8 6 7 9

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
}

vector<vector<pair<int,int>>> adj;
vector<int> e1, e2, rem_use, res;
vector<bool> onPath;
vector<int> par, pe;

void dfs(int u, int pe_id){
    while (true) {
        int ce = -1, v = -1;
        for (auto &p : adj[u]) {
            if (p.second != pe_id && rem_use[p.second] == 2) {
                ce = p.second; v = p.first;
                break;
            }
        }
        if (ce < 0) {
            for (auto &p : adj[u]) {
                if (p.second != pe_id && rem_use[p.second] > 0) {
                    ce = p.second; v = p.first;
                    break;
                }
            }
        }
        if (ce < 0 && pe_id >= 0 && rem_use[pe_id] > 0) {
            ce = pe_id;
            v = (e1[ce] == u ? e2[ce] : e1[ce]);
        }
        if (ce < 0) break;
        rem_use[ce]--;
        dfs(v, ce);
    }
    res.push_back(u);
}

int main(){
    while (true) {
        int n = Cin(), m = Cin();
        if (n==0) break;
        adj.assign(n+1, {});
        e1.resize(m);
        e2.resize(m);
        vector<int> deg(n+1,0);
        for (int i = 0; i < m; i++) {
            int a = Cin(), b = Cin();
            e1[i] = a; e2[i] = b;
            adj[a].emplace_back(b,i);
            adj[b].emplace_back(a,i);
            deg[a]++, deg[b]++;
        }
        vector<int> d1;
        for (int i = 1; i <= n; i++) if (deg[i] == 1) d1.push_back(i);

        int s, g;
        if (d1.size() > 2) {
            Cout(-1), pc('\n');
            continue;
        } else if (d1.size() == 2) s = d1[0], g = d1[1];
        else if (d1.size() == 1) {
            s = d1[0];
            g = s == 1 ? adj[1][0].first : adj[s][0].first;
        } else {
            s = 1;
            if (adj[1].empty()) {
                Cout(-1), pc('\n');
                continue;
            }
            g = adj[1][0].first;
        }

        par.assign(n+1, -1);
        pe.assign(n+1, -1);
        queue<int> q;
        par[s] = s;
        q.push(s);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            if (u == g) break;
            for (auto &p : adj[u]) {
                int v = p.first, ei = p.second;
                if (par[v] < 0) {
                    par[v] = u;
                    pe[v] = ei;
                    q.push(v);
                }
            }
        }
        if (par[g] < 0) {
            Cout(-1), pc('\n');
            continue;
        }

        onPath.assign(m, false);
        for (int u = g; u != s; u = par[u]) onPath[ pe[u] ] = true;

        rem_use.resize(m);
        for (int i = 0; i < m; i++) rem_use[i] = onPath[i] ? 1 : 2;

        res.clear();
        dfs(s, -1);
        reverse(res.begin(), res.end());

        for (int i = 0; i < (int)res.size(); i++) {
            if (i) pc(' ');
            Cout(res[i]);
        }
        pc('\n');
    }
    return 0;
}
accuracy: 1
time_ms: 670
memory_kb: 7984
final_rank: 2

code_snippet: // AOJ #3299 Parade
// 2025.4.27

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
}

vector<vector<pair<int,int>>> adj;
vector<int> e1, e2, rem_use, res;
vector<bool> onPath;
vector<int> par, pe;

void dfs(int u, int pe_id){
    while (true) {
        int ce = -1, v = -1;
        for (auto &p : adj[u]) {
            if (p.second != pe_id && rem_use[p.second] == 2) {
                ce = p.second; v = p.first;
                break;
            }
        }
        if (ce < 0) {
            for (auto &p : adj[u]) {
                if (p.second != pe_id && rem_use[p.second] > 0) {
                    ce = p.second; v = p.first;
                    break;
                }
            }
        }
        if (ce < 0 && pe_id >= 0 && rem_use[pe_id] > 0) {
            ce = pe_id;
            v = (e1[ce] == u ? e2[ce] : e1[ce]);
        }
        if (ce < 0) break;
        rem_use[ce]--;
        dfs(v, ce);
    }
    res.push_back(u);
}

int main(){
    while (true) {
        int n = Cin(), m = Cin();
        if (n==0) break;
        adj.assign(n+1, {});
        e1.resize(m);
        e2.resize(m);
        vector<int> deg(n+1,0);
        for (int i = 0; i < m; i++) {
            int a = Cin(), b = Cin();
            e1[i] = a; e2[i] = b;
            adj[a].emplace_back(b,i);
            adj[b].emplace_back(a,i);
            deg[a]++, deg[b]++;
        }
        vector<int> d1;
        for (int i = 1; i <= n; i++) if (deg[i] == 1) d1.push_back(i);

        int s, g;
        if (d1.size() > 2) {
            Cout(-1), pc('\n');
            continue;
        } else if (d1.size() == 2) s = d1[0], g = d1[1];
        else if (d1.size() == 1) {
            s = d1[0];
            g = s == 1 ? adj[1][0].first : adj[s][0].first;
        } else {
            s = 1;
            if (adj[1].empty()) {
                Cout(-1), pc('\n');
                continue;
            }
            g = adj[1][0].first;
        }

        par.assign(n+1, -1);
        pe.assign(n+1, -1);
        queue<int> q;
        par[s] = s;
        q.push(s);
        while (!q.empty()) {
            int u = q.front(); q.pop();
            if (u == g) break;
            for (auto &p : adj[u]) {
                int v = p.first, ei = p.second;
                if (par[v] < 0) {
                    par[v] = u;
                    pe[v] = ei;
                    q.push(v);
                }
            }
        }
        if (par[g] < 0) {
            Cout(-1), pc('\n');
            continue;
        }

        onPath.assign(m, false);
        for (int u = g; u != s; u = par[u]) onPath[ pe[u] ] = true;

        rem_use.resize(m);
        for (int i = 0; i < m; i++) rem_use[i] = onPath[i] ? 1 : 2;

        res.clear();
        dfs(s, -1);
        reverse(res.begin(), res.end());

        for (int i = 0; i < (int)res.size(); i++) {
            if (i) pc(' ');
            Cout(res[i]);
        }
        pc('\n');
    }
    return 0;
}
accuracy: 1
time_ms: 840
memory_kb: 7868
final_rank: 3

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

// ある辺を2回使って、オイラーグラフにする
vector<pair<int, int>> make_euler_graph(int n, vector<int> &x, vector<int> &y, vector<int> &match) {
    vector<vector<int>> g(n);
    vector<bool> used(n);
    vector<int> p(n, -1), order;
    vector<vector<int>> c(n);
    for (int i = 0; i < (int)x.size(); i++) {
        g[x[i]].push_back(y[i]);
        g[y[i]].push_back(x[i]);
    }
    auto make_tree = [&](auto self, int s) -> void {
        order.push_back(s);
        for (int t : g[s]) {
            if (used[t]) continue;
            used[t] = true;
            p[t] = s;
            c[s].push_back(t);
            self(self, t);
        }
    };
    used[0] = true;
    make_tree(make_tree, 0);
    reverse(order.begin(), order.end());
    vector<int> imos(n);
    for (int i = 0; i < (int)match.size(); i += 2) {
        imos[match[i]] ^= 1;
        imos[match[i + 1]] ^= 1;
    }
    vector<pair<int, int>> res;
    for (int s : order) {
        if (imos[s]) {
            res.push_back({s, p[s]});
        }
        if (p[s] != -1) {
            imos[p[s]] ^= imos[s];
        }
    }
    return res;
}
// オイラー路を1つ求める
struct edge {
    int from, to;
    bool used;
};
vector<int> find_euler_trail(int n, vector<int> &x, vector<int> &y, int sx, int sy) {
    vector<edge> edges;
    vector<vector<int>> g(n);
    for (int i = 0; i < (int)x.size(); i++) {
        g[x[i]].push_back(edges.size());
        g[y[i]].push_back(edges.size());
        edges.push_back(edge{x[i], y[i], false});
    }
    vector<int> res;
    auto dfs = [&](auto dfs, int s) -> void {
        for (auto &id : g[s]) {
            auto &e = edges[id];
            if (e.used) continue;
            int t = (e.from) ^ (e.to) ^ s;
            e.used = true;
            dfs(dfs, t);
        }
        res.push_back(s);
    };
    dfs(dfs, sx);
    reverse(res.begin(), res.end());
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    while (cin >> n >> m, n) {
        vector<int> vx(m), vy(m);
        vector<int> deg(n);
        for (int i = 0; i < m; i++) {
            cin >> vx[i] >> vy[i];
            vx[i] -= 1, vy[i] -= 1;
            deg[vx[i]] += 1, deg[vy[i]] += 1;
        }
        vector<int> one;
        for (int i = 0; i < n; i++) {
            if (deg[i] == 1) one.push_back(i);
        }
        if (one.size() >= 3) {
            cout << -1 << "\n";
            continue;
        }
        int s = -1, t = -1;
        if (!one.size()) {
            s = 0, t = 1;
        } else if (one.size() == 1) {
            s = one[0];
            for (int i = 0; i < n; i++) {
                if (i != s and deg[i] % 2) t = i;
            }
        } else {
            s = one[0], t = one[1];
        }
        // 辺を倍加してオイラーグラフにしたい
        vector<int> v;
        for (int i = 0; i < n; i++) {
            if (deg[i] % 2 == 1) {
                if (i != s and i != t) {
                    v.push_back(i);
                }
            } else if (s == i or t == i) {
                v.push_back(i);
            }
        }
        auto p = make_euler_graph(n, vx, vy, v);
        for (auto &pp : p) {
            vx.push_back(pp.first);
            vy.push_back(pp.second);
        }
        auto r = find_euler_trail(n, vx, vy, s, t);
        for (int i = 2; i < (int)r.size(); i++) {
            if (r[i] == r[i - 2]) {
                int l = -1;
                for (int j = i - 2; j >= 0; j--) {
                    if (r[j] == r[i - 1]) {
                        l = j;
                        break;
                    }
                }
                // [l+1, i-2] をreverse
                reverse(r.begin() + l + 1, r.begin() + i - 1);
            }
        }
        bool sep = false;
        for (int i : r) {
            if (sep) cout << " ";
            cout << i + 1;
            sep = true;
        }
        cout << "\n";
    }
}
accuracy: 1
time_ms: 470
memory_kb: 9052
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;

using P = pair<int, int>;

const int M = 1000000007;

void dfs(int p, int par, const vector<vector<int>>& edge, const vector<P>& edges, vector<int>& cnt, vector<int>& vs) {
    while (true) {
        bool f = false;
        for (auto& ei : edge[p]) {
            int nex = edges[ei].first ^ edges[ei].second ^ p;
            if (cnt[ei]) {
                --cnt[ei];
                dfs(nex, p, edge, edges, cnt, vs);
                f = true;
            }
        }
        if (!f) break;
    }
    vs.push_back(p);
}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    while (true) {
        int n, m;
        cin >> n >> m;
        if (n == 0) break;
        vector<P> edges(m);
        vector<vector<int>> edge(n);
        for (int i = 0; i < m; ++i) {
            int u, v;
            cin >> u >> v;
            --u;
            --v;
            edges[i] = { u, v };
            edge[u].push_back(i);
            edge[v].push_back(i);
        }
        vector<int> d1;
        for (int i = 0; i < n; ++i) {
            if (edge[i].size() == 1) {
                d1.push_back(i);
            }
        }
        if (d1.size() > 2) {
            cout << -1 << '\n';
            continue;
        }

        vector<int> cnt(m, 2);
        if (d1.size() == 2) {
            vector<int> dist(n, M);
            vector<int> prev(n, -1);
            queue<int> q;
            dist[d1[0]] = 0;
            q.push(d1[0]);
            while (!q.empty()) {
                int p = q.front();
                q.pop();
                for (auto& ei : edge[p]) {
                    int nex = edges[ei].first ^ edges[ei].second ^ p;
                    if (dist[nex] > dist[p] + 1) {
                        dist[nex] = dist[p] + 1;
                        prev[nex] = ei;
                        q.push(nex);
                    }
                }
            }
            int t = d1[1];
            while (t != d1[0]) {
                int ei = prev[t];
                cnt[ei] = 1;
                t ^= edges[ei].first ^ edges[ei].second;
            }
        }
        vector<int> vs;
        int r = 0;
        if (d1.size()) r = d1[0];
        dfs(r, -1, edge, edges, cnt, vs);
        for (int i = 0; i + 2 < (int)vs.size(); ++i) {
            if (vs[i] == vs[i + 2]) {
                for (int j = 0; j < (int)vs.size(); ++j) {
                    if (j == i + 1) continue;
                    if (vs[j] == vs[i + 1]) {
                        int l = min(i + 1, j) + 1;
                        int r = max(i + 1, j) - 1;
                        while (l < r) {
                            swap(vs[l], vs[r]);
                            ++l;
                            --r;
                        }
                        break;
                    }
                }
            }
        }
        for (int i = 0; i < (int)vs.size(); ++i) {
            cout << vs[i] + 1 << (i + 1 < (int)vs.size() ? ' ' : '\n');
        }

    }
    return 0;
}
accuracy: 1
time_ms: 3400
memory_kb: 7924
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <deque>
#include <array>
#include <cassert>

using namespace std;

struct testcase{
	struct edge{
		int a, b;
		int rem;
	};
	
	deque<edge> edges;
	vector<array<deque<edge*>,2>> G;
	
	vector<char> vis;
	vector<int> res;
	
	bool dfs1(int u, int t){
		if(vis[u]){ return false; }
		vis[u] = 1;
		if(u == t){ return true; }
		for(edge *e : G[u][0]){
			int v = e->a ^ e->b ^ u;
			if(dfs1(v, t)){
				e->rem = 1;
				return true;
			}
		}
		return false;
	}

	void dfs2(int u, edge *prev){
		for(int pri = 0; pri <= 1; ++pri){
			while(!G[u][pri].empty()){
				edge *e = G[u][pri].front();
				G[u][pri].pop_front();
				
				if(e->rem == 0){ continue; }
				if(pri == 0 && e->rem == 1){
					G[u][1].push_back(e);
					continue;
				}
				if(e == prev){
					assert(pri == 1);
					assert(!G[u][1].empty());
					G[u][1].push_back(e);
					continue;
				}
				
				--e->rem;
				if(e->rem == 1){
					G[u][1].push_back(e);
				}
				int v = e->a ^ e->b ^ u;
				dfs2(v, e);
			}
		}
		res.push_back(u);
	}

	vector<int> solve(int n, int m){
		G.resize(n + 1);
		for(int i = 0; i < m; ++i){
			int a, b;
			cin >> a >> b;
			edges.push_back(edge{a, b, 2});
			edge *e = &edges.back();
			G[a][0].push_back(e);
			G[b][0].push_back(e);
		}
		
		vector<int> ones;
		for(int i = 1; i <= n; ++i){
			if(G[i][0].size() == 1){
				ones.push_back(i);
			}
		}
		if(ones.size() > 2){
			return {-1};
		}
		
		int end1 = 1, end2 = 1;
		if(ones.size() >= 1){
			end1 = ones[0];
		}
		if(ones.size() == 2){
			end2 = ones[1];
		}
		
		vis.assign(n + 1, 0);
		bool reached = dfs1(end1, end2);
		assert(reached);
		
		dfs2(end1, nullptr);
		return res;
	}
};

int main(){
	ios::sync_with_stdio(false);

	int n, m;
	while(cin >> n >> m && n){
		vector<int> ans = testcase().solve(n, m);
		const char *sep = "";
		for(int x : ans){
			cout << sep << x;
			sep = " ";
		}
		cout << endl;
	}
}
accuracy: 1
time_ms: 340
memory_kb: 34480
final_rank: 4