#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, c = getchar(), f = 0;
  for (; c > '9' || c < '0'; f = c == '-', c = getchar())
    ;
  for (; c >= '0' && c <= '9'; x = (x << 1) + (x << 3) + c - '0', c = getchar())
    ;
  return f ? -x : x;
}
inline void write(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) write(x / 10);
  putchar(x % 10 + 48);
}
const int N = 100000 + 10;
int n, m, cnt = 1, head[N], du[N], layer[N], leader[N], q[N];
bool vis1[N], vis2[N], vis3[N * 2];
vector<vector<int> > ans;
vector<int> tmp, _;
vector<pair<int, int> > comp;
struct edge {
  int to, nxt;
} e[N * 4];
void addedge(int u, int v) {
  e[++cnt] = (edge){v, head[u]};
  head[u] = cnt;
  e[++cnt] = (edge){u, head[v]};
  head[v] = cnt;
  du[u]++;
  du[v]++;
}
void dfs(int u, int fa, int lineid) {
  vis1[u] = 1;
  vis2[layer[u]] = 1;
  tmp.push_back(u);
  for (int i = head[u], v; i; i = e[i].nxt)
    if ((i >> 1) != lineid) {
      if (!vis1[v = e[i].to]) {
        dfs(v, u, i >> 1);
        tmp.push_back(u);
        for (; cnt >= 0 && vis2[comp[cnt].second]; cnt--)
          ;
        if (cnt >= 0) {
          vis3[i >> 1] = 1;
          v = leader[comp[cnt].second];
          ans.push_back(tmp);
          tmp.clear();
          _.clear();
          _.push_back(i >> 1);
          _.push_back(u);
          _.push_back(v);
          ans.push_back(_);
          dfs(v, u, i >> 1);
          tmp.push_back(u);
        }
      } else {
        if (vis3[i >> 1]) continue;
        for (; cnt >= 0 && vis2[comp[cnt].second]; cnt--)
          ;
        if (cnt >= 0) {
          vis3[i >> 1] = 1;
          v = leader[comp[cnt].second];
          ans.push_back(tmp);
          tmp.clear();
          _.clear();
          _.push_back(i >> 1);
          _.push_back(u);
          _.push_back(v);
          ans.push_back(_);
          dfs(v, u, i >> 1);
          tmp.push_back(u);
        }
      }
    }
}
void print() {
  puts("YES");
  write(ans.size() / 2);
  puts("");
  for (int i = (int)0; i <= (int)ans.size() - 1; i++) {
    if (i & 1)
      write(ans[i][0]), putchar(' '), write(ans[i][1]), putchar(' '),
          write(ans[i][2]), puts("");
    else {
      write(ans[i].size());
      for (int j = (int)0; j <= (int)ans[i].size() - 1; j++)
        putchar(' '), write(ans[i][j]);
      puts("");
    }
  }
}
int findbridge() {
  for (int i = (int)2; i <= (int)n; i++) vis1[i] = 0;
  for (int i = (int)1; i <= (int)m; i++) vis3[i] = 0;
  for (int i = (int)2; i <= (int)n; i++)
    if (!vis1[i]) {
      q[*q = 1] = i;
      vis1[i] = 1;
      for (int j = (int)1; j <= (int)*q; j++) {
        int u = q[j];
        for (int k = head[u], v; k; k = e[k].nxt)
          if (!vis3[k >> 1]) {
            vis3[k >> 1] = 1;
            if (vis1[v = e[k].to])
              return k >> 1;
            else
              vis1[v] = 1, q[++*q] = v;
          }
      }
    }
  return 0;
}
int getblo(int l, int r) {
  for (int i = (int)l; i <= (int)r; i++) vis1[i] = 0;
  int blo = 0;
  comp.clear();
  for (int i = (int)l; i <= (int)r; i++)
    if (!vis1[i]) {
      ++blo;
      q[*q = 1] = i;
      vis1[i] = 1;
      for (int j = (int)1; j <= (int)*q; j++) {
        int u = q[j];
        for (int k = head[u], v; k; k = e[k].nxt)
          if (!vis1[v = e[k].to]) vis1[v] = 1, q[++*q] = v;
      }
      for (int j = (int)1; j <= (int)*q; j++) layer[q[j]] = blo;
      leader[blo] = q[1];
      comp.push_back(make_pair(*q, blo));
    }
  sort(comp.begin(), comp.end());
  return blo;
}
void go(int id) {
  int u = 1;
  for (int i = (int)2; i <= (int)n; i++) {
    for (int j = head[i], pre; j; pre = j, j = e[j].nxt)
      if ((j >> 1) == id) {
        if (du[i] > 1) u = i;
        du[i]--;
        if (j == head[i])
          head[i] = e[j].nxt;
        else
          e[pre].nxt = e[j].nxt;
        break;
      }
  }
  getblo(2, n);
  cnt = comp.size() - 1;
  for (int i = (int)1; i <= (int)n; i++) vis1[i] = vis2[i] = 0;
  for (int i = (int)1; i <= (int)m; i++) vis3[i] = 0;
  vis1[1] = 1;
  _.clear();
  _.push_back(1);
  ans.push_back(_);
  _.clear();
  _.push_back(id);
  _.push_back(1);
  _.push_back(u);
  ans.push_back(_);
  dfs(u, 1, 0);
  if (tmp.size()) ans.push_back(tmp), tmp.clear();
  print();
}
int main() {
  n = read(), m = read();
  for (int i = (int)1; i <= (int)m; i++) addedge(read(), read());
  if (n == 1) return puts("YES\n0\n1 1\n"), 0;
  int blo = getblo(1, n);
  if (m < blo - 1) return puts("NO"), 0;
  if (du[1]) {
    for (int i = (int)1; i <= (int)n; i++) vis1[i] = vis2[i] = 0;
    for (int i = (int)1; i <= (int)m; i++) vis3[i] = 0;
    cnt = comp.size() - 1;
    dfs(1, 0, 0);
    if (tmp.size()) ans.push_back(tmp), tmp.clear();
    print();
  } else {
    int id = findbridge();
    if (id)
      go(id);
    else {
      if (m < blo)
        puts("NO");
      else {
        for (int i = (int)2; i <= (int)n; i++)
          if (du[i] > 1) {
            id = head[i] / 2;
            break;
          }
        if (id)
          go(id);
        else
          puts("NO");
      }
    }
  }
}
