#include <bits/stdc++.h> using namespace std; int main() { cin.tie(0)->sync_with_stdio(0); int n, m; cin >> n >> m; vector<vector<int>> g(n); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; u--; v--; g[u].push_back(v); } vector<int> output, visited(n, 0); auto dfs = [&](int v, vector<int>& order, vector<vector<int>>& adj, auto&& self) -> void { visited[v] = 1; for (auto u : adj[v]) { if (!visited[u]) { self(u, order, adj, self); } } order.push_back(v); }; vector<vector<int>> components, g_cond; vector<int> roots(n, 0); auto scc = [&]() -> void { for (int i = 0; i < n; i++) { if (!visited[i]) dfs(i, output, g, dfs); } vector<vector<int>> g_rev(n); for (int v = 0; v < n; v++) { for (int u : g[v]) { g_rev[u].push_back(v); } } visited.assign(n, 0); reverse(output.begin(), output.end()); for (auto v : output) { if (!visited[v]) { vector<int> component; dfs(v, component, g_rev, dfs); int root = components.size(); components.push_back(component); for (auto u : component) roots[u] = root; } } g_cond.assign(components.size(), {}); for (int v = 0; v < n; v++) { for (auto u : g[v]) { if (roots[v] != roots[u]) { g_cond[roots[v]].push_back(roots[u]); } } } }; scc(); vector<int> indeg(g_cond.size(), 0), top_ord; for (auto& v : g_cond) for (auto x : v) indeg[x]++; queue<int> q; for (int i = 0; i < g_cond.size(); i++) if (indeg[i] == 0) q.push(i); while (!q.empty()) { int i = q.front(); q.pop(); top_ord.push_back(i); for (int x : g_cond[i]) if (--indeg[x] == 0) q.push(x); } int sz = 0; for (auto v : components) { sz = max(sz, (int) v.size()); } if (sz % 2 == 0) sz++; cout << "YES" << endl << sz << endl; for (int i = 0; i < sz; i++) { for (int t : top_ord) { auto& c = components[t]; for (auto el : c) cout << el + 1 << ' '; } cout << endl; for (auto& c : components) { int tmp = c.front(); for (int i = 0; i < c.size() - 1; i++) c[i] = c[i+1]; c.back() = tmp; } } return 0; }