#include <bits/stdc++.h>   #pragma GCC optimize( O3 )   using namespace std;   const int N = 200031;   int n, m, a[N], b[N];   vector<int> g[N];   int used[N];   int dep[N];   vector<int> this_comp;   vector<pair<int, int> > order;   vector<pair<int, pair<int, int> > > solution;   int par[N];   int in_st[N];   int used_edge[N];   int par_edge[N];   set<int> sons[N];   vector<int> with_dep[N];   vector<int> not_st_list[N];   set<int>::iterator it;   void trace(int v) {     used[v] = 1;     this_comp.push_back(v);     for (int i = 0; i < g[v].size(); i++) {       int id = g[v][i];       int to = a[id] + b[id] - v;       if (used[to]) continue;       par[to] = v;       sons[v].insert(to);       par_edge[to] = id;       dep[to] = dep[v] + 1;       in_st[id] = 1;       trace(to);     }   }   void process_vertex(int v) {     vector<int> free_edges;     for (int i = 0; i < g[v].size(); i++) {       int id = g[v][i];       if (used_edge[id]) continue;       if (in_st[id]) continue;       free_edges.push_back(id);     }     while (free_edges.size() > 1) {       int a = free_edges.back();       free_edges.pop_back();       int b = free_edges.back();       free_edges.pop_back();       used_edge[a] = 1;       used_edge[b] = 1;       solution.push_back(make_pair(v, make_pair(a, b)));     }     if (free_edges.size() == 1) {       if (par[v] == 0) {         int id = free_edges[0];         used_edge[id] = 1;         return;       }       solution.push_back(make_pair(v, make_pair(par_edge[v], free_edges[0])));       used_edge[par_edge[v]] = 1;       used_edge[free_edges[0]] = 1;       sons[par[v]].erase(v);       return;     }   }   int get_out_of_st(int v) {     while (not_st_list[v].size() > 0) {       int id = not_st_list[v].back();       if (used_edge[id] == 0) return id;       not_st_list[v].pop_back();     }     return -1;   }   void resolve(int v) {     if (par[v] == 0) return;     if (used_edge[par_edge[v]]) return;     if (sons[par[v]].size() > 1) {       sons[par[v]].erase(v);       it = sons[par[v]].begin();       int othr = (*it);       sons[par[v]].erase(othr);       used_edge[par_edge[othr]] = 1;       used_edge[par_edge[v]] = 1;       solution.push_back(           make_pair(par[v], make_pair(par_edge[othr], par_edge[v])));       return;     }     int edge_in_father = get_out_of_st(par[v]);     if (edge_in_father != -1) {       sons[par[v]].erase(v);       solution.push_back(           make_pair(par[v], make_pair(par_edge[v], edge_in_father)));       used_edge[par_edge[v]] = 1;       used_edge[edge_in_father] = 1;       return;     }     if (dep[v] == 1) return;     int v2 = par[par[v]];     sons[par[v]].erase(v);     sons[v2].erase(par[v]);     solution.push_back(         make_pair(par[v], make_pair(par_edge[v], par_edge[par[v]])));     used_edge[par_edge[v]] = 1;     used_edge[par_edge[par[v]]] = 1;   }   void solve(int v) {     this_comp.clear();     trace(v);     int max_dep = 0;     for (int i = 0; i < this_comp.size(); i++) {       max_dep = max(max_dep, dep[this_comp[i]]);     }     order.clear();     for (int i = 0; i < this_comp.size(); i++) {       int cur_v = this_comp[i];       for (int j = 0; j < g[cur_v].size(); j++) {         int e_id = g[cur_v][j];         if (in_st[e_id]) continue;         not_st_list[cur_v].push_back(e_id);       }       order.push_back(make_pair(dep[cur_v], cur_v));       with_dep[dep[cur_v]].push_back(cur_v);     }     for (int i = max_dep; i >= 0; --i) {       for (int j = 0; j < with_dep[i].size(); j++) {         int v_id = with_dep[i][j];         process_vertex(v_id);       }       for (int j = 0; j < with_dep[i].size(); j++) {         int v_id = with_dep[i][j];         resolve(v_id);       }       with_dep[i].clear();     }   }   int get_other(int id, int v) { return a[id] + b[id] - v; }   int main() {     ios_base::sync_with_stdio(0);     cin.tie(0);     cin >> n;     cin >> m;     for (int i = 1; i <= m; i++) {       cin >> a[i] >> b[i];       g[a[i]].push_back(i);       g[b[i]].push_back(i);     }     for (int i = 1; i <= n; i++) {       if (used[i]) continue;       solve(i);     }     cout << solution.size() << endl;     for (int i = 0; i < solution.size(); i++) {       int id1 = solution[i].second.first;       int id2 = solution[i].second.second;       cout << get_other(id1, solution[i].first) <<     << solution[i].first <<                << get_other(id2, solution[i].first) <<   n ;     }     cin.get();     cin.get();     return 0;   }