#include <bits/stdc++.h>
using namespace std;
const int N = 400005;
const int inf = 1e9 + 7;
int tx[N], ty[N], v[N], vis[N], tot, dfn[N];
int head[N], nxt[N], to[N], e, cnt, id[N];
inline void init() {
  memset(head, -1, sizeof(head));
  e = 0;
}
inline void add_edge(int x, int y, int z) {
  to[e] = y;
  nxt[e] = head[x];
  id[e] = z;
  head[x] = e++;
}
vector<pair<int, int> > xjt;
int dfs(int x, int f) {
  vector<int> cur;
  cur.clear();
  dfn[x] = ++tot;
  vis[x] = 1;
  for (int i = head[x]; i + 1; i = nxt[i])
    if (to[i] != f) {
      int j = to[i];
      if (!vis[j]) {
        int t = dfs(j, x);
        if (t != -1) {
          xjt.push_back(make_pair(id[i], t));
          v[id[i]] = 1;
          v[t] = 1;
        } else
          cur.push_back(id[i]);
        continue;
      }
      if (dfn[j] > dfn[x]) cur.push_back(id[i]);
    }
  for (int i = 0; i + 1 < cur.size(); i += 2) {
    xjt.push_back(make_pair(cur[i], cur[i + 1]));
    v[cur[i]] = 1;
    v[cur[i + 1]] = 1;
  }
  if (cur.size() & 1)
    return cur[cur.size() - 1];
  else
    return -1;
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  init();
  for (int i = (1); i <= (m); i++) {
    scanf("%d%d", &tx[i], &ty[i]);
    add_edge(tx[i], ty[i], i);
    add_edge(ty[i], tx[i], i);
  }
  for (int i = (1); i <= (n); i++)
    if (!vis[i]) dfs(i, 0);
  printf("%d\n", xjt.size());
  if (!xjt.size()) return 0;
  for (int p = (0); p <= (xjt.size() - 1); p++) {
    int x = xjt[p].first, y = xjt[p].second;
    if (tx[x] == tx[y])
      printf("%d %d %d\n", ty[x], tx[x], ty[y]);
    else if (tx[x] == ty[y])
      printf("%d %d %d\n", ty[x], tx[x], tx[y]);
    else if (ty[x] == tx[y])
      printf("%d %d %d\n", tx[x], ty[x], ty[y]);
    else
      printf("%d %d %d\n", tx[x], ty[x], tx[y]);
  }
  return 0;
}
