#include <bits/stdc++.h>
template <typename T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  bool flag = false;
  while (!isdigit(c)) {
    if (c == '-') flag = true;
    c = getchar();
  }
  while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar();
  if (flag) x = -x;
}
using namespace std;
inline void MIN(int &a, int b) {
  if (b < a) a = b;
}
int n, m;
struct edge {
  int nxt, to;
  edge() {}
  edge(int jzp, int zzz) { nxt = jzp, to = zzz; }
} e[201000 << 1];
int head[201000], ecnt = 1;
inline void addedge(int from, int to) {
  e[++ecnt] = edge(head[from], to);
  head[from] = ecnt;
}
inline void Addedge(int u, int v) { addedge(u, v), addedge(v, u); }
int low[201000], dfn[201000], dcnt;
int stk[201000], stop;
vector<int> dcc[201000];
set<int> indcc[201000];
int dcctot;
void tarjan(int cur) {
  low[cur] = dfn[cur] = ++dcnt;
  stk[++stop] = cur;
  for (int i = head[cur]; i; i = e[i].nxt) {
    int to = e[i].to;
    if (!dfn[to]) {
      tarjan(to);
      MIN(low[cur], low[to]);
      if (low[to] >= dfn[cur]) {
        int tmp;
        ++dcctot;
        do {
          tmp = stk[stop--];
          indcc[tmp].insert(dcctot);
          dcc[dcctot].push_back(tmp);
        } while (tmp != to);
        dcc[dcctot].push_back(cur);
        indcc[cur].insert(dcctot);
      }
    } else
      MIN(low[cur], dfn[to]);
  }
}
vector<int> ve[201000];
int du[201000];
inline void aded(int u, int v) {
  ve[u].push_back(v);
  ++du[u];
}
int que[201000], front, rear, pre[201000];
bool vis[201000];
int pos[201000];
inline void bfs_xy(int s, int t, int cant) {
  que[++rear] = s;
  vis[s] = vis[cant] = true;
  while (front < rear) {
    int cur = que[++front];
    for (unsigned int j = 0; j < ve[cur].size(); ++j) {
      int to = ve[cur][j];
      if (vis[to]) continue;
      vis[to] = true;
      pre[to] = cur;
      if (to == t) return;
      que[++rear] = to;
    }
  }
}
inline int bfs_z(int s, int cant) {
  front = rear = 0;
  memset(vis, 0, sizeof(vis));
  memset(pre, 0, sizeof(pre));
  if (pos[s]) return pos[s];
  que[++rear] = s;
  vis[s] = vis[cant] = true;
  while (front < rear) {
    int cur = que[++front];
    for (unsigned int j = 0; j < ve[cur].size(); ++j) {
      int to = ve[cur][j];
      if (vis[to]) continue;
      vis[to] = true;
      pre[to] = cur;
      if (pos[to]) return pos[to];
      que[++rear] = to;
    }
  }
  puts("QAQ");
  exit(-1);
  return 0;
}
int h[201000], htot, ans[201000], atot;
inline void sol(int s) {
  int x = ve[s][0], y = ve[s][1], z = ve[s][2];
  bfs_xy(x, y, s);
  if (!pre[y]) {
    printf("s = %d, x = %d, y = %d, z = %d\n", s, x, y, z);
    puts("QAQ");
    exit(0);
  }
  int p = y;
  while (p != x) h[++htot] = p, pos[p] = htot, p = pre[p];
  h[++htot] = x, pos[x] = htot;
  int t = bfs_z(z, s);
  puts("YES");
  printf("%d ", t + 1);
  printf("%d ", s);
  for (int i = 1; i <= t; ++i) printf("%d ", h[i]);
  puts("");
  printf("%d ", htot - t + 2);
  printf("%d ", s);
  for (int i = htot; i >= t; --i) printf("%d ", h[i]);
  puts("");
  p = h[t];
  while (p != z) ans[++atot] = p, p = pre[p];
  ans[++atot] = z;
  printf("%d ", atot + 1);
  printf("%d ", s);
  for (int i = atot; i; --i) printf("%d ", ans[i]);
  puts("");
}
vector<int> dcce[201000];
int main() {
  read(n), read(m);
  for (int i = 1; i <= m; ++i) {
    int u, v;
    read(u), read(v);
    Addedge(u, v);
  }
  for (int i = 1; i <= n; ++i)
    if (!dfn[i]) tarjan(i);
  for (int i = 2; i <= ecnt; i += 2) {
    int u = e[i].to, v = e[i ^ 1].to;
    if (indcc[u].size() > indcc[v].size()) swap(u, v);
    for (set<int>::iterator it = indcc[u].begin(); it != indcc[u].end(); ++it) {
      int c = *it;
      if (indcc[v].find(c) != indcc[v].end()) {
        dcce[c].push_back(i);
        break;
      }
    }
  }
  for (int i = 1; i <= dcctot; ++i) {
    for (unsigned int j = 0; j < dcce[i].size(); ++j) {
      int jzp = dcce[i][j];
      int u = e[jzp].to, v = e[jzp ^ 1].to;
      aded(u, v), aded(v, u);
    }
    for (unsigned int j = 0; j < dcc[i].size(); ++j) {
      int cur = dcc[i][j];
      if (du[cur] >= 3) {
        sol(cur);
        return 0;
      }
    }
    for (unsigned int j = 0; j < dcc[i].size(); ++j) {
      int cur = dcc[i][j];
      du[cur] = 0;
      ve[cur].clear();
    }
  }
  puts("NO");
  return 0;
}
