#include <bits/stdc++.h>
using namespace std;
const int MaxN = 1111111;
int v[MaxN], Next[MaxN], h[MaxN], tot;
void add_edge(int b, int e) {
  v[++tot] = e;
  Next[tot] = h[b];
  h[b] = tot;
  v[++tot] = b;
  Next[tot] = h[e];
  h[e] = tot;
}
vector<tuple<int, int, int> > ans;
int vis[MaxN], Left[MaxN];
int id = 0;
void dfs(int x, int fa) {
  vis[x] = ++id;
  vector<int> vec;
  for (int z = h[x]; z; z = Next[z])
    if (v[z] != fa) {
      if (!vis[v[z]]) {
        dfs(v[z], x);
        if (Left[v[z]]) {
          ans.emplace_back(x, v[z], Left[v[z]]);
        } else
          vec.push_back(v[z]);
      } else if (vis[v[z]] > vis[x])
        vec.push_back(v[z]);
    }
  for (int i = 0; i < vec.size(); i += 2) {
    if (i + 1 == vec.size()) {
      Left[x] = vec[i];
      return;
    }
    ans.emplace_back(vec[i], x, vec[i + 1]);
  }
}
int n, m;
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int b, e;
    scanf("%d%d", &b, &e);
    add_edge(b, e);
  }
  memset(vis, 0, sizeof vis);
  for (int i = 1; i <= n; ++i)
    if (!vis[i]) {
      dfs(i, 0);
      if (Left[i]) {
        puts("No solution");
        return 0;
      }
    }
  for (auto x : ans) printf("%d %d %d\n", get<0>(x), get<1>(x), get<2>(x));
  return 0;
}
