#include <bits/stdc++.h>
using namespace std;
struct apple {
  int v, nxt, no;
} edge[1000011 * 4];
struct point {
  int x, y;
} ee[1000011 * 4];
int indexx[1000011], tot, fa[1000011], deep[1000011], n, m, father[1000011],
    s1[1000011], s2[1000011], t1[1000011], t2[1000011], Ans[4][1000011], len1,
    len2;
int S, T, cnt, used[1000011], vist[1000011], Mark[1000011];
vector<int> V;
void addedge(int x, int y, int z) {
  edge[++tot].v = y;
  edge[tot].no = z;
  edge[tot].nxt = indexx[x];
  indexx[x] = tot;
}
int find(int u) {
  if (u == father[u]) return u;
  return father[u] = find(father[u]);
}
void basic_dfs(int u, int Fa, int dep) {
  deep[u] = dep;
  fa[u] = Fa;
  int t = indexx[u], vv;
  while (t) {
    vv = edge[t].v;
    if (vv != Fa) {
      basic_dfs(vv, u, dep + 1);
    }
    t = edge[t].nxt;
  }
}
int dfs(int u) {
  if (u == T) {
    V.push_back(T);
    return 1;
  } else if (used[u])
    return 0;
  used[u] = 1;
  int t = indexx[u], vv;
  while (t) {
    vv = edge[t].v;
    if (Mark[edge[t].no]) {
      int k = dfs(vv);
      if (k) {
        V.push_back(u);
        if (u == S) {
          cnt++;
          printf("%d ", V.size());
          for (int i = 0; i < V.size(); i++) {
            printf("%d ", V[i]);
          }
          printf("\n");
          V.clear();
          if (cnt == 3) return 0;
        } else
          return 1;
      }
    }
    t = edge[t].nxt;
  }
  used[u] = 0;
  return 0;
}
void solve(int k, int x, int y) {
  int flag = 0;
  s1[0] = s2[0] = t1[0] = t2[0] = len1 = len2 = 0;
  while (x != y) {
    if (deep[x] > deep[y]) {
      if (flag) {
        if (vist[x] == flag) s1[++s1[0]] = x, s1[++s1[0]] = fa[x];
      } else if (vist[x]) {
        flag = vist[x];
        s1[++s1[0]] = x, s1[++s1[0]] = fa[x];
      } else
        vist[x] = k;
      t1[++t1[0]] = x;
      x = fa[x];
    } else {
      if (flag) {
        if (vist[y] == flag) s2[++s2[0]] = y, s2[++s2[0]] = fa[y];
      } else if (vist[y]) {
        flag = vist[y];
        s2[++s2[0]] = y, s2[++s2[0]] = fa[y];
      } else
        vist[y] = k;
      t2[++t2[0]] = y;
      y = fa[y];
    }
  }
  if (flag) {
    if (vist[x] == flag) s1[++s1[0]] = x;
  } else if (vist[x]) {
    flag = vist[x];
    s1[++s1[0]] = x;
  }
  t1[++t1[0]] = x;
  if (flag) {
    for (int i = 1; i <= t1[0]; i++) Ans[1][++len1] = t1[i];
    for (int i = t2[0]; i >= 1; i--) Ans[1][++len1] = t2[i];
    for (int i = 1; i <= s1[0]; i++) Ans[2][++len2] = s1[i];
    for (int i = s2[0]; i >= 1; i--) Ans[2][++len2] = s2[i];
    S = Ans[2][1], T = Ans[2][len2];
    if (S == T) return;
    printf("YES\n");
    Mark[flag] = Mark[k] = 1;
    dfs(S);
    exit(0);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) father[i] = i;
  for (int i = 1, x, y; i <= m; i++) {
    scanf("%d%d", &x, &y);
    ee[i].x = x, ee[i].y = y;
    int fx = find(x), fy = find(y);
    if (fx == fy) continue;
    Mark[i] = 1;
    father[fx] = fy;
    addedge(x, y, i);
    addedge(y, x, i);
  }
  for (int i = 1; i <= n; i++) {
    if (father[i] == i) {
      basic_dfs(i, 0, 1);
    }
  }
  for (int i = 1; i <= m; i++) {
    if (!Mark[i]) addedge(ee[i].x, ee[i].y, i), addedge(ee[i].y, ee[i].x, i);
  }
  for (int i = 1; i <= m; i++) {
    if (Mark[i]) continue;
    solve(i, ee[i].x, ee[i].y);
  }
  printf("NO\n");
  return 0;
}
