#include <bits/stdc++.h>
#pragma GCC optimize("-O3")
using namespace std;
const double PI = acos(-1);
long long gcd() { return 0ll; }
template <typename T, typename... Args>
T gcd(T a, Args... args) {
  return __gcd(a, (__typeof(a))gcd(args...));
}
vector<int> G[200010];
set<pair<int, int>> s;
vector<array<int, 3>> v;
bool vis[200010];
void dfs(int u, int p = -1) {
  vis[u] = 1;
  for (auto it : G[u]) {
    if (vis[it]) continue;
    dfs(it, u);
  }
  vector<int> t;
  for (auto it : G[u]) {
    if (it == p) continue;
    if (s.find({u, it}) == s.end()) t.emplace_back(it);
  }
  if ((t.size() & 1) && p != -1) t.emplace_back(p);
  for (int i = 0; i + 1 < t.size(); i += 2) {
    s.insert({t[i], u});
    s.insert({u, t[i]});
    s.insert({t[i + 1], u});
    s.insert({u, t[i + 1]});
    v.push_back({t[i], u, t[i + 1]});
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  {
    int n, m, x, y;
    cin >> n >> m;
    for (__typeof(m) i = (0) - ((0) > (m)); i != (m) - ((0) > (m));
         i += 1 - 2 * ((0) > (m))) {
      cin >> x >> y;
      x--;
      y--;
      G[x].emplace_back(y);
      G[y].emplace_back(x);
    }
    for (__typeof(n) i = (0) - ((0) > (n)); i != (n) - ((0) > (n));
         i += 1 - 2 * ((0) > (n)))
      if (!vis[i]) dfs(i);
    cout << v.size() << "\n";
    for (auto it : v) {
      for (auto t : it) cout << t + 1 << " ";
      cout << "\n";
    }
  }
  return 0;
}
