#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
const int maglim = 7e7 + 98;
int magic;
struct fini {
  vector<pair<pair<int, int>, int> > v;
  void clear() { v.clear(); }
  void add(pair<int, int> z, int idx) { v.push_back({z, idx}); }
  void prep() { sort(v.begin(), v.end()); }
  int find(int p) {
    int l = 0, r = v.size() - 1;
    while (l <= r) {
      int mid = (l + r) >> 1;
      int a = v[mid].first.first, b = v[mid].first.second;
      if (a <= p && p <= b) return v[mid].second;
      if (p < a)
        r = mid - 1;
      else
        l = mid + 1;
    }
  }
} S;
vector<int> G[maxn];
vector<int> ch[maxn];
vector<int> R[maxn];
vector<int> odds;
int ed[maxn];
int lft[maxn];
int rgt[maxn];
int enter[maxn];
int clk;
void dfs1(int x, int pi) {
  ch[x].clear();
  clk++;
  lft[x] = enter[x] = clk;
  ed[x] = 0;
  for (int j = 0; j < G[x].size(); j++) {
    int y = G[x][j];
    if (enter[y] <= 0) {
      ch[x].push_back(y);
      dfs1(y, x);
      ed[x] += ed[y];
    }
    if (lft[x] <= enter[y]) {
      ed[x]++;
    }
  }
  clk++;
  rgt[x] = clk;
}
void dfs(int x) {
  if (enter[x] >= maglim) return;
  if (ch[x].size() == 0) return;
  S.clear();
  for (int y : ch[x]) {
    R[y].clear();
    S.add({lft[y], rgt[y]}, y);
    R[y].push_back(y);
  }
  S.prep();
  for (int z : G[x]) {
    if (z < 0 || (lft[x] <= enter[z] && enter[z] <= rgt[x])) {
      if (z < 0) z = -z;
      int u = S.find(enter[z]);
      if (z == u) {
        ed[u]++;
        if (enter[u] >= maglim) ed[u] = 1;
        continue;
      }
      R[u].push_back(z);
      ed[u]++;
      if (enter[u] >= maglim) ed[u] = 1;
    }
  }
  odds.clear();
  for (int y : ch[x]) {
    if (ed[y] % 2 == 1) {
      odds.push_back(y);
    }
  }
  assert(odds.size() % 2 == 0);
  for (int i = 0; i < odds.size(); i += 2) {
    int a = odds[i], b = odds[i + 1];
    assert(R[a].size() > 0);
    assert(R[b].size() > 0);
    int u = R[a][R[a].size() - 1], v = R[b][R[b].size() - 1];
    R[a].resize(R[a].size() - 1);
    R[b].resize(R[b].size() - 1);
    printf("%d %d %d\n", u, x, v);
  }
  for (int y : ch[x]) {
    for (int j = R[y].size() - 1; j - 1 >= 0; j -= 2) {
      printf("%d %d %d\n", R[y][j], x, R[y][j - 1]);
    }
    if (R[y].size() % 2 == 1) {
      int z = R[y][0];
      ch[z].push_back(x);
      G[z].push_back(-x);
      ed[z]++;
    }
  }
  lft[x] = enter[x] = rgt[x] = magic;
  ed[x] = 0;
  magic++;
  for (int y : ch[x]) dfs(y);
}
int main() {
  magic = maglim;
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);
  clk = 0;
  if (m % 2 == 1) {
    printf("No solution\n");
    return 0;
  }
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d", &x);
    scanf("%d", &y);
    G[x].push_back(y);
    G[y].push_back(x);
  }
  dfs1(1, -1);
  dfs(1);
}
