#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> G[201116];
int dep[201116], par[201116], dir[201116];
void dfs(int u, int fa) {
  dep[u] = dep[fa] + 1, par[u] = fa;
  for (int i = 0; i < G[u].size(); ++i) {
    int v = G[u][i];
    if (v == fa) continue;
    if (!dep[v])
      dfs(v, u), dir[u] += dir[v];
    else if (dep[v] < dep[u])
      ++dir[u], --dir[v];
  }
}
int l, r, L, R;
int s;
void dfs2(int u, int fa) {
  for (int i = 0; i < G[u].size(); ++i) {
    int v = G[u][i];
    if (dep[v] == dep[u] + 1)
      dfs2(v, u);
    else if (dep[v] < dep[s] && v != fa) {
      if (l)
        L = u, R = v;
      else
        l = u, r = v;
    }
    if (L) return;
  }
}
vector<int> ans, tmp;
void doit(int fr, int to) {
  if (dep[fr] < dep[to]) {
    tmp.clear();
    to = par[to];
    while (to != fr) tmp.push_back(to), to = par[to];
    tmp.push_back(fr);
    for (auto it = tmp.rbegin(); it != tmp.rend(); ++it) ans.push_back(*it);
    return;
  }
  while (fr != to) ans.push_back(fr), fr = par[fr];
}
int main() {
  cin >> n >> m;
  for (int i = 1, u, v; i <= m; ++i) {
    scanf("%d%d", &u, &v);
    G[u].push_back(v), G[v].push_back(u);
  }
  for (int i = 1; i <= n; ++i)
    if (!dep[i]) dfs(i, 0);
  for (int i = 1; i <= n; ++i)
    if (dir[i] > 1) {
      s = i;
      break;
    }
  if (!s) return puts("NO"), 0;
  puts("YES");
  dfs2(s, par[s]);
  if (dep[R] < dep[r]) swap(r, R), swap(l, L);
  int x = l, y = L;
  while (x != y) dep[x] > dep[y] ? x = par[x] : y = par[y];
  doit(x, l), ans.push_back(l), doit(r, R), ans.push_back(R);
  printf("%d ", ans.size());
  for (auto& x : ans) printf("%d ", x);
  puts("");
  ans.clear();
  doit(x, L), ans.push_back(L), ans.push_back(R);
  printf("%d ", ans.size());
  for (auto& x : ans) printf("%d ", x);
  puts("");
  ans.clear();
  doit(x, R), ans.push_back(R);
  printf("%d ", ans.size());
  for (auto& x : ans) printf("%d ", x);
  puts("");
}
