#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e5 + 5;
const int maxm = 4e5 + 5;
bool mark[maxn];
int n, m, ans, num, kp, anst[maxn], fa[maxn], tub[maxn];
int cnt = 1, head[maxn], judge[maxm << 1];
struct node {
  int to, next, w;
} line[maxm << 1];
inline void add(int x, int y, int z) {
  line[cnt].w = z, line[cnt].to = y, line[cnt].next = head[x], head[x] = cnt++;
}
void dfs(int x) {
  mark[x] = 1;
  for (register int i = head[x]; i; i = line[i].next) {
    int v = line[i].to;
    if (!mark[v]) fa[v] = i, dfs(v);
  }
  int rem = 0;
  for (register int i = head[x]; i; i = line[i].next) {
    int v = line[i].to;
    if (i == fa[x] + line[fa[x]].w) continue;
    if (!judge[i]) {
      if (rem) {
        ++ans,
            judge[i] = judge[i + line[i].w] = judge[rem] =
                judge[rem + line[rem].w] = 1,
            anst[++num] = line[i].to, anst[++num] = x,
            anst[++num] = line[rem].to;
        rem = 0;
      } else
        rem = i;
    }
  }
  if (rem && fa[x]) {
    ++ans;
    judge[rem] = judge[rem + line[rem].w] = 1,
    judge[fa[x]] = judge[fa[x] + line[fa[x]].w] = 1;
    anst[++num] = line[rem].to, anst[++num] = x,
    anst[++num] = line[fa[x] + line[fa[x]].w].to;
  }
}
inline int read() {
  int t = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') ch = getchar();
  while (ch >= '0' && ch <= '9')
    t = (t << 3) + (t << 1) + (ch ^ 48), ch = getchar();
  return t;
}
int main() {
  int x, y;
  n = read(), m = read();
  for (register int i = 1; i <= m; ++i)
    x = read(), y = read(), add(x, y, 1), add(y, x, -1);
  for (register int i = 1; i <= n; ++i)
    if (!mark[i]) dfs(i);
  printf("%d\n", ans);
  for (register int i = 1; i <= num; i += 3) {
    printf("%d %d %d\n", anst[i], anst[i + 1], anst[i + 2]);
  }
}
