#include <bits/stdc++.h>
bool visited[200010] = {0};
int first[200010], second[200010], thrid[200010], count = 0;
std::set<long long int> happened;
long long int f(int one, int two) {
  return (1LL * 1e6 * std::min(one, two) + std::max(one, two));
}
int dfs(int current, std::vector<std::vector<int> > &g, int parent = -1) {
  if (visited[current]) return current;
  visited[current] = 1;
  std::vector<int> s;
  for (int i = 0; i < g[current].size(); ++i) {
    if (g[current][i] != parent) {
      int value = dfs(g[current][i], g, current);
      if (value != -1 &&
          happened.find(f(g[current][i], current)) == happened.end()) {
        s.push_back(value);
      }
    }
  }
  int ffirst = 0, ssecond = 1;
  while (ssecond < s.size()) {
    happened.insert(f(s[ffirst], current));
    happened.insert(f(s[ssecond], current));
    first[count] = s[ffirst];
    second[count] = current;
    thrid[count] = s[ssecond];
    ++count;
    ffirst += 2;
    ssecond += 2;
  }
  if (ffirst == s.size()) return current;
  if (parent != -1) {
    first[count] = s[ffirst];
    second[count] = current;
    thrid[count] = parent;
    ++count;
    happened.insert(f(s[ffirst], current));
    happened.insert(f(current, parent));
  }
  return -1;
}
int main() {
  int n, m;
  std::cin >> n >> m;
  std::vector<std::vector<int> > g(n);
  for (int i = 0; i < m; ++i) {
    int x, y;
    std::cin >> x >> y;
    --x;
    --y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (int i = 0; i < n; ++i) {
    if (!visited[i]) {
      dfs(i, g);
    }
  }
  std::cout << count << "\n";
  for (int i = 0; i < count; ++i) {
    std::cout << first[i] + 1 << " " << second[i] + 1 << " " << thrid[i] + 1
              << "\n";
  }
}
