#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T& s) {
  s = 0;
  int f = 0;
  char c = getchar();
  while (!isdigit(c)) f |= (c == '-'), c = getchar();
  while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
  s = f ? -s : s;
}
const int _ = 200010;
const int __ = 400010;
int tot = 1, head[_], nxt[__], ver[__];
inline void Add_edge(int u, int v) {
  nxt[++tot] = head[u], head[u] = tot, ver[tot] = v;
}
int n, m, vis[_] = {1}, f[_];
int cnt;
struct node {
  int x, y, z;
} t[_];
inline void dfs(int u) {
  vis[u] = 1;
  for (register int v, i = head[u]; i; i = nxt[i]) {
    v = ver[i], ver[i] = ver[i ^ 1] = 0;
    if (v != 0) {
      if (!vis[v]) dfs(v);
      if (f[v])
        t[++cnt] = (node){u, v, f[v]}, f[v] = 0;
      else if (f[u])
        t[++cnt] = (node){f[u], u, v}, f[u] = 0;
      else
        f[u] = v;
    }
  }
}
int main() {
  read(n), read(m);
  for (register int u, v, i = 1; i <= m; ++i)
    read(u), read(v), Add_edge(u, v), Add_edge(v, u);
  for (register int i = 1; i <= n; ++i)
    if (!vis[i]) dfs(i);
  printf("%d\n", cnt);
  for (register int i = 1; i <= cnt; ++i)
    printf("%d %d %d\n", t[i].x, t[i].y, t[i].z);
  return 0;
}
