#include <iostream>
#include <cassert>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
vector<int> G[100005];
vector<vector<int> > R;
int N,M;
int id[100005],lastid;
int low[100005];
stack<pair<int,int> > st;
vector<int> tmp;
void dfs(int nod,int tata){
low[nod] = id[nod] = ++lastid;
for(auto it:G[nod]){
if(it == tata){
continue;
}
if(!id[it]){
st.push( {nod,it} );
dfs(it,nod);
if(low[it] >= id[nod]){
tmp.clear();
while(!st.empty() && (st.top().first != nod || st.top().second != it)){
tmp.push_back(st.top().first);
tmp.push_back(st.top().second);
st.pop();
}
tmp.push_back(st.top().first);
tmp.push_back(st.top().second);
st.pop();
sort(tmp.begin(),tmp.end());
tmp.resize(unique(tmp.begin(),tmp.end()) - tmp.begin());
R.push_back(tmp);
}
}
if(low[it] < low[nod]){
low[nod] = low[it];
}
}
}
int main(){
freopen("biconex.in","r",stdin);cin.sync_with_stdio(false);cin.tie(0);
freopen("biconex.out","w",stdout);cout.sync_with_stdio(false);cout.tie(0);
cin >> N >> M;
while(M--){
int x,y;
cin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
dfs(1,0);
cout << R.size() << "\n";
for(auto it:R){
for(auto it2:it){
cout << it2 << " ";
}
cout << "\n";
}
return 0;
}