#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
bool Max(T1& a, T2 b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T1, typename T2>
bool Min(T1& a, T2 b) {
  return a > b ? a = b, 1 : 0;
}
const int N = 200001;
vector<int> g[N];
int vi[N], ct;
vector<array<int, 3>> ans;
bool dfs(int i, int p) {
  vi[i] = ++ct;
  vector<int> ch;
  for (auto& e : g[i])
    if (e != p) {
      if (vi[e] && vi[e] < vi[i])
        ch.push_back(e);
      else if (!vi[e] && dfs(e, i))
        ch.push_back(e);
    }
  while (ch.size() >= 2) {
    int x = ch.back();
    ch.pop_back();
    int y = ch.back();
    ch.pop_back();
    ans.push_back({x, i, y});
  }
  if (ch.size() && p) {
    ans.push_back({ch[0], i, p});
    return 0;
  }
  return 1;
}
void solve() {
  int n, m, u, v;
  cin >> n >> m;
  while (m--) {
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  for (int i = 1; i <= (n); ++i)
    if (!vi[i]) dfs(i, 0);
  cout << ans.size() << '\n';
  for (auto& e : ans) cout << e[0] << ' ' << e[1] << ' ' << e[2] << '\n';
}
void init() {}
int main(void) {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(20);
  init();
  int TC = 1;
  for (int TI = 1; TI <= (TC); ++TI) {
    solve();
  }
  return 0;
}
