#include <bits/stdc++.h>
using namespace std;
const int maxn = 222222, inf = ~0U >> 1;
vector<int> e[maxn], ans[maxn], ord;
int A[maxn], other[maxn], n, m, d[maxn], choose[maxn], fa[maxn], fa_edge[maxn];
bool vis[maxn];
void fail() {
  puts("No solution");
  exit(0);
}
int main() {
  scanf("%d%d", &n, &m);
  if (m & 1) fail();
  for (int i = 1; i <= m; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    if (x > y) swap(x, y);
    e[x].push_back(2 * i), other[2 * i] = y;
    e[y].push_back(2 * i + 1), other[2 * i + 1] = x;
  }
  queue<int> q;
  q.push(1);
  vis[1] = true;
  while (q.size()) {
    int x = q.front();
    q.pop();
    ord.push_back(x);
    for (__typeof(e[x].begin()) it = e[x].begin(); it != e[x].end(); it++) {
      int y = other[*it], z = *it / 2;
      if (choose[z]) continue;
      d[x]++, choose[z] = 1 + (*it & 1);
      if (!vis[y]) {
        vis[y] = true;
        q.push(y);
        fa[y] = x;
        fa_edge[y] = z;
      }
    }
  }
  for (int k = n - 1; k >= 0; --k) {
    int i = ord[k];
    if (d[i] & 1) {
      d[i]--;
      d[fa[i]]++;
      choose[fa_edge[i]] = 3 - choose[fa_edge[i]];
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (__typeof(e[i].begin()) it = e[i].begin(); it != e[i].end(); it++)
      if (1 + (*it & 1) == choose[*it / 2]) ans[i].push_back(other[*it]);
    for (int j = 0, end = ans[i].size() / 2; j < end; ++j)
      printf("%d %d %d\n", ans[i][j], i, ans[i][j + end]);
  }
}
