#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:512000000")
using namespace std;
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline string tostr(const T& x) {
  stringstream ss;
  ss << x;
  return ss.str();
}
const long double EPS = 1e-12;
const int INF = 1000 * 1000 * 1000;
const char CINF = 102;
const long long LINF = INF * 1ll * INF;
const long double DINF = 1e200;
const long double PI = 3.1415926535897932384626433832795l;
int gcd(int a, int b) { return a ? gcd(b % a, a) : b; }
long long gcd(long long a, long long b) { return a ? gcd(b % a, a) : b; }
long long powmod(long long a, long long p, long long m) {
  long long r = 1;
  while (p) {
    if (p & 1) r = r * a % m;
    p >>= 1;
    a = a * a % m;
  }
  return r;
}
int n;
vector<int> gr[110000];
int D[110000];
vector<pair<int, pair<int, int> > > ans;
bool dfs(int v, int d, int pr) {
  D[v] = d;
  int x = -1;
  for (int i = 0; i < (((int)(gr[v]).size())); ++i) {
    int p = gr[v][i];
    bool t = false;
    if (D[p]) {
      if (p != pr && D[p] > d) t = true;
    } else
      t = dfs(p, d + 1, v);
    if (!t) continue;
    if (x == -1)
      x = p;
    else {
      ans.push_back(make_pair(p, make_pair(v, x)));
      x = -1;
    }
  }
  if (x != -1) {
    ans.push_back(make_pair(pr, make_pair(v, x)));
    return false;
  }
  return true;
}
int main() {
  int m;
  cin >> n >> m;
  for (int i = 0; i < (m); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a;
    --b;
    gr[a].push_back(b);
    gr[b].push_back(a);
  }
  if (!dfs(0, 1, -1)) {
    cout << "No solution";
    return 0;
  }
  for (int i = 0; i < (((int)(ans).size())); ++i) {
    printf("%d %d %d\n", ans[i].first + 1, ans[i].second.first + 1,
           ans[i].second.second + 1);
  }
  return 0;
}
