File size: 3,494 Bytes
1fd0050
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 500000;
int parent[MAXN], sizeComp[MAXN], nxt[MAXN], prv[MAXN], compStart[MAXN], compEnd[MAXN];
bool isEndpoint[MAXN];

int find(int x) {
    return parent[x] == x ? x : parent[x] = find(parent[x]);
}

void reverseComponent(int r) {
    int cur = compStart[r];
    while (cur != -1) {
        swap(nxt[cur], prv[cur]);
        cur = prv[cur]; // after swap, prv holds the original next
    }
    swap(compStart[r], compEnd[r]);
}

void merge(int u, int v, int ru, int rv) {
    nxt[u] = v;
    prv[v] = u;
    isEndpoint[u] = false;
    isEndpoint[v] = false;
    int start_u = compStart[ru];
    int end_v = compEnd[rv];
    if (sizeComp[ru] < sizeComp[rv]) {
        swap(ru, rv);
    }
    parent[rv] = ru;
    sizeComp[ru] += sizeComp[rv];
    compStart[ru] = start_u;
    compEnd[ru] = end_v;
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    vector<int> a(10);
    for (int i = 0; i < 10; ++i) scanf("%d", &a[i]); // ignored in the algorithm

    vector<pair<int, int>> edges;
    for (int i = 0; i < m; ++i) {
        int u, v;
        scanf("%d %d", &u, &v);
        --u; --v;
        edges.emplace_back(u, v);
    }

    // sort edges by destination, then source
    sort(edges.begin(), edges.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {
        if (p1.second != p2.second) return p1.second < p2.second;
        return p1.first < p2.first;
    });

    // initialize DSU and path structures
    for (int i = 0; i < n; ++i) {
        parent[i] = i;
        sizeComp[i] = 1;
        nxt[i] = -1;
        prv[i] = -1;
        isEndpoint[i] = true;
        compStart[i] = i;
        compEnd[i] = i;
    }

    // up to 10 passes
    for (int iter = 0; iter < 10; ++iter) {
        bool changed = false;
        for (const auto& e : edges) {
            int u = e.first, v = e.second;
            int ru = find(u), rv = find(v);
            if (ru == rv) continue;
            if (!isEndpoint[u] || !isEndpoint[v]) continue;

            bool u_start = (prv[u] == -1);
            bool u_end = (nxt[u] == -1);
            bool v_start = (prv[v] == -1);
            bool v_end = (nxt[v] == -1);

            if (u_end && v_start) {
                merge(u, v, ru, rv);
                changed = true;
            } else if (u_start && v_end) {
                reverseComponent(ru);
                reverseComponent(rv);
                merge(u, v, ru, rv);
                changed = true;
            } else if (u_end && v_end) {
                reverseComponent(rv);
                merge(u, v, ru, rv);
                changed = true;
            } else if (u_start && v_start) {
                reverseComponent(ru);
                merge(u, v, ru, rv);
                changed = true;
            }
        }
        if (!changed) break;
    }

    // find the largest component
    int bestRoot = -1, bestSize = 0;
    for (int i = 0; i < n; ++i) {
        if (find(i) == i) {
            if (sizeComp[i] > bestSize) {
                bestSize = sizeComp[i];
                bestRoot = i;
            }
        }
    }

    // reconstruct the path
    vector<int> path;
    int cur = compStart[bestRoot];
    while (cur != -1) {
        path.push_back(cur);
        cur = nxt[cur];
    }

    // output
    printf("%d\n", (int)path.size());
    for (size_t i = 0; i < path.size(); ++i) {
        if (i) printf(" ");
        printf("%d", path[i] + 1);
    }
    printf("\n");

    return 0;
}