#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
template <class T, class U>
inline void Max(T &a, U b) {
  if (a < b) a = b;
}
template <class T, class U>
inline void Min(T &a, U b) {
  if (a > b) a = b;
}
inline void add(int &a, int b) {
  a += b;
  while (a >= 1000000007) a -= 1000000007;
}
int pow(int a, int b) {
  int ans = 1;
  while (b) {
    if (b & 1) ans = ans * (long long)a % 1000000007;
    a = (long long)a * a % 1000000007;
    b >>= 1;
  }
  return ans;
}
vector<int> g[200010], e[200010];
struct node {
  int first, second, z;
};
vector<node> ans;
int vis[200010], d[200010];
int dfs(int u, int fa = -1) {
  vis[u] = 1;
  for (auto v : g[u]) {
    if (v == fa) continue;
    if (vis[v]) {
      if (d[v] > d[u]) continue;
      e[u].push_back(v);
    } else {
      d[v] = d[u] + 1;
      if (dfs(v, u) == 0) {
        e[u].push_back(v);
      } else
        ans.push_back({e[v].back(), v, u});
    }
  }
  for (int i = 0; i < (int)(e[u].size()) - 1; i++) {
    ans.push_back({e[u][i], u, e[u][i + 1]});
    i++;
  }
  return (int)(e[u].size()) & 1;
}
int main() {
  int j, k, i, T, ca = 0, K = 0, n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &j, &k), j--, k--;
    g[j].push_back(k);
    g[k].push_back(j);
  }
  for (int i = 0; i < n; i++)
    if (!vis[i]) {
      dfs(i);
    }
  printf("%d\n", (int)(ans.size()));
  for (auto &o : ans) printf("%d %d %d\n", o.first + 1, o.second + 1, o.z + 1);
  return 0;
}
