#include <bits/stdc++.h>
using namespace std;
const int N = (int)2e5 + 5;
vector<int> g[N], son[N];
bool used[N];
int tin[N], tout[N], tup[N];
vector<int> fstep[N];
int start = -1, a, b, c;
void dfs(int v, int p) {
  static int TIME = 0;
  tin[v] = TIME++;
  tup[v] = tin[v];
  used[v] = true;
  for (int u : g[v]) {
    if (u == p) continue;
    if (used[u]) {
      tup[v] = min(tup[v], tin[u]);
    } else {
      son[v].push_back(u);
      dfs(u, v);
      tup[v] = min(tup[v], tup[u]);
    }
  }
  for (int x : g[v]) {
    fstep[x].clear();
  }
  for (int x : g[v]) {
    if (tin[x] < tin[v]) {
      fstep[p].push_back(x);
    } else {
      auto it =
          lower_bound((son[v]).begin(), (son[v]).end(), x,
                      [&](int _x, int __x) { return tout[_x] < tout[__x]; });
      if (tup[*it] < tin[v])
        fstep[p].push_back(x);
      else
        fstep[*it].push_back(x);
    }
  }
  for (int x : g[v]) {
    if (start == -1 && (int)(fstep[x]).size() >= 3) {
      start = v;
      a = fstep[x][0];
      b = fstep[x][1];
      c = fstep[x][2];
    }
  }
  tout[v] = TIME++;
}
bool inPath[N];
int par[N];
bool dfs2(int v, vector<int>& path, function<bool(int)> stop) {
  if (stop(v)) {
    path.push_back(v);
    for (int u = v; par[u] != u; u = par[u]) path.push_back(par[u]);
    reverse((path).begin(), (path).end());
    return true;
  }
  used[v] = true;
  for (int u : g[v]) {
    if (u != start && !used[u]) {
      par[u] = v;
      if (dfs2(u, path, stop)) return true;
    }
  }
  return false;
}
int main() {
  int n, m;
  scanf("%d %d", &n, &m);
  while (m--) {
    int u, v;
    scanf("%d %d", &u, &v);
    --u;
    --v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int x = 0; x < n; ++x) {
    if (!used[x]) dfs(x, x);
  }
  if (start == -1) {
    printf("NO\n");
    return 0;
  }
  vector<int> p1;
  par[a] = a;
  memset(used, false, sizeof used);
  dfs2(a, p1, [&](int x) { return x == b; });
  for (int x : p1) inPath[x] = true;
  vector<int> p2;
  par[c] = c;
  memset(used, false, sizeof used);
  dfs2(c, p2, [&](int x) { return inPath[x]; });
  int finish = p2.back();
  vector<int> out[3];
  out[0].push_back(start);
  for (int pos = 0; p1[pos] != finish; ++pos) out[0].push_back(p1[pos]);
  out[0].push_back(finish);
  out[1].push_back(start);
  for (int pos = (int)(p1).size() - 1; p1[pos] != finish; --pos)
    out[1].push_back(p1[pos]);
  out[1].push_back(finish);
  out[2].push_back(start);
  for (int x : p2) out[2].push_back(x);
  printf("YES\n");
  for (int ii = 0; ii < 3; ++ii) {
    printf("%d ", (int)(out[ii]).size());
    for (int x : out[ii]) printf("%d ", x + 1);
    printf("\n");
  }
}
