#include <bits/stdc++.h>
using namespace std;
int hand = 1, la[100000 + 10], fa[100000 + 10], n, m, u[100000 + 10],
    v[100000 + 10], oug[100000 + 10], vis[100000 + 10], in[100000 + 10],
    que[100000 + 10], mk[100000 + 10];
vector<int> ins[100000 + 10];
struct edge {
  int st, en, su;
} e[2 * 100000 + 10];
void Build(int s, int t) {
  e[++hand] = (edge){s, t, la[s]};
  la[s] = hand;
}
void DFS(int k) {
  vis[k] = 1;
  for (int q = la[k]; q; q = e[q].su)
    if (!vis[e[q].en]) {
      fa[e[q].en] = q ^ 1;
      in[k]++;
      DFS(e[q].en);
    }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1, _end_ = m; i <= _end_; i++) {
    scanf("%d%d", &u[i], &v[i]);
    Build(u[i], v[i]);
    Build(v[i], u[i]);
    oug[v[i]]++;
    oug[v[i]] &= 1;
  }
  for (int i = 1, _end_ = n; i <= _end_; i++) {
    if (!vis[i]) DFS(i);
  }
  int head = 0, tail = 0;
  for (int i = 1, _end_ = n; i <= _end_; i++) {
    if (in[i] == 0) que[tail++] = i;
  }
  for (; head != tail;) {
    int v = que[head++];
    if (oug[v]) {
      if (fa[v]) {
        oug[e[fa[v]].en] ^= 1, mk[fa[v] >> 1] = 1;
      } else {
        printf("No solution");
        return 0;
      }
    }
    if (fa[v])
      if (!--in[e[fa[v]].en]) que[tail++] = e[fa[v]].en;
  }
  for (int i = 1, _end_ = m; i <= _end_; i++) {
    if (!mk[i])
      ins[v[i]].push_back(u[i]);
    else
      ins[u[i]].push_back(v[i]);
  }
  for (int i = 1, _end_ = n; i <= _end_; i++) {
    if (ins[i].size() % 2 == 0)
      for (int j = 0; j < (int)ins[i].size(); j += 2)
        printf("%d %d %d\n", ins[i][j], i, ins[i][j + 1]);
    else {
      printf("No solution");
      return 0;
    }
  }
}
