#include <bits/stdc++.h>
using namespace std;
template <typename tp>
inline void read(tp &x) {
  x = 0;
  char c = getchar();
  int f = 0;
  for (; c < '0' || c > '9'; f |= c == '-', c = getchar())
    ;
  for (; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar())
    ;
  if (f) x = -x;
}
const int N = 3e5 + 233;
struct E {
  int nxt, from, to;
} e[N << 2];
int head[N], e_cnt = 0;
int dep[N], fa[N], vis[N], cov[N], x = -1, y = -1;
int n, m;
inline void adde(int x, int y) {
  e[++e_cnt] = (E){head[x], x, y};
  head[x] = e_cnt;
}
inline void dfs(int u, int fat) {
  dep[u] = dep[fa[u] = fat] + 1;
  vis[u] = true;
  for (register int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if (v == fat) continue;
    if (vis[v]) {
      if (dep[v] > dep[u] && x == -1 && y == -1) {
        for (int t = v; t != u; t = fa[t]) {
          if (cov[t]) x = cov[t], y = i;
          cov[t] = i;
        }
      }
    } else {
      dfs(v, u);
    }
  }
}
inline int LCA(int x, int y) {
  while (x != y) {
    if (dep[x] < dep[y]) swap(x, y);
    x = fa[x];
  }
  return x;
}
vector<int> path(int x, int y, int rev = 0) {
  assert(LCA(x, y) == y);
  vector<int> ans;
  while (x != y) ans.push_back(x), x = fa[x];
  ans.push_back(x);
  if (rev) reverse(ans.begin(), ans.end());
  return ans;
}
vector<int> add(vector<int> x, vector<int> y) {
  for (int i : y) x.push_back(i);
  return x;
}
inline void print(vector<int> x) {
  cout << x.size() << " ";
  for (int i : x) cout << i << " ";
  cout << "\n";
}
int main(void) {
  read(n);
  read(m);
  for (register int i = 1; i <= (m); i++) {
    int x, y;
    read(x);
    read(y);
    adde(x, y);
    adde(y, x);
  }
  for (register int i = 1; i <= (n); i++)
    if (!vis[i]) {
      x = -1;
      y = -1;
      dfs(i, 0);
      if (x > 0 && y > 0) {
        if (dep[e[x].from] > dep[e[y].from]) swap(x, y);
        int v = LCA(e[x].to, e[y].to);
        int u = e[y].from;
        cout << "YES\n";
        print(add({u}, path(e[y].to, v)));
        print(add(path(e[y].from, e[x].from), path(e[x].to, v)));
        print(path(v, e[y].from, 1));
        return 0;
      }
    }
  cout << "NO\n";
}
