#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:16777216")
using namespace std;
vector<int> adj[110000];
bool vst[110000];
vector<int> ans;
set<pair<int, int> > vis_edges;
bool failed;
int dfs(int u, int fa) {
  vst[u] = true;
  vector<int> tmp;
  for (int i = 0; i < (int)adj[u].size(); i++) {
    int v = adj[u][i];
    if (v == fa) continue;
    if (vst[v] == false) {
      if (dfs(v, u) == 1) tmp.push_back(v);
    } else if (vis_edges.find(pair<int, int>(u, v)) == vis_edges.end()) {
      tmp.push_back(v);
      vis_edges.insert(pair<int, int>(u, v));
      vis_edges.insert(pair<int, int>(v, u));
    }
  }
  if (tmp.size() % 2 == 0) {
    for (int i = 0; i < tmp.size(); i += 2) {
      ans.push_back(tmp[i]);
      ans.push_back(u);
      ans.push_back(tmp[i + 1]);
    }
    return 1;
  } else if (fa != -1) {
    tmp.push_back(fa);
    for (int i = 0; i < tmp.size(); i += 2) {
      ans.push_back(tmp[i]);
      ans.push_back(u);
      ans.push_back(tmp[i + 1]);
    }
    return 0;
  } else {
    failed = true;
    return 0;
  }
}
int main() {
  int n, m;
  while (scanf("%d %d", &n, &m) != EOF) {
    for (int i = 1; i <= n; i++) adj[i].clear();
    for (int i = 1; i <= m; i++) {
      int a, b;
      scanf("%d %d", &a, &b);
      adj[a].push_back(b);
      adj[b].push_back(a);
    }
    memset(vst, false, sizeof(vst));
    ans.clear();
    vis_edges.clear();
    failed = false;
    for (int i = 1; i <= n; i++) {
      if (vst[i] == false) {
        if (dfs(i, -1) == 0) failed = true;
      }
    }
    if (failed) {
      puts("No solution");
    } else {
      for (int i = 0; i < ans.size(); i += 3) {
        printf("%d %d %d\n", ans[i], ans[i + 1], ans[i + 2]);
      }
    }
  }
}
