#include <bits/stdc++.h>
using namespace std;
const int N = 400005;
struct node {
  int to, next, pre;
} q[N];
struct data {
  int x, y, z;
} ans[N];
int tot = 0, dfn[N], tag[N], num;
int h[N], cnt = 1;
int n, m, du[N], dep[N], vst[N], prt[N], edg[N];
void qxx(int x, int y) {
  cnt++;
  q[cnt].to = y;
  q[cnt].next = h[x];
  q[h[x]].pre = cnt;
  h[x] = cnt;
}
void dfs(int x) {
  int i, y;
  vst[x] = 1;
  for (i = h[x]; i; i = q[i].next) {
    y = q[i].to;
    if (!vst[y]) {
      prt[y] = x;
      dep[y] = dep[x] + 1;
      edg[y] = i;
      dfs(y);
    }
  }
}
void Del(int x, int k) {
  q[q[k].next].pre = q[k].pre;
  q[q[k].pre].next = q[k].next;
  if (k == h[x]) h[x] = q[k].next;
}
void dp(int x) {
  int i, y;
  for (i = h[x]; i; i = q[i].next) {
    y = q[i].to;
    if (prt[y] == x) dp(y);
  }
  num = 0;
  if (prt[x]) {
    num++;
    dfn[num] = prt[x];
    tag[num] = edg[x] ^ 1;
  }
  for (i = h[x]; i; i = q[i].next) {
    y = q[i].to;
    if (y == prt[x]) continue;
    num++;
    dfn[num] = y;
    tag[num] = i;
  }
  while (num >= 2) {
    tot++;
    ans[tot].x = dfn[num];
    ans[tot].y = x;
    ans[tot].z = dfn[num - 1];
    Del(x, tag[num]);
    Del(dfn[num], tag[num] ^ 1);
    num--;
    Del(x, tag[num]);
    Del(dfn[num], tag[num] ^ 1);
    num--;
  }
}
void solve(int rt) {
  dep[rt] = 1;
  edg[rt] = 0;
  dfs(rt);
  dp(rt);
}
int main() {
  scanf("%d%d", &n, &m);
  int i, j, x, y;
  for (i = 1; i <= m; i++) {
    scanf("%d%d", &x, &y);
    qxx(x, y);
    qxx(y, x);
    du[x]++;
    du[y]++;
  }
  for (i = 1; i <= n; i++)
    if (!vst[i]) solve(i);
  printf("%d\n", tot);
  for (i = 1; i <= tot; i++) printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].z);
  return 0;
}
