#include <bits/stdc++.h>
using namespace std;
int main(){
    string cnf="/tmp/edges491.txt", tourf="/tmp/hcp491_one_bad.tour";
    ifstream te(tourf); vector<int> tour; int x; while(te>>x) tour.push_back(x);
    int n=tour.size();
    ifstream in(cnf); int a,b,N=0; vector<pair<int,int>> edges;
    while(in>>a>>b){ edges.push_back({a,b}); N=max(N,max(a,b)+1); }
    vector<unordered_set<int>> adj(N);
    for(auto [u,v]:edges){ adj[u].insert(v); adj[v].insert(u); }
    int bad=-1; for(int i=0;i<n;i++) if(!adj[tour[i]].count(tour[(i+1)%n])) bad=i;
    vector<int> path; for(int k=bad+1;k<n;k++) path.push_back(tour[k]); for(int k=0;k<=bad;k++) path.push_back(tour[k]);
    array<array<int,3>,6> perms = {{{0,1,2},{0,2,1},{1,0,2},{1,2,0},{2,0,1},{2,1,0}}};
    auto ep=[&](int i,int j,int idx,int rev){
        pair<int,int> p;
        if(idx==0) p={path[0],path[i]};
        else if(idx==1) p={path[i+1],path[j]};
        else p={path[j+1],path[n-1]};
        if(rev) swap(p.first,p.second);
        return p;
    };
    auto emit=[&](int i,int j,array<int,3> perm,int mask){
        vector<int> out; out.reserve(n);
        for(int pp=0;pp<3;pp++){
            int idx=perm[pp]; int l,r;
            if(idx==0){l=0;r=i;} else if(idx==1){l=i+1;r=j;} else {l=j+1;r=n-1;}
            if(mask>>idx &1){ for(int k=r;k>=l;k--) out.push_back(path[k]);}
            else { for(int k=l;k<=r;k++) out.push_back(path[k]);}
        }
        ofstream o("/tmp/hcp491_3opt_cycle.tour");
        for(int k=0;k<n;k++) o<<out[k]<<(k+1==n?'\n':' ');
    };
    cerr<<"n "<<n<<" bad "<<bad<<" edge "<<tour[bad]<<" "<<tour[(bad+1)%n]<<"\n";
    auto st=chrono::steady_clock::now();
    for(int i=0;i<n-2;i++){
        if(i%500==0) cerr<<"i "<<i<<" time "<<chrono::duration<double>(chrono::steady_clock::now()-st).count()<<"\n";
        for(int j=i+1;j<n-1;j++){
            for(auto perm:perms) for(int mask=0;mask<8;mask++){
                bool good=true;
                for(int p=0;p<3;p++){
                    auto e1=ep(i,j,perm[p],(mask>>perm[p])&1);
                    auto e2=ep(i,j,perm[(p+1)%3],(mask>>perm[(p+1)%3])&1);
                    if(!adj[e1.second].count(e2.first)){good=false;break;}
                }
                if(good){ cerr<<"FOUND "<<i<<" "<<j<<" mask "<<mask<<"\n"; emit(i,j,perm,mask); return 0; }
            }
        }
    }
    cerr<<"none\n"; return 1;
}
