#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 );         }       }     }   }