#include <bits/stdc++.h>
using namespace std;
using ll = long long;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MXN = 100005;
int depth[MXN];
vector<int> ups[MXN];
set<int> children[MXN];
int parent[MXN];
vector<int> adj[MXN];
vector<pair<int, int>> cur_component;
int cur_edges = 0;
bool dealt_with[MXN];
bool weird[MXN];
void dfs(int v, int par) {
  depth[v] = 1 + depth[par];
  cur_component.push_back({depth[v], v});
  children[par].insert(v);
  parent[v] = par;
  for (auto u : adj[v]) {
    if (depth[u] > depth[v]) ups[u].push_back(v);
    if (depth[u] == 0) dfs(u, v);
    if (depth[u] < depth[v]) cur_edges++;
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  vector<tuple<int, int, int>> ans;
  for (int v = 1; v <= n; v++) {
    if (depth[v] != 0) continue;
    while (!cur_component.empty()) cur_component.pop_back();
    dfs(v, 0);
    if (cur_edges % 2 != 0) {
      cout << "No solution\n";
      return 0;
    }
    sort(cur_component.rbegin(), cur_component.rend());
    for (auto thing : cur_component) {
      int u = thing.second;
      while (int((ups[u]).size()) > 1) {
        ans.push_back({ups[u][int((ups[u]).size()) - 1], u,
                       ups[u][int((ups[u]).size()) - 2]});
        ups[u].pop_back();
        ups[u].pop_back();
      }
    }
    priority_queue<tuple<int, int, int>> cur_components2;
    for (auto c : cur_component) {
      cur_components2.push({c.first, int((ups[c.second]).size()), c.second});
    }
    while (!cur_components2.empty()) {
      int u = get<2>(cur_components2.top());
      if (weird[u] && get<1>(cur_components2.top()) == 1) {
        cur_components2.pop();
        continue;
      }
      cur_components2.pop();
      if (dealt_with[u] || u == v) continue;
      if (int((ups[u]).size()) == 1) {
        ans.push_back({parent[u], u, ups[u].back()});
        ups[u].pop_back();
        children[parent[u]].erase(u);
        continue;
      }
      if (int((children[parent[u]]).size()) >= 2) {
        children[parent[u]].erase(u);
        int u2;
        for (auto uu : children[parent[u]]) {
          u2 = uu;
          break;
        }
        children[parent[u]].erase(u2);
        dealt_with[u2] = 1;
        ans.push_back({u, parent[u], u2});
      } else {
        if (!ups[parent[u]].empty()) {
          children[parent[u]].erase(u);
          ans.push_back({u, parent[u], ups[parent[u]].back()});
          ups[parent[u]].pop_back();
          cur_components2.push({depth[parent[u]], 0, parent[u]});
          weird[parent[u]] = 1;
        } else {
          ans.push_back({u, parent[u], parent[parent[u]]});
          dealt_with[parent[u]] = 1;
          children[parent[parent[u]]].erase(parent[u]);
        }
      }
    }
  }
  for (auto a : ans)
    cout << get<0>(a) << " " << get<1>(a) << " " << get<2>(a) << endl;
}
