#include <bits/stdc++.h>
using namespace std;
const int maxn = 200 * 1000 + 10;
int n, m, u, v, amoo[maxn][3];
bool mark[maxn], park[maxn];
vector<pair<int, int> > vec[maxn];
vector<pair<pair<int, int>, int> > ans;
void dfs(int x) {
  park[x] = 1;
  int hlp;
  for (int i = ((int(vec[x].size()))) - 1; i >= 0; i--) {
    if (!mark[vec[x][i].second]) {
      mark[vec[x][i].second] = 1;
      hlp = vec[x][i].first;
      vec[x].pop_back();
      dfs(hlp);
      amoo[x][0]++;
      amoo[x][amoo[x][0]] = hlp;
      if (amoo[amoo[x][amoo[x][0]]][0] > 0) {
        ans.push_back(
            {{x, hlp},
             amoo[amoo[x][amoo[x][0]]][amoo[amoo[x][amoo[x][0]]][0]]});
        amoo[amoo[x][amoo[x][0]]][0]--;
        amoo[x][0]--;
      }
      if (amoo[x][0] == 2) {
        ans.push_back({{amoo[x][1], x}, amoo[x][2]});
        amoo[x][0] = 0;
      }
    } else
      vec[x].pop_back();
  }
}
int main() {
  ios::sync_with_stdio(0);
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &u, &v);
    vec[u].push_back(make_pair(v, i));
    vec[v].push_back(make_pair(u, i));
  }
  for (int i = 1; i <= n; i++) {
    if (!park[i]) dfs(i);
  }
  cout << ((int(ans.size()))) << endl;
  for (int i = 0; i < ((int(ans.size()))); i++)
    cout << ans[i].first.first << " " << ans[i].first.second << " "
         << ans[i].second << endl;
  return 0;
}
