#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000 * 100 + 10;
vector<pair<int, int> > e[maxn];
vector<int> component;
bool mark[maxn], Mark[maxn], finish[maxn];
bool cmp(int a, int b) { return e[a].size() < e[b].size(); }
bool cmp2(pair<int, int> a, pair<int, int> b) {
  return e[a.first].size() < e[b.first].size();
}
void bye() {
  cout << "No solution\n";
  exit(0);
}
void dfs(int source, int &cnt) {
  cnt += e[source].size();
  mark[source] = true;
  for (int i = 0; i < e[source].size(); i++)
    if (!mark[e[source][i].first]) dfs(e[source][i].first, cnt);
}
void DFS(int source, int par, int E) {
  mark[source] = true;
  for (int i = 0; i < e[source].size(); i++)
    if (!mark[e[source][i].first])
      DFS(e[source][i].first, source, e[source][i].second);
  int past, time = 0, P;
  for (int i = 0; i < e[source].size(); i++)
    if (finish[e[source][i].first] and !Mark[e[source][i].second]) {
      if (time % 2 == 0)
        past = e[source][i].first, P = e[source][i].second;
      else
        Mark[e[source][i].second] = true, Mark[P] = true,
        cout << past + 1 << " " << source + 1 << " " << e[source][i].first + 1
             << endl;
      time++;
    }
  if (time % 2)
    Mark[E] = true, Mark[P] = true,
    cout << past + 1 << " " << source + 1 << " " << par + 1 << endl;
  finish[source] = true;
}
int main() {
  int n, m, fi, se;
  cin >> n >> m;
  for (int i = 0; i < m; i++)
    cin >> fi >> se, e[--fi].push_back(make_pair(--se, i)),
        e[se].push_back(make_pair(fi, i));
  for (int i = 0; i < n; i++) sort(e[i].begin(), e[i].end(), cmp2);
  for (int i = 0; i < n; i++)
    if (!mark[i]) {
      component.push_back(i);
      int cnt = 0;
      dfs(i, cnt);
      if ((cnt / 2) % 2) bye();
    }
  memset(mark, 0, sizeof mark);
  for (int i = 0; i < component.size(); i++) DFS(component[i], -1, -1);
  return 0;
}
