#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 500010;
int n, m, tin[N], timer, sz[N];
vector<int> g[N], t[N], rev[N];
bool used[N];
void dfs1(int v, int parent) {
  used[v] = true;
  sz[v] = 0;
  timer++;
  tin[v] = timer;
  for (int i = 0; i < g[v].size(); i++)
    if (!used[g[v][i]]) {
      t[v].push_back(g[v][i]);
      dfs1(g[v][i], v);
      sz[v] += sz[g[v][i]] + 1;
    } else {
      if ((g[v][i] != parent) && (tin[g[v][i]] < tin[v]))
        rev[g[v][i]].push_back(v);
    }
  sz[v] += rev[v].size();
}
void dfs2(int v, int u) {
  if (u != -1) rev[v].push_back(u);
  for (int i = 0; i < rev[v].size() / 2; i++)
    printf("%d %d %d\n", rev[v][2 * i], v, rev[v][2 * i + 1]);
  int p = -1;
  if (rev[v].size() % 2 != 0) {
    for (int i = 0; i < t[v].size(); i++)
      if (sz[t[v][i]] % 2 == 0) {
        p = t[v][i];
        printf("%d %d %d\n", rev[v][rev[v].size() - 1], v, p);
        break;
      }
  }
  int cur = -1;
  for (int i = 0; i < t[v].size(); i++) {
    if (t[v][i] != p) {
      if (sz[t[v][i]] % 2 != 0)
        dfs2(t[v][i], v);
      else {
        if (cur == -1) {
          cur = t[v][i];
          dfs2(t[v][i], -1);
        } else {
          printf("%d %d %d\n", cur, v, t[v][i]);
          cur = -1;
          dfs2(t[v][i], -1);
        }
      }
    } else
      dfs2(t[v][i], -1);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    g[a].push_back(b);
    g[b].push_back(a);
  }
  if (m % 2 != 0) {
    cout << "No solution";
    return 0;
  }
  memset(used, false, sizeof(used));
  timer = 0;
  dfs1(1, -1);
  dfs2(1, -1);
  return 0;
}
