#include <bits/stdc++.h>
using namespace std;
const int limite = 1000000;
int n, m;
vector<int> g[limite];
int visto[limite];
int profundidad[limite];
int profreach[limite];
int eleccion[limite];
int padre[limite];
void escribe(vector<int> &sol) {
  cout << int(sol.size());
  for (int i = 0; i < int(sol.size()); i++) cout << " " << sol[i];
  cout << endl;
}
void calcula(int u, int e1, int e2) {
  int prof1 = profundidad[e1];
  if (prof1 > profundidad[u]) prof1 = profreach[e1];
  int prof2 = profundidad[e2];
  if (prof2 > profundidad[u]) prof2 = profreach[e2];
  if (prof1 < prof2) {
    swap(e1, e2);
    swap(prof1, prof2);
  }
  vector<int> sol1;
  sol1.push_back(u);
  while (profundidad[sol1.back()] != prof1) {
    int v = padre[sol1.back()];
    sol1.push_back(v);
  }
  vector<int> sol2;
  sol2.push_back(u);
  sol2.push_back(e1);
  while (profundidad[sol2.back()] != prof1) {
    int v = eleccion[sol2.back()];
    sol2.push_back(v);
  }
  vector<int> sol3;
  sol3.push_back(u);
  sol3.push_back(e2);
  while (profundidad[sol3.back()] != prof2) {
    int v = eleccion[sol3.back()];
    sol3.push_back(v);
  }
  vector<int> rev;
  int v = sol1.back();
  while (v != sol3.back()) {
    rev.push_back(v);
    v = padre[v];
  }
  for (int i = int(rev.size()) - 1; i >= 0; i--) sol3.push_back(rev[i]);
  cout << "YES" << endl;
  escribe(sol1);
  escribe(sol2);
  escribe(sol3);
  exit(0);
}
void genera(int u, int p, int prof) {
  padre[u] = p;
  visto[u] = 1;
  profundidad[u] = prof;
  profreach[u] = prof;
  vector<int> &ar = g[u];
  for (int i = 0; i < int(ar.size()); i++) {
    int v = ar[i];
    if (v != p) {
      if (visto[v]) {
        if (profundidad[v] < profundidad[u]) {
          if (eleccion[u])
            calcula(u, eleccion[u], v);
          else {
            eleccion[u] = v;
            profreach[u] = profundidad[v];
          }
        }
      } else {
        genera(v, u, prof + 1);
        if (profreach[v] < profundidad[u]) {
          if (eleccion[u])
            calcula(u, eleccion[u], v);
          else {
            eleccion[u] = v;
            profreach[u] = profreach[v];
          }
        }
      }
    }
  }
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int u = 1; u <= n; u++)
    if (not visto[u]) genera(u, 0, 0);
  cout << "NO" << endl;
}
