#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int n, m, cnt, head[maxn], vis[maxn], mark[maxn], ans[maxn], tot;
struct edge {
  int to, next;
} e[maxn];
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + (ch ^ 48);
    ch = getchar();
  }
  return x * f;
}
void add(int from, int to) {
  e[++cnt] = (edge){to, head[from]};
  head[from] = cnt;
}
void dfs(int now, int father, int edge) {
  vis[now] = 1;
  vector<int> bian;
  for (int i = head[now]; i; i = e[i].next) {
    int to = e[i].to;
    if (!vis[to]) dfs(to, now, i);
  }
  for (int i = head[now]; i; i = e[i].next) {
    int to = e[i].to;
    if (to != father && !mark[i]) {
      bian.push_back(i);
      mark[i] = 1;
      if (i & 1)
        mark[i + 1] = 1;
      else
        mark[i - 1] = 1;
    }
  }
  int size = bian.size();
  for (int i = 0; i < size; i++) {
    if (i & 1) ans[++tot] = now;
    ans[++tot] = e[bian[i]].to;
  }
  if (size & 1) {
    if (father)
      ans[++tot] = now, ans[++tot] = father, mark[edge] = 1;
    else
      tot--;
  }
}
int main() {
  n = read(), m = read();
  for (int i = 1; i <= m; i++) {
    int u = read(), v = read();
    add(u, v), add(v, u);
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs(i, 0, 0);
  printf("%d\n", tot / 3);
  for (int i = 1; i <= tot; i++) {
    printf("%d ", ans[i]);
    if (i % 3 == 0) puts("");
  }
  return 0;
}
