#include <iostream> #include <vector> #include <algorithm> struct UnionFind { std::vector<int> a; UnionFind(int n) : a(n, -1) {} auto find(int idx) -> int { if (a[idx] < 0) return idx; else return a[idx] = find(a[idx]); } auto unite(int l, int r) -> bool { l = find(l); r = find(r); if (l == r) return false; if (-a[l] < -a[r]) std::swap(l, r); a[l] += a[r]; a[r] = l; return true; } }; int main() { int n, m; std::cin >> n >> m; // auto adj = std::vector<std::vector<std::pair<int, int>>>(n); auto edges = std::vector<std::tuple<int, int, int>>{}; for (int i = 0; i < m; i++) { int u, v; std::cin >> u >> v; u--, v--; edges.push_back({0, u, v}); } auto q = std::vector<std::vector<int>>{}; for (int i = 1; i <= 50'000; i++) { auto dsu = UnionFind(n); std::sort(edges.begin(), edges.end()); auto used = std::vector<std::pair<int, int>>{}; auto adj = std::vector<std::vector<int>>(n); for (auto &[w, u, v] : edges) { if (dsu.unite(u, v)) { used.push_back({u, v}); w += 1; adj[u].push_back(v); } } auto min_w = std::get<0>(edges[0]); for (int i = 0; i < m; i++) { min_w = std::min(min_w, std::get<0>(edges[i])); } auto res = std::vector<int>{}; auto vis = std::vector<char>(n, false); auto dfs = [&](auto &&self, int v) { if (vis[v]) return; vis[v] = true; for (auto u : adj[v]) self(self, u); res.push_back(v); }; for (int i = 0; i < n; i++) { dfs(dfs, i); } std::reverse(res.begin(), res.end()); q.push_back(std::move(res)); if (min_w >= i / 2 + 1) { std::cout << "YES\n"; // std::cerr << min_w << ' ' << i << '\n'; std::cout << q.size() << '\n'; for (auto &v : q) { for (auto x : v) { std::cout << x + 1 << ' '; } std::cout << '\n'; } return 0; } } std::cout << "NO\n"; }