#include <bits/stdc++.h>
using namespace std;
struct edge {
  int to, nxxt;
} e[200004 << 1];
int n, m, head[200004], cnt = 1, fa[200004], dep[200004], c[200004],
                        b[200004][2], tot, bel[200004][2], ans[200004], js;
bool vis[200004];
inline void ins(int u, int v) {
  e[cnt] = (edge){v, head[u]};
  head[u] = cnt++;
}
void df5(int te, int la) {
  vis[te] = 1;
  for (int i = head[te]; i; i = e[i].nxxt) {
    int j = e[i].to;
    if (j == la) continue;
    if (vis[j]) {
      if (dep[j] < dep[te]) b[++tot][0] = te, b[tot][1] = j;
    } else {
      fa[j] = te, dep[j] = dep[te] + 1;
      df5(j, te);
    }
  }
}
void pt() {
  printf("%d ", js);
  for (int i = 1; i <= js; i++) printf("%d ", ans[i]);
  puts("");
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    ins(x, y), ins(y, x);
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) df5(i, i);
  for (int i = 1; i <= tot; i++) {
    int x = b[i][0];
    while (x ^ b[i][1]) {
      if (!c[x]) {
        c[x] = 1;
        bel[x][0] = b[i][0], bel[x][1] = b[i][1];
        x = fa[x];
      } else {
        puts("YES");
        int s1 = bel[x][0], t1 = bel[x][1], s2 = b[i][0], t2 = b[i][1];
        if (dep[t1] < dep[t2]) swap(s1, s2), swap(t1, t2);
        ans[++js] = t1;
        int te = s1;
        while (te ^ x) ans[++js] = te, te = fa[te];
        ans[++js] = te;
        pt();
        js = 0;
        ans[++js] = t1;
        te = x;
        while (te ^ t1) ans[++js] = te, te = fa[te];
        reverse(ans + 2, ans + js + 1);
        pt();
        js = 0;
        te = t1;
        while (te ^ t2) ans[++js] = te, te = fa[te];
        ans[++js] = te;
        te = s2;
        while (te ^ x) ans[++js] = te, te = fa[te];
        ans[++js] = te;
        pt();
        return 0;
      }
    }
  }
  puts("NO");
}
