#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200000 + 9;
int n, m;
struct E {
  int next, to;
} edge[MAXN << 1];
int head[MAXN], edge_num = 1;
int ANS;
int ans[MAXN][5];
bool vis[MAXN];
bool pd[MAXN << 1];
int depth[MAXN];
int fa[MAXN];
void addedge(int x, int y) {
  edge[++edge_num].next = head[x];
  edge[edge_num].to = y;
  head[x] = edge_num;
}
void DFS(int x, int mdf) {
  vis[x] = 1;
  depth[x] = depth[fa[x]] + 1;
  int i;
  for (i = head[x]; i; i = edge[i].next) {
    if (!vis[edge[i].to]) {
      fa[edge[i].to] = x;
      DFS(edge[i].to, i);
    }
  }
  int cnt = 0;
  for (i = head[x]; i; i = edge[i].next) {
    if (depth[edge[i].to] <= depth[x] || pd[i]) continue;
    if (cnt & 1) {
      ans[ANS][2] = edge[i].to;
      pd[i] = pd[i ^ 1] = 1;
      cnt++;
    } else {
      ans[++ANS][1] = x;
      ans[ANS][0] = edge[i].to;
      pd[i] = pd[i ^ 1] = 1;
      cnt++;
    }
  }
  if (cnt & 1) {
    ans[ANS][2] = fa[x];
    if (fa[x] == 0) ANS--;
    pd[mdf] = pd[mdf ^ 1] = 1;
  }
}
void solve() {
  int i;
  for (i = 1; i <= n; i++) {
    if (!vis[i]) DFS(i, 0);
  }
  printf("%d\n", ANS);
  for (i = 1; i <= ANS; i++) {
    printf("%d %d %d\n", ans[i][0], ans[i][1], ans[i][2]);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  int i;
  for (i = 1; i <= m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    addedge(a, b);
    addedge(b, a);
  }
  solve();
  return 0;
}
