#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> G[500009];
bool vis[500009];
int type[500009];
struct node {
  int x, y, z;
  node(int _x = 0, int _y = 0, int _z = 0) {
    x = _x;
    y = _y;
    z = _z;
  }
};
vector<node> ans;
bool in[500009];
void dfs(int u, int fa) {
  vector<int> cur;
  in[u] = 1;
  vis[u] = 1;
  for (auto v : G[u]) {
    if (v == fa) continue;
    if (!vis[v]) {
      dfs(v, u);
      if (type[v] != 0) {
        ans.push_back(node(type[v], v, u));
      } else {
        cur.push_back(v);
      }
    } else if (in[v]) {
      cur.push_back(v);
    }
  }
  int sz = cur.size();
  int from = 0;
  if (sz % 2 == 1) {
    type[u] = cur[0];
    from = 1;
  }
  for (int i = from; i < sz; i += 2) {
    ans.push_back(node(cur[i], u, cur[i + 1]));
  }
  in[u] = 0;
}
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    G[x].push_back(y);
    G[y].push_back(x);
  }
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) {
      dfs(i, -1);
    }
  }
  cout << ans.size() << endl;
  for (int i = 0; i < (int)ans.size(); i++) {
    printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].z);
  }
  return 0;
}
