#include <bits/stdc++.h>
using namespace std;
int read() {
  int s = 0, t = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') t = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
  return s * t;
}
struct edge {
  int to, lt;
} e[200010 << 1];
struct node {
  int x, y;
} w[200010];
int in[200010], cnt, d[200010], dep[200010], fa[200010], dfn[200010], tot,
    sz[200010], n, m;
bool vis[200010];
void add(int x, int y) {
  e[++cnt].to = y;
  e[cnt].lt = in[x];
  in[x] = cnt;
  e[++cnt].to = x;
  e[cnt].lt = in[y];
  in[y] = cnt;
  w[cnt >> 1] = (node){x, y};
}
void dfs(int x, int fr) {
  dep[x] = dep[fr] + 1;
  fa[x] = fr;
  dfn[x] = ++tot;
  sz[x] = 1;
  for (int i = in[x]; i; i = e[i].lt) {
    int y = e[i].to;
    if (y == fr || dep[y]) continue;
    dfs(y, x);
    vis[i + 1 >> 1] = 1;
    sz[x] += sz[y];
  }
}
void cf(int x, int y) {
  if (dep[x] < dep[y]) swap(x, y);
  d[x]++;
  d[y]--;
}
int gg;
void dfs2(int x) {
  for (int i = in[x]; i; i = e[i].lt) {
    int y = e[i].to;
    if (y == fa[x] || !vis[i + 1 >> 1]) continue;
    dfs2(y);
    d[x] += d[y];
  }
  if (d[x] > 1 && !gg) gg = x;
}
int p1, p2, s, t;
int pa1[200010], pa2[200010], pa3[200010], t1, t2, t3;
void get() {
  for (int i = 1; i <= m; i++) {
    int x = w[i].x, y = w[i].y;
    if (vis[i]) continue;
    if (dfn[x] < dfn[y]) swap(x, y), swap(w[i].x, w[i].y);
    if (dfn[x] >= dfn[gg] && dfn[x] < dfn[gg] + sz[gg] && dfn[y] < dfn[gg])
      if (!p1)
        p1 = i;
      else
        p2 = i;
  }
  int x = w[p1].x, y = w[p2].x;
  while (x != y) {
    if (dep[x] < dep[y])
      y = fa[y];
    else if (dep[x] > dep[y])
      x = fa[x];
    else
      x = fa[x], y = fa[y];
  }
  if (dep[w[p1].y] < dep[w[p2].y]) swap(p1, p2);
  int s = x, t = w[p1].y;
  while (x != t) pa1[++t1] = x, x = fa[x];
  pa1[++t1] = t;
  x = w[p1].x;
  pa2[++t2] = s;
  while (x != s) pa2[++t2] = x, x = fa[x];
  reverse(pa2 + 2, pa2 + t2 + 1);
  pa2[++t2] = t;
  x = w[p2].x;
  pa3[++t3] = s;
  while (x != s) pa3[++t3] = x, x = fa[x];
  reverse(pa3 + 2, pa3 + t3 + 1);
  pa3[++t3] = w[p2].y;
  int rem = t3;
  x = t;
  while (x != w[p2].y) pa3[++t3] = x, x = fa[x];
  reverse(pa3 + rem + 1, pa3 + t3 + 1);
}
int main() {
  n = read(), m = read();
  for (int i = 1; i <= m; i++) add(read(), read());
  for (int i = 1; i <= n; i++)
    if (!dep[i]) dfs(i, 0);
  for (int i = 1; i <= m; i++)
    if (!vis[i]) cf(w[i].x, w[i].y);
  for (int i = 1; i <= n; i++)
    if (dep[i] == 1) dfs2(i);
  if (!gg) return puts("NO"), 0;
  get();
  puts("YES");
  printf("%d", t1);
  for (int i = 1; i <= t1; i++) printf(" %d", pa1[i]);
  printf("\n");
  printf("%d", t2);
  for (int i = 1; i <= t2; i++) printf(" %d", pa2[i]);
  printf("\n");
  printf("%d", t3);
  for (int i = 1; i <= t3; i++) printf(" %d", pa3[i]);
  printf("\n");
  return 0;
}
