#include <bits/stdc++.h>
using namespace std;
const int maxn = 200003;
struct edge {
  int to, next;
} e[maxn << 1];
int head[maxn], cnte;
void add(int u, int v) { e[++cnte] = (edge){v, head[u]}, head[u] = cnte; }
int n, m, dep[maxn], up[maxn], ANS[maxn][3], CNT;
bool vis[maxn];
void dfs(int u, int last) {
  vis[u] = 1;
  dep[u] = dep[last] + 1;
  vector<int> vec;
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == last) continue;
    if (vis[v]) {
      if (dep[v] > dep[u]) vec.push_back(i);
      continue;
    }
    dfs(v, u);
    if (up[v])
      ANS[++CNT][0] = up[v], ANS[CNT][1] = v, ANS[CNT][2] = u;
    else
      vec.push_back(i);
  }
  int i;
  for (i = 1; i < int(vec.size()); i += 2) {
    ANS[++CNT][0] = e[vec[i - 1]].to, ANS[CNT][1] = u,
    ANS[CNT][2] = e[vec[i]].to;
  }
  if (--i < int(vec.size())) {
    up[u] = e[vec[i]].to;
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    add(u, v), add(v, u);
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs(i, 0);
  printf("%d\n", CNT);
  for (int i = 1; i <= CNT; i++)
    for (int j = 0; j <= 2; j++) printf("%d%c", ANS[i][j], j < 2 ? ' ' : '\n');
  return 0;
}
