#include <bits/stdc++.h> using namespace std; /* const int maxn = 60; int n,m; vector<int> res[maxn]; vector<int> ciklus; bool bio[maxn]; bool bio2[maxn]; bool dfs(int node,vector<vector<int> > &g){ ciklus.push_back(node); if(bio2[node]) { return true; } if(bio[node]){ ciklus.pop_back(); return false; } bio2[node]=true; bio[node]=true; for(int i:g[node]){ if(dfs(i,g)) return true; } ciklus.pop_back(); return false; } vector<vector<int> > ubij(int a,int b,vector<vector<int> > g){ vector<vector<int> > ret(n+1); for(int i=1;i<=n;i++){ for(int j:g[i]){ if(i==a && j==b) continue; ret[i].push_back(j); } } return ret; } vector<int> kurac; bool bio3[maxn]; void dfs2(int node,vector<vector<int> > &g){ bio3[node]=true; for(int i:g[node]){ if(bio3[i]) continue; dfs2(i,g); } kurac.push_back(node); } vector<int> napravi(vector<vector<int> > g){ kurac.clear(); fill(bio3,bio3+n+1,false); for(int i=1;i<=n;i++){ if(bio3[i]) continue; dfs2(i,g); } reverse(kurac.begin(),kurac.end()); return kurac; } void uradi(int l,int r,vector<vector<int> > g){ fill(bio,bio+n+1,false); for(int i=1;i<=n;i++) { fill(bio2, bio2 + n + 1, false); if (!bio[i] && dfs(i, g)) { int poc = 0; for (int i = 0; i < ciklus.size(); i++) { if (ciklus[i] == ciklus.back()) { poc = i; break; } } int siz = ciklus.size() - poc - 1; siz = (r - l + 1) / siz; for (int i = poc; i + 1 < ciklus.size(); i++) { if (i + 2 < ciklus.size()) { uradi(l + (i - poc) * siz, l + (i - poc + 1) * siz - 1, ubij(ciklus[i], ciklus[i + 1], g)); } else { uradi(l + (i - poc) * siz, r, ubij(ciklus[i], ciklus[i + 1], g)); } } ciklus.clear(); return; } } vector<int> sta = napravi(g); for(int i=l;i<=r;i++) res[i]=sta; } */ const int MAXN = 60; vector<int> adj[MAXN]; vector<pair<int, int> > g[3]; set<pair<int, int> > e; bool pos[MAXN]; int n, m; void dfs(int node, int c, int p) { //cerr << "DFS " << node << " " << c << " " << adj[node].size() << endl; pos[node] = true; for (auto x : adj[node]) { if (x != p) { int p1 = x, p2 = node; if (e.find({p1, p2}) == e.end()) swap(p1, p2); if (e.find({p1, p2}) != e.end()) g[c].push_back({p1, p2}); e.erase({p1, p2}); } if (!pos[x]) { dfs(x, (c+1)%3, node); } } } void printPerm(vector<pair<int, int> > &v1, vector<pair<int, int> > &v2) { vector<int> adj[MAXN]; vector<int> degin(MAXN); for (auto x : v1) { adj[x.first].push_back(x.second); degin[x.second]++; } for (auto x : v2) { adj[x.first].push_back(x.second); degin[x.second]++; } vector<int> q; for (int i = 1; i <= n; i++) { if (degin[i] == 0) { q.push_back(i); } } while(!q.empty()) { int vrh = q.back(); q.pop_back(); cout << vrh << ' '; for (auto x : adj[vrh]) { degin[x]--; if (degin[x] == 0) { q.push_back(x); } } } cout << '\n'; } int main() { cin >> n >> m; for (int i = 0; i < m; i++) { int x, y; cin >> x >> y; adj[x].push_back(y); adj[y].push_back(x); e.insert({x, y}); } for (int i = 1; i <= n; i++) { if (!pos[i]) { dfs(i, 0, 0); } } cout << "YES\n3\n"; for (auto x : g[0]) { //cerr << x.first << ' ' << x.second << endl; } //cerr << "B1" << endl; for (auto x : g[1]) { // cerr << x.first << ' ' << x.second << endl; } //cerr << "B2" << endl; for (auto x : g[2]) { // cerr << x.first << ' ' << x.second << endl; } printPerm(g[0], g[1]); printPerm(g[1], g[2]); printPerm(g[2], g[0]); /* cin>>n>>m; vector<vector<int> > g(n+1); for(int i=0;i<m;i++){ int a,b; cin>>a>>b; g[a].push_back(b); } uradi(0,n+5,g); cout<<"YES\n"; cout<<n+6<<"\n"; for(int i=0;i<n+6;i++){ for(int j:res[i]) cout<<j<<" "; cout<<"\n"; } */ return 0; } /* */