#include using namespace std; struct FastScanner { static constexpr size_t BUFSIZE = 1 << 20; int idx = 0, size = 0; char buf[BUFSIZE]; inline char readChar() { if (idx >= size) { size = (int)fread(buf, 1, BUFSIZE, stdin); idx = 0; if (size == 0) return 0; } return buf[idx++]; } template bool readInt(T &out) { char c; do { c = readChar(); if (!c) return false; } while (c <= ' '); bool neg = false; if (c == '-') { neg = true; c = readChar(); } T val = 0; while (c > ' ') { val = val * 10 + (c - '0'); c = readChar(); } out = neg ? -val : val; return true; } }; struct FastOutput { static constexpr int BUFSIZE = 1 << 20; int idx = 0; char buf[BUFSIZE]; ~FastOutput() { flush(); } inline void flush() { if (idx) { fwrite(buf, 1, idx, stdout); idx = 0; } } inline void pushChar(char c) { if (idx == BUFSIZE) flush(); buf[idx++] = c; } inline void writeInt(int x, char endc) { if (x == 0) { pushChar('0'); pushChar(endc); return; } if (x < 0) { pushChar('-'); x = -x; } char s[24]; int n = 0; while (x) { s[n++] = char('0' + (x % 10)); x /= 10; } while (n--) pushChar(s[n]); pushChar(endc); } }; static uint64_t rng_state = 88172645463325252ull; static inline uint64_t nextRand() { rng_state ^= rng_state << 7; rng_state ^= rng_state >> 9; return rng_state; } struct CSR { int n; vector start; vector edges; // size = m }; static inline int findBestNeighborOut( int u, int timer, const CSR &out, const vector °, const vector &vis ) { int best = -1; int bestScore = -1; for (int i = out.start[u]; i < out.start[u + 1]; ++i) { int v = out.edges[i]; if (vis[v] == timer) continue; int sc = deg[v]; if (sc > bestScore || (sc == bestScore && (nextRand() & 1))) { bestScore = sc; best = v; } } return best; } static inline int findBestNeighborIn( int u, int timer, const CSR &in, const vector °, const vector &vis ) { int best = -1; int bestScore = -1; for (int i = in.start[u]; i < in.start[u + 1]; ++i) { int v = in.edges[i]; // v -> u if (vis[v] == timer) continue; int sc = deg[v]; if (sc > bestScore || (sc == bestScore && (nextRand() & 1))) { bestScore = sc; best = v; } } return best; } static inline void buildPathInBuffer( int startV, int timer, int n, int mid, vector &buf, int &L, int &R, const CSR &out, const CSR &in, const vector °, vector &vis ) { L = R = mid; buf[L] = startV; vis[startV] = timer; bool backBlocked = false, frontBlocked = false; int storedBack = -1, storedFront = -1; int candBack = -2, candFront = -2; while (true) { int back = buf[R]; int front = buf[L]; if (!backBlocked) { if (storedBack != back || candBack == -2 || (candBack != -1 && vis[candBack] == timer)) { candBack = findBestNeighborOut(back, timer, out, deg, vis); storedBack = back; } if (candBack == -1) backBlocked = true; } if (!frontBlocked) { if (storedFront != front || candFront == -2 || (candFront != -1 && vis[candFront] == timer)) { candFront = findBestNeighborIn(front, timer, in, deg, vis); storedFront = front; } if (candFront == -1) frontBlocked = true; } if (backBlocked && frontBlocked) break; bool takeBack; if (frontBlocked) takeBack = true; else if (backBlocked) takeBack = false; else { int sb = deg[candBack]; int sf = deg[candFront]; if (sb > sf) takeBack = true; else if (sb < sf) takeBack = false; else takeBack = (nextRand() & 1); } if (takeBack) { int v = candBack; if (v == -1 || vis[v] == timer) { backBlocked = true; continue; } buf[++R] = v; vis[v] = timer; storedBack = -1; candBack = -2; backBlocked = false; } else { int v = candFront; if (v == -1 || vis[v] == timer) { frontBlocked = true; continue; } buf[--L] = v; vis[v] = timer; storedFront = -1; candFront = -2; frontBlocked = false; } if (R - L + 1 >= n) break; } } int main() { FastScanner fs; int n, m; if (!fs.readInt(n)) return 0; fs.readInt(m); for (int i = 0; i < 10; ++i) { int tmp; fs.readInt(tmp); } vector U(m), V(m); vector outdeg(n + 2, 0), indeg(n + 2, 0); for (int i = 0; i < m; ++i) { int u, v; fs.readInt(u); fs.readInt(v); U[i] = u; V[i] = v; ++outdeg[u]; ++indeg[v]; } CSR out, in; out.n = in.n = n; out.start.assign(n + 2, 0); in.start.assign(n + 2, 0); for (int i = 1; i <= n; ++i) { out.start[i + 1] = out.start[i] + outdeg[i]; in.start[i + 1] = in.start[i] + indeg[i]; } out.edges.assign(m, 0); in.edges.assign(m, 0); vector outCur = out.start; vector inCur = in.start; for (int i = 0; i < m; ++i) { int u = U[i], v = V[i]; out.edges[outCur[u]++] = v; in.edges[inCur[v]++] = u; } vector deg(n + 2, 0); int maxOutV = 1, maxInV = 1, maxDegV = 1; for (int i = 1; i <= n; ++i) { deg[i] = outdeg[i] + indeg[i]; if (outdeg[i] > outdeg[maxOutV]) maxOutV = i; if (indeg[i] > indeg[maxInV]) maxInV = i; if (deg[i] > deg[maxDegV]) maxDegV = i; } vector starts; starts.reserve(32); unordered_set used; used.reserve(64); auto addStart = [&](int x) { if (x < 1 || x > n) return; if (used.insert(x).second) starts.push_back(x); }; addStart(1); addStart(maxDegV); addStart(maxOutV); addStart(maxInV); for (int i = 0; i < min(m, 5); ++i) { addStart(U[i]); addStart(V[i]); } for (int i = 0; i < 6; ++i) { int x = (int)(nextRand() % (uint64_t)n) + 1; addStart(x); } const int MAX_ATTEMPTS = 12; if ((int)starts.size() > MAX_ATTEMPTS) starts.resize(MAX_ATTEMPTS); vector vis(n + 2, 0); int timer = 0; int mid = n + 5; vector work(2 * n + 30, 0); vector bestPath; bestPath.reserve(n); for (int s : starts) { ++timer; int L, R; buildPathInBuffer(s, timer, n, mid, work, L, R, out, in, deg, vis); int len = R - L + 1; if ((int)bestPath.size() < len) { bestPath.assign(work.begin() + L, work.begin() + R + 1); if ((int)bestPath.size() == n) break; } } if (bestPath.empty()) bestPath.push_back(1); FastOutput fo; fo.writeInt((int)bestPath.size(), '\n'); for (int i = 0; i < (int)bestPath.size(); ++i) { fo.writeInt(bestPath[i], i + 1 == (int)bestPath.size() ? '\n' : ' '); } fo.flush(); return 0; }