#include <bits/stdc++.h>
using namespace std;
vector<int> graph[100010];
map<pair<int, int>, int> mp;
bitset<100010> visNode, visEdge;
int n, m, a, b;
pair<int, int> dfs(int node) {
  vector<int> edges;
  for (int i = 0; i < graph[node].size(); i++) {
    pair<int, int> tmpEdge(-1, -1);
    pair<int, int> secondEdge(-1, -1);
    int u = min(node, graph[node][i]);
    int v = max(node, graph[node][i]);
    if (visEdge[mp[pair<int, int>(u, v)]]) {
      continue;
    }
    tmpEdge = pair<int, int>(node, graph[node][i]);
    visEdge[mp[pair<int, int>(u, v)]] = 1;
    if (!visNode[graph[node][i]]) {
      visNode[graph[node][i]] = 1;
      secondEdge = dfs(graph[node][i]);
    }
    if (secondEdge.first != -1) {
      int thirdNode = (secondEdge.first == graph[node][i]) ? secondEdge.second
                                                           : secondEdge.first;
      printf("%d %d %d\n", node + 1, graph[node][i] + 1, thirdNode + 1);
    } else {
      edges.push_back(tmpEdge.second);
    }
  }
  for (int i = 0; i + 1 < edges.size(); i += 2) {
    printf("%d %d %d\n", edges[i] + 1, node + 1, edges[i + 1] + 1);
  }
  if (edges.size() % 2 == 0)
    return pair<int, int>(-1, -1);
  else
    return pair<int, int>(min(node, edges[edges.size() - 1]),
                          max(node, edges[edges.size() - 1]));
}
int main() {
  scanf("%d %d", &n, &m);
  if (m % 2 == 1) {
    printf("No solution\n");
    return 0;
  }
  for (int i = 0; i < m; i++) {
    scanf("%d %d", &a, &b);
    a--, b--;
    graph[a].push_back(b);
    graph[b].push_back(a);
    mp[pair<int, int>(min(a, b), max(a, b))] = i;
  }
  visNode[0] = 1;
  dfs(0);
}
