#include <bits/stdc++.h>
using namespace std;
const long double PI = acos(-1.L);
const int SZ = 111111;
vector<int> edges[SZ];
bool blocked[SZ];
int begv[SZ], endv[SZ];
int n, m;
struct triple {
  int f, m, l;
};
vector<triple> ans;
void add_triple(int a, int b, int c) {
  triple cur;
  cur.l = a;
  cur.m = b;
  cur.f = c;
  ans.push_back(cur);
}
int dfs(int v) {
  vector<int> fred;
  for (int i = 0; i < edges[v].size(); ++i) {
    int ednm = edges[v][i];
    if (!blocked[ednm]) {
      fred.push_back(ednm);
      blocked[ednm] = true;
    }
  }
  vector<int> cped;
  for (int i = 0; i < fred.size(); ++i) {
    int fv = begv[fred[i]] == v ? endv[fred[i]] : begv[fred[i]];
    int dfans = dfs(fv);
    if (dfans != -1) {
      add_triple(dfans, fv, v);
    } else {
      cped.push_back(fred[i]);
    }
  }
  for (int i = 0; i + 1 < cped.size(); i += 2) {
    int fed = cped[i];
    int sed = cped[i + 1];
    int fothv = begv[fed] == v ? endv[fed] : begv[fed];
    int sothv = begv[sed] == v ? endv[sed] : begv[sed];
    add_triple(fothv, v, sothv);
  }
  if (cped.size() & 1) {
    int ansed = cped.back();
    int ansv = begv[ansed] == v ? endv[ansed] : begv[ansed];
    return ansv;
  } else {
    return -1;
  }
}
int main() {
  scanf("%d%d", &n, &m);
  if (m & 1) {
    puts("No solution");
    return 0;
  }
  for (int i = 0; i < m; ++i) {
    scanf("%d%d", begv + i, endv + i);
    --begv[i];
    --endv[i];
    edges[begv[i]].push_back(i);
    edges[endv[i]].push_back(i);
  }
  dfs(0);
  for (int i = 0; i < ans.size(); ++i) {
    printf("%d %d %d\n", ans[i].f + 1, ans[i].m + 1, ans[i].l + 1);
  }
  return 0;
}
