#include <bits/stdc++.h>
using namespace std;
const int N = 100 * 1000 + 10;
bool mark[N], mark2[N], mark3[N];
vector<pair<int, int> > v[N];
vector<int> adj[N], ans[N], nmch[N];
int t, cnt;
int dfs(int u) {
  mark[u] = true;
  for (int i = 0; i < v[u].size(); i++) {
    int y = v[u][i].first, id = v[u][i].second;
    if (!mark2[id]) adj[u].push_back(y);
    mark2[id] = true;
  }
  for (int i = 0; i < adj[u].size(); i++) {
    int y = adj[u][i];
    int y2 = dfs(y);
    if (y2 == -1) {
      nmch[u].push_back(y);
    } else {
      ans[t].push_back(y2);
      ans[t].push_back(y);
      ans[t++].push_back(u);
    }
  }
  adj[u].clear();
  while (nmch[u].size() >= 2) {
    int u1 = nmch[u].back();
    nmch[u].pop_back();
    int u2 = nmch[u].back();
    nmch[u].pop_back();
    ans[t].push_back(u1);
    ans[t].push_back(u);
    ans[t++].push_back(u2);
  }
  if (nmch[u].size() > 0) {
    int x = nmch[u][0];
    nmch[u].clear();
    return nmch[u][0];
  }
  return -1;
}
void dfs2(int u) {
  mark3[u] = true;
  for (int i = 0; i < v[u].size(); i++) {
    if (!mark3[v[u][i].first]) dfs2(v[u][i].first);
    if (mark2[v[u][i].second] == false) {
      cnt++;
      mark2[v[u][i].second] = true;
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    v[a].push_back(make_pair(b, i));
    v[b].push_back(make_pair(a, i));
  }
  for (int i = 0; i < n; i++)
    if (!mark[i]) dfs(i);
  fill(mark2, mark2 + N, false);
  for (int i = 0; i < n; i++) {
    if (mark3[i]) continue;
    cnt = 0;
    dfs2(i);
    if (cnt % 2 == 1) {
      cout << "No solution";
      exit(0);
    }
  }
  for (int i = 0; i < t; i++) {
    for (int j = 0; j < ans[i].size(); j++) cout << ans[i][j] + 1 << " ";
    cout << '\n';
  }
}
