#include <bits/stdc++.h>
using namespace std;
long long read() {
  char ch = getchar();
  long long f = 1, x = 0;
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return f * x;
}
const long long maxn = 1e5 + 10;
long long n, h[maxn], cnt, m;
struct edge {
  long long v, next;
} e[maxn << 1];
void addedge(long long u, long long v) {
  e[++cnt].v = v;
  e[cnt].next = h[u];
  h[u] = cnt;
}
void insert(long long u, long long v) {
  addedge(u, v);
  addedge(v, u);
}
stack<long long> g[maxn];
struct answers {
  long long a, b, c;
} ans[maxn];
long long vis[maxn], tot;
bool no;
void dfs(long long u, long long fa) {
  vis[u] = 1;
  for (long long i = h[u]; i; i = e[i].next) {
    long long v = e[i].v;
    if (!vis[v])
      dfs(v, u);
    else if (v != fa) {
      g[v].push(u);
    }
  }
  while (g[u].size() >= 2) {
    ans[++tot].a = g[u].top();
    ans[tot].b = u;
    g[u].pop();
    ans[tot].c = g[u].top();
    g[u].pop();
  }
  if (g[u].size() == 1) {
    if (fa == 0) {
      no = 1;
      return;
    }
    long long x = g[u].top();
    ans[++tot].a = x;
    ans[tot].b = u;
    ans[tot].c = fa;
    g[u].pop();
  } else {
    g[fa].push(u);
  }
}
signed main() {
  n = read();
  m = read();
  if (m & 1) {
    cout << "No solution\n";
    return 0;
  }
  for (long long i = 1; i <= m; i++) {
    insert(read(), read());
  }
  dfs(1, 0);
  if (no) {
    cout << "No solution\n";
    return 0;
  }
  for (long long i = 1; i <= tot; i++) {
    cout << ans[i].a << " " << ans[i].b << " " << ans[i].c << endl;
  }
  return 0;
}
