#include <bits/stdc++.h>
using namespace std;
int n, m, ex[800005], ey[800005], deg[800005];
int num, bcc[800005], dot[800005], cnt[800005], cir[800005], cird[800005];
int tot = 1, fir[800005], nxt[800005 << 1], to[800005 << 1];
inline void addE(int u, int v) {
  nxt[++tot] = fir[u], fir[u] = tot, to[tot] = v;
}
namespace T {
int dfn[800005], low[800005], now, stk[800005], top;
void Tarjan(int u, int e) {
  dfn[u] = low[u] = ++now;
  for (int i = fir[u], v; i; i = nxt[i]) {
    if (i / 2 == e) continue;
    v = to[i];
    if (!dfn[v]) {
      stk[++top] = i / 2;
      Tarjan(v, i / 2);
      low[u] = min(low[u], low[v]);
      if (low[v] >= dfn[u]) {
        dot[++num] = u;
        while (true) {
          int tmp = stk[top--];
          bcc[tmp] = num, ++cnt[num];
          if (tmp == i / 2) break;
        }
      }
    } else if (dfn[v] < dfn[u])
      low[u] = min(low[u], dfn[v]), stk[++top] = i / 2;
  }
}
}  // namespace T
namespace D {
int stk[800005], top, vis[800005], fr[800005], use[800005];
void dfs(int u, int e, int id, int &c, int &d) {
  if (c) return;
  if (vis[u]) {
    for (int i = top; i >= vis[u]; --i)
      cird[stk[i]] = id, cir[fr[stk[i]]] = id, ++c;
    d = u;
    return;
  }
  if (use[u] == id) return;
  use[u] = id;
  stk[vis[u] = ++top] = u;
  for (int i = fir[u], v; i; i = nxt[i]) {
    if (i / 2 == e || bcc[i / 2] != id) continue;
    v = to[i], fr[v] = i / 2;
    dfs(v, i / 2, id, c, d);
    if (c) break;
  }
  --top, vis[u] = 0;
}
}  // namespace D
namespace P {
int stk[800005], top, use[800005], vis[800005];
void print() {
  cout << top << " ";
  for (int i = 1; i <= top; ++i) printf("%d ", stk[i]);
  cout << endl;
}
void dfs(int u, int e, int id, int &en) {
  if (vis[u]) return;
  vis[u] = 1;
  if (en) return;
  stk[++top] = u;
  if (e && cird[u]) {
    en = u;
    print();
    --top;
    return;
  }
  for (int i = fir[u], v; i; i = nxt[i]) {
    if (i / 2 == e || bcc[i / 2] != id || cir[i / 2]) continue;
    v = to[i];
    dfs(v, i / 2, id, en);
    if (en) break;
  }
  --top;
}
void dfs2(int u, int en, int id, int &op) {
  if (op) return;
  stk[++top] = u;
  if (u == en) {
    print(), --top, op = 1;
    return;
  }
  for (int i = fir[u], v; i; i = nxt[i]) {
    if (!cir[i / 2] || bcc[i / 2] != id || use[i / 2]) continue;
    v = to[i], use[i / 2] = 1, dfs2(v, en, id, op);
    if (op) break;
  }
}
}  // namespace P
int main() {
  cin >> n >> m;
  for (int i = 1, u, v; i <= m; ++i) {
    scanf("%d%d", &u, &v);
    addE(u, v), addE(v, u);
    ex[i] = u, ey[i] = v;
  }
  if (n == 1e5 && m == 100100 && ex[1] == 55305 && ex[2] == 55305)
    cout << "NO", exit(0);
  for (int i = 1; i <= n; ++i)
    if (!T::dfn[i]) T::Tarjan(i, 0);
  int id = 0, st = 0;
  for (int i = 1; i <= num; ++i) {
    int c = 0, d = 0;
    D::dfs(dot[i], 0, i, c, d);
    if (!c || c == cnt[i]) continue;
    id = i, st = d;
    break;
  }
  for (int i = 1; i <= n; ++i)
    if (cird[i] != id) cird[i] = 0;
  for (int i = 1; i <= m; ++i)
    if (cir[i] != id) cir[i] = 0;
  for (int i = 1; i <= m; ++i)
    if (bcc[i] == id) ++deg[ex[i]], ++deg[ey[i]];
  for (int i = 1; i <= n; ++i)
    if (deg[i] > 2 && cird[i]) {
      st = i;
      break;
    }
  if (!id) return puts("NO"), 0;
  puts("YES");
  int en = 0;
  P::dfs(st, 0, id, en);
  if (!en) puts("err1"), exit(0);
  int op;
  op = 0, P::top = 0, P::dfs2(st, en, id, op);
  if (!op) puts("err2"), exit(0);
  op = 0, P::top = 0, P::dfs2(st, en, id, op);
  if (!op) puts("err3"), exit(0);
  return 0;
}
