#include <bits/stdc++.h>
using namespace std;
vector<pair<int, int> > E[200005];
vector<pair<int, int> > top;
vector<vector<int> > res;
vector<int> now;
bool edge_used[200005];
bool can[200005];
int red = -1, red0, red1, cnt, top_cnt = 0;
void init() {
  for (int i = 0; i < ((int)200005); i++) edge_used[i] = false;
  for (int i = 0; i < ((int)200005); i++) can[i] = true;
}
void recur(int pos, int parent = -1) {
  can[pos] = false;
  for (int i = 0; i < ((int)((int)E[pos].size())); i++)
    if (E[pos][i].second != parent) {
      cnt++;
      if (can[E[pos][i].first]) {
        recur(E[pos][i].first, E[pos][i].second);
      } else {
        red = E[pos][i].second;
        red0 = pos;
        red1 = E[pos][i].first;
      }
    }
}
void dfs(int pos, int parent = -1) {
  can[pos] = false;
  now.push_back(pos);
  for (int i = 0; i < ((int)((int)E[pos].size())); i++)
    if (E[pos][i].second != parent) {
      if (can[E[pos][i].first]) {
        dfs(E[pos][i].first, E[pos][i].second);
        now.push_back(pos);
      }
    }
  for (int i = 0; i < ((int)((int)E[pos].size())); i++)
    if (E[pos][i].second != parent && top_cnt != ((int)top.size())) {
      if (edge_used[E[pos][i].second]) continue;
      edge_used[E[pos][i].second] = true;
      res.push_back(now);
      now.clear();
      now.push_back(E[pos][i].second);
      now.push_back(pos);
      now.push_back(top[top_cnt].second);
      res.push_back(now);
      now.clear();
      dfs(top[top_cnt++].second);
      now.push_back(pos);
    }
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < ((int)m); i++) {
    int t0, t1;
    cin >> t0 >> t1;
    E[t0 - 1].push_back(make_pair(t1 - 1, i));
    E[t1 - 1].push_back(make_pair(t0 - 1, i));
  }
  if (n == 1 || m == 0) {
    if (n == 1)
      cout << "YES" << endl << "0" << endl << "1 1" << endl;
    else
      cout << "NO" << endl;
    return 0;
  }
  init();
  recur(0);
  for (int i = 0; i < ((int)n); i++)
    if (can[i]) {
      cnt = 0;
      recur(i);
      top.push_back(make_pair(cnt, i));
    }
  sort(top.begin(), top.end());
  reverse(top.begin(), top.end());
  if (((int)E[0].size()) == 0) {
    if (red == -1) {
      int maxi = 0;
      for (int i = 0; i < ((int)n); i++)
        if (((int)E[maxi].size()) < ((int)E[i].size())) maxi = i;
      red = E[maxi][((int)E[maxi].size()) - 1].second;
      red0 = maxi;
      red1 = E[maxi][((int)E[maxi].size()) - 1].first;
    }
    E[red0].erase(find(E[red0].begin(), E[red0].end(), make_pair(red1, red)));
    E[red1].erase(find(E[red1].begin(), E[red1].end(), make_pair(red0, red)));
    E[0].push_back(make_pair(red0, red));
    E[red0].push_back(make_pair(0, red));
    now.push_back(0);
    res.push_back(now);
    now.clear();
    now.push_back(red);
    now.push_back(0);
    now.push_back(red0);
    res.push_back(now);
    now.clear();
    int tmp0 = red0, tmp = red;
    init();
    top.clear();
    recur(0);
    for (int i = 0; i < ((int)n); i++)
      if (can[i]) {
        cnt = 0;
        recur(i);
        top.push_back(make_pair(cnt, i));
      }
    sort(top.begin(), top.end());
    reverse(top.begin(), top.end());
    init();
    can[0] = false;
    edge_used[tmp] = true;
    dfs(0);
    res.push_back(now);
    res[2].erase(res[2].begin());
  } else {
    init();
    dfs(0);
    res.push_back(now);
  }
  for (int i = 0; i < ((int)n); i++)
    if (can[i]) {
      cout << "NO" << endl;
      return 0;
    }
  cout << "YES" << endl;
  cout << ((int)res.size()) / 2 << endl;
  for (int i = 0; i < ((int)((int)res.size())); i++) {
    if (i % 2 == 0) cout << ((int)res[i].size()) << " ";
    for (int j = 0; j < ((int)((int)res[i].size())); j++)
      cout << res[i][j] + 1 << " ";
    cout << endl;
  }
}
