#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 69, mod = 1e9 + 7;
vector<int> gr[N], dfs_gr[N];
int n, m, answer, cont, edge, root;
int lvl[N], dp[N], con[N], non_con[N], col[N], P[N], ROOT[N];
struct bla {
  int a, b, c;
};
bla ans[N];
map<int, int> mp[N];
void dfs(int x, int p) {
  vector<pair<int, int> > childs;
  for (int i = 0; i < gr[x].size(); i++) {
    int to = gr[x][i];
    if (!lvl[to]) {
      lvl[to] = lvl[x] + 1;
      dfs(to, x);
      if (!mp[x][to]) {
        childs.push_back({0, to});
      }
      continue;
    }
    if (!mp[to][x] && lvl[to] > lvl[x]) childs.push_back({1, to});
  }
  if (p) childs.push_back({2, p});
  for (int i = 0; i + 1 < childs.size(); i += 2) {
    answer++;
    int to = childs[i].second;
    int to1 = childs[i + 1].second;
    ans[answer].a = to;
    mp[x][to] = mp[to][x] = 1;
    ans[answer].b = x;
    ans[answer].c = to1;
    mp[x][to1] = mp[to1][x] = 1;
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int x, y;
    cin >> x >> y;
    gr[x].push_back(y);
    gr[y].push_back(x);
  }
  for (int i = 1; i <= n; i++) {
    if (lvl[i]) continue;
    lvl[i] = 1;
    dfs(i, 0);
  }
  cout << answer << endl;
  for (int i = 1; i <= answer; i++) {
    cout << ans[i].a << " " << ans[i].b << " " << ans[i].c << endl;
  }
}
