#include <bits/stdc++.h>
using namespace std;
int N, M;
vector<vector<int> > adj;
vector<int> U, V;
vector<int> tin, bck, id, sz;
stack<int> st;
int timer = 0, bcnt = 0;
void dfs(int u, int p, bool root) {
  tin[u] = timer++;
  bck[u] = tin[u];
  int Chd_cnt = 0;
  for (int i = 0; i < adj[u].size(); i++) {
    int e = adj[u][i];
    int v = U[e] + V[e] - u;
    if (tin[v] == -1) {
      Chd_cnt++;
      st.push(e);
      dfs(v, u, 0);
      if ((root && Chd_cnt > 1) || (!root && bck[v] >= tin[u])) {
        while (1) {
          int t = st.top();
          st.pop();
          id[t] = bcnt;
          if (t == e) break;
        }
        bcnt++;
      }
      bck[u] = min(bck[u], bck[v]);
    } else if (v != p && tin[v] < tin[u]) {
      bck[u] = min(bck[u], tin[v]);
      st.push(e);
    }
  }
}
vector<int> chk, vis, fe, Vcycle, Ecycle;
bool dfs2(int u, int c) {
  vis[u] = c;
  for (int i = 0; i < adj[u].size(); i++) {
    int e = adj[u][i];
    int v = U[e] + V[e] - u;
    if (id[e] != c) continue;
    if (e == fe[u]) continue;
    if (vis[v] == c) {
      Vcycle.clear();
      Vcycle.push_back(v);
      Ecycle[e] = 1;
      while (u != v) {
        Vcycle.push_back(u);
        e = fe[u];
        Ecycle[e] = 1;
        u = U[e] + V[e] - u;
      }
      return true;
    }
    fe[v] = e;
    if (dfs2(v, c)) return true;
  }
  return false;
}
vector<int> dest, par, path[3];
bool dfs3(int u, int c, int st) {
  vis[u] = 1;
  for (int i = 0; i < adj[u].size(); i++) {
    int e = adj[u][i];
    int v = U[e] + V[e] - u;
    if (id[e] != c) continue;
    if (Ecycle[e]) continue;
    if (dest[v]) {
      path[0].push_back(v);
      while (u != st) {
        path[0].push_back(u);
        u = par[u];
      }
      path[0].push_back(st);
      return true;
    }
    if (vis[v]) continue;
    par[v] = u;
    if (dfs3(v, c, st)) return true;
  }
  return false;
}
void solve(int st, int col) {
  vis = vector<int>(N, 0);
  dest = vector<int>(N, 0);
  par = vector<int>(N, -1);
  for (int i = 0; i < Vcycle.size(); i++) {
    if (Vcycle[i] == st) continue;
    dest[Vcycle[i]] = 1;
  }
  dfs3(st, col, st);
  int pos = 0;
  bool f = false;
  while (1) {
    if (Vcycle[pos] == path[0][0]) f = true;
    if (f) path[1].push_back(Vcycle[pos]);
    if (f && Vcycle[pos] == path[0].back()) break;
    pos = (pos + 1) % Vcycle.size();
  }
  pos = 0;
  f = false;
  while (1) {
    if (Vcycle[pos] == path[0][0]) f = true;
    if (f) path[2].push_back(Vcycle[pos]);
    if (f && Vcycle[pos] == path[0].back()) break;
    pos = (pos + (int)Vcycle.size() - 1) % Vcycle.size();
  }
  for (int i = 0; i < 3; i++) {
    printf("%d ", path[i].size());
    for (int j = 0; j < path[i].size(); j++) {
      printf("%d ", path[i][j] + 1);
    }
    printf("\n");
  }
}
int main() {
  scanf("%d %d", &N, &M);
  adj.resize(N);
  U.resize(M);
  V.resize(M);
  for (int i = 0; i < M; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    u--;
    v--;
    adj[u].push_back(i);
    adj[v].push_back(i);
    U[i] = u;
    V[i] = v;
  }
  tin = bck = vector<int>(N, -1);
  id = vector<int>(M, -1);
  for (int i = 0; i < N; i++)
    if (tin[i] == -1) {
      dfs(i, -1, 1);
      while (!st.empty()) {
        int t = st.top();
        st.pop();
        id[t] = bcnt;
      }
      bcnt++;
    }
  sz = vector<int>(bcnt, 0);
  for (int i = 0; i < M; i++) {
    sz[id[i]]++;
  }
  chk = vector<int>(bcnt, 0);
  vis = vector<int>(N, -1);
  fe = vector<int>(N, -1);
  Ecycle = vector<int>(M, 0);
  for (int i = 0; i < M; i++)
    if (!chk[id[i]]) {
      chk[id[i]] = 1;
      if (sz[id[i]] == 1) continue;
      dfs2(U[i], id[i]);
      for (int j = 0; j < Vcycle.size(); j++) {
        int u = Vcycle[j];
        for (int k = 0; k < adj[u].size(); k++) {
          int e = adj[u][k];
          if (id[e] != id[i]) continue;
          if (Ecycle[e]) continue;
          printf("YES\n");
          solve(u, id[i]);
          return 0;
        }
      }
    }
  printf("NO");
}
