#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;
}
/*

 */