#include <bits/stdc++.h>
using namespace std;
int n, m, t, x, y, ed, pt, bcc, done, cnt, cycl;
int qd[400005], qn[400005], l[400005], v[400005], w[400005], vv[400005],
    d[400005], AP[400005], p[400005], vis[400005];
int col[400005], par[400005], L[400005], C[400005], cc[400005], vc[400005],
    pp[400005];
vector<int> P;
void bd(int x, int y) { qd[++ed] = y, qn[ed] = l[x], l[x] = ed; }
void dfs(int x, int y) {
  int c = 0;
  v[x] = w[x] = ++t;
  p[x] = y;
  for (int i = l[x]; i; i = qn[i])
    if (!v[qd[i]]) {
      dfs(qd[i], x);
      w[x] = min(w[x], w[qd[i]]);
      ++c;
      if ((y >= 0 && w[qd[i]] >= v[x]) || (y < 0 && c > 1)) AP[x] = 1;
    } else if (qd[i] != y)
      w[x] = min(w[x], v[qd[i]]);
}
void color(int x, int y) {
  vis[x] = 1;
  for (int i = l[x]; i; i = qn[i]) {
    if (col[i] || col[i ^ 1]) continue;
    if (p[x] == -1 || (AP[x] && w[qd[i]] >= v[x])) {
      col[i] = col[i ^ 1] = ++bcc;
      color(qd[i], bcc);
    } else {
      col[i] = col[i ^ 1] = y;
      if (!vis[qd[i]]) color(qd[i], y);
    }
  }
}
void cyc(int x, int p) {
  vv[x] = 1;
  par[x] = p;
  for (int i = (l[x]); i; i = qn[i])
    if (qd[i] != p) {
      if (!vv[qd[i]])
        cyc(qd[i], x);
      else if (vv[qd[i]] == 1 && !cycl) {
        int t = x;
        while (1) {
          C[cycl++] = t;
          cc[t] = 1;
          if (t == qd[i]) break;
          t = par[t];
        }
      }
    }
  vv[x] = 2;
}
void shoot(int x, int p) {
  if (done) return;
  vc[x] = 1;
  pp[x] = p;
  for (int i = (l[x]); i; i = qn[i])
    if (!vc[qd[i]] && !done) {
      if (p == -1 && cc[qd[i]]) continue;
      if (cc[qd[i]]) {
        done = 1;
        pp[qd[i]] = x;
        pt = qd[i];
      } else
        shoot(qd[i], x);
    }
}
void print() {
  printf("%d", P.size());
  for (int i = (0); i < (P.size()); i++) printf(" %d", P[i]);
  puts("");
}
void doit(int y, int j) {
  P.clear();
  for (int k = y; k != j; k = (k + 1 == cycl ? 0 : k + 1))
    P.push_back(C[k] + 1);
  P.push_back(C[j] + 1);
  print();
  P.clear();
  for (int k = y; k != j; k = (k == 0 ? cycl - 1 : k - 1))
    P.push_back(C[k] + 1);
  P.push_back(C[j] + 1);
  print();
}
struct edge {
  int x, y, c;
  bool operator<(edge const &T) const { return c < T.c; }
};
edge E[400005];
int main() {
  scanf("%d%d", &n, &m);
  ed = 1;
  for (int i = (0); i < (m); i++) {
    scanf("%d%d", &x, &y), --x, --y;
    bd(x, y), bd(y, x);
  }
  for (int i = (0); i < (n); i++)
    if (!v[i]) dfs(i, -1);
  for (int i = (0); i < (n); i++)
    if (!vis[i]) color(i, -1);
  memset(l, 0, sizeof(l));
  for (int i = (2); i <= (ed); i++) {
    E[i - 2].x = qd[i];
    E[i - 2].y = qd[i ^ 1];
    E[i - 2].c = col[i];
  }
  int Edges = ed - 1;
  sort(E, E + Edges);
  int ptr = 0;
  for (int bb = (1); bb <= (bcc); bb++) {
    ed = cnt = 0;
    while (ptr < Edges && E[ptr].c == bb) {
      bd(E[ptr].x, E[ptr].y);
      ++d[E[ptr].x];
      L[cnt++] = E[ptr].x;
      ++ptr;
    }
    if (cnt < 4) goto AFTER;
    cycl = 0;
    cyc(L[0], -1);
    for (int j = (0); j < (cycl); j++)
      if (d[C[j]] > 2) {
        for (int k = (l[C[j]]); k; k = qn[k]) {
          int y = qd[k];
          if (!cc[y]) continue;
          if (y == C[(j + 1) % cycl] || y == C[(j + cycl - 1) % cycl]) continue;
          puts("YES");
          printf("2 %d %d\n", y + 1, C[j] + 1);
          int ty = y;
          for (int k = (0); k < (cycl); k++)
            if (C[k] == ty) y = k;
          doit(y, j);
          return 0;
        }
        done = 0;
        shoot(C[j], -1);
        if (done) {
          puts("YES");
          for (int k = (0); k < (cycl); k++)
            if (C[k] == pt) y = k;
          doit(y, j);
          P.clear();
          while (1) {
            P.push_back(pt + 1);
            if (pt == C[j]) break;
            pt = pp[pt];
          }
          print();
          return 0;
        }
      }
  AFTER:
    for (int i = (0); i < (cnt); i++)
      vv[L[i]] = vc[L[i]] = cc[L[i]] = l[L[i]] = d[L[i]] = 0;
  }
  puts("NO");
  return 0;
}
