#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-9;
const int INF = (int)1e9 + 7;
const long long linf = (long long)1e16 + 7;
const long long MOD = (long long)1e16 + 7;
const int MAXN = (int)1e6;
vector<set<int>> g;
vector<int> used;
struct triple {
  int f, s, t;
};
vector<triple> res;
void dfs(int v, int pr) {
  used[v] = 1;
  vector<int> nxt, per;
  for (const auto &to : g[v]) {
    nxt.push_back(to);
  }
  for (const auto &to : nxt) {
    if (!used[to]) {
      dfs(to, v);
      if (g[v].count(to)) per.push_back(to);
    } else if (g[v].count(to) && to != pr)
      per.push_back(to);
  }
  for (int i = 0; i < per.size(); i += 2) {
    if (i + 1 < per.size()) {
      res.push_back({per[i], v, per[i + 1]});
      g[per[i]].erase(v);
      g[per[i + 1]].erase(v);
    }
  }
  if (pr != -1 && per.size() % 2 == 1) {
    res.push_back({per[per.size() - 1], v, pr});
    g[pr].erase(v);
    g[per[per.size() - 1]].erase(v);
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  g.resize(n), used.resize(n);
  for (int i = 0; i < m; ++i) {
    int f, s;
    cin >> f >> s;
    f--, s--;
    g[f].insert(s);
    g[s].insert(f);
  }
  for (int i = 0; i < n; ++i)
    if (!used[i]) {
      dfs(i, -1);
    }
  cout << res.size() << '\n';
  for (const auto &it : res) {
    cout << it.f + 1 << " " << it.s + 1 << " " << it.t + 1 << '\n';
  }
  return 0;
}
