#include <bits/stdc++.h>
using namespace std;
inline int Read() {
  char c = getchar();
  while (c < '0' || c > '9') c = getchar();
  int x = c - '0';
  c = getchar();
  while (c <= '9' && c >= '0') x = x * 10 + c - '0', c = getchar();
  return x;
}
const int N = 200010;
int fa[N], n, m;
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
vector<int> G[N], adj[N];
void DFS(int o, int f) {
  int sz = int(G[o].size()) - 1;
  for (int i = 0; i <= sz; i++) {
    int v = G[o][i];
    if (v == f) continue;
    DFS(v, o);
    if (adj[v].size() & 1)
      adj[v].push_back(o);
    else
      adj[o].push_back(v);
  }
}
int main() {
  n = Read(), m = Read();
  for (int i = 1; i <= n; i++) fa[i] = i;
  for (int i = 1; i <= m; i++) {
    int u = Read(), v = Read();
    if (find(u) ^ find(v)) {
      fa[find(u)] = find(v);
      G[u].push_back(v), G[v].push_back(u);
    } else
      adj[u].push_back(v);
  }
  for (int i = 1; i <= n; i++)
    if (find(i) == i) {
      DFS(i, 0);
      m -= adj[i].size() & 1;
    }
  printf("%d\n", m >> 1);
  for (int i = 1; i <= n; i++) {
    int sz = int(adj[i].size() / 2) - 1;
    for (int j = 0; j <= sz; j++)
      printf("%d %d %d\n", adj[i][j << 1], i, adj[i][j << 1 | 1]);
  }
  return 0;
}
