#include <bits/stdc++.h>
using namespace std;
int n, m, a, b;
map<pair<int, int>, bool> mapa;
vector<int> e[201000];
vector<string> sol;
bool bio[201000], solved[201000];
void dfs(int cv) {
  bio[cv] = true;
  for (int i = 0; i < e[cv].size(); ++i) {
    if (!bio[e[cv][i]]) {
      dfs(e[cv][i]);
    }
  }
  vector<int> free_edges;
  for (int i = 0; i < e[cv].size(); ++i) {
    if (solved[e[cv][i]] && !mapa[{min(cv, e[cv][i]), max(cv, e[cv][i])}]) {
      free_edges.push_back(e[cv][i]);
    }
  }
  for (int i = 0; i < e[cv].size(); ++i) {
    if (!solved[e[cv][i]] && !mapa[{min(cv, e[cv][i]), max(cv, e[cv][i])}]) {
      free_edges.push_back(e[cv][i]);
    }
  }
  solved[cv] = true;
  for (int i = 0; i < free_edges.size(); i += 2) {
    if (i + 1 == free_edges.size()) break;
    sol.push_back(to_string(free_edges[i] + 1) + " " + to_string(cv + 1) + " " +
                  to_string(free_edges[i + 1] + 1));
    mapa[{min(free_edges[i], cv), max(free_edges[i], cv)}] = true;
    mapa[{min(free_edges[i + 1], cv), max(free_edges[i + 1], cv)}] = true;
  }
}
int main(void) {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; ++i) {
    scanf("%d%d", &a, &b);
    a--;
    b--;
    e[a].push_back(b);
    e[b].push_back(a);
    mapa.insert({{a, b}, false});
  }
  for (int i = 0; i < n; ++i) {
    if (!bio[i]) dfs(i);
  }
  printf("%d\n", sol.size());
  for (int i = 0; i < sol.size(); ++i) {
    cout << sol[i] << endl;
  }
  return 0;
}
