#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000 * 1000 + 10;
const int maxn5 = 3 * 1000 * 100 + 10;
const long long mod = 1000 * 1000 * 1000 + 7;
const long long inf = 1LL * 2 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 + 10;
set<int> adj[maxn5];
bool mark[maxn5];
int cnt = 0, h[maxn5], sz[maxn5], extra[maxn5];
vector<int> backedge[maxn5], odd[maxn5];
void cmp_dfs(int v, int par = -1) {
  cnt += adj[v].size();
  mark[v] = true;
  auto it = adj[v].begin();
  while (it != adj[v].end()) {
    int u = *it;
    it++;
    if (!mark[u]) {
      h[u] = h[v] + 1;
      cmp_dfs(u, v);
    } else if (h[v] > h[u] and u != par)
      adj[v].erase(u);
  }
  return;
}
void remove_backedge(int v, int par = -1) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  mark[v] = true;
  auto it = adj[v].begin();
  while (it != adj[v].end()) {
    int u = *it;
    it++;
    if (!mark[u]) {
      sz[u]++;
      remove_backedge(u, v);
      sz[v] += sz[u];
    } else if (u != par)
      backedge[v].push_back(u);
  }
  if (backedge[v].size() % 2 == 1) {
    extra[v] = backedge[v].back();
    sz[v]++;
  }
  for (int i = 1; i < backedge[v].size(); i += 2)
    cout << backedge[v][i] << ' ' << v << ' ' << backedge[v][i - 1] << '\n';
  for (auto u : backedge[v]) adj[v].erase(u);
  backedge[v].clear();
  return;
}
void dfs(int v) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  mark[v] = true;
  for (auto u : adj[v])
    if (sz[u] % 2 == 1) odd[v].push_back(u);
  if (extra[v] != 0) {
    int u = odd[v].back();
    cout << extra[v] << ' ' << v << ' ' << u << '\n';
    adj[u].erase(v);
    odd[v].pop_back();
  }
  for (int i = 1; i < odd[v].size(); i += 2) {
    cout << odd[v][i] << ' ' << v << ' ' << odd[v][i - 1] << '\n';
    adj[odd[v][i]].erase(v);
    adj[odd[v][i - 1]].erase(v);
  }
  odd[v].clear();
  sz[v] = 1;
  auto it = adj[v].begin();
  while (it != adj[v].end()) {
    int u = *it;
    it++;
    if (!mark[u]) dfs(u);
  }
  return;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    adj[a].insert(b);
    adj[b].insert(a);
  }
  for (int i = 1; i <= n; i++)
    if (!mark[i]) {
      cnt = 0;
      cmp_dfs(i);
      cnt /= 2;
      if (cnt % 2 == 1) return cout << "No solution" << endl, 0;
    }
  fill(mark, mark + maxn5, false);
  for (int i = 1; i <= n; i++)
    if (!mark[i]) remove_backedge(i);
  fill(mark, mark + maxn5, false);
  for (int i = 1; i <= n; i++)
    if (!mark[i]) dfs(i);
  return 0;
}
