#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:100000000")
using namespace std;
map<long long, int> st;
long long num[200200];
int cnt = 0;
int n;
vector<int> v[200200];
int deg[200200];
bool vis[200200];
int mas[11][11];
int c[11];
long long pown[11];
long long parsemask(long long m, bool pr = false) {
  for (int i = 0; i < n; i++) c[i] = 0;
  for (int i = 0; i < n; i++) {
    long long idx = (m & ((1LL << (4 * (i + 1))) - 1)) >> (4 * i);
    mas[idx][c[idx]++] = i;
  }
  int cntline = 0;
  for (int idx = 0; idx < n; idx++) {
    if (c[idx] != 0) {
      if (idx != cntline) {
        swap(c[idx], c[cntline]);
        for (int i = 0; i < c[cntline]; i++) swap(mas[idx][i], mas[cntline][i]);
      }
      cntline++;
    }
  }
  for (int idx = 0; idx < cntline; idx++) {
    for (int i = 0; i < c[idx]; i++) {
      for (int j = i + 1; j < c[idx]; j++) {
        if (mas[idx][i] > mas[idx][j]) swap(mas[idx][i], mas[idx][j]);
      }
    }
  }
  for (int idx1 = 0; idx1 < cntline; idx1++) {
    for (int idx2 = idx1 + 1; idx2 < cntline; idx2++) {
      if (mas[idx1][0] > mas[idx2][0]) {
        int maxlen = max(c[idx1], c[idx2]);
        for (int i = 0; i < maxlen; i++) {
          swap(mas[idx1][i], mas[idx2][i]);
        }
        swap(c[idx1], c[idx2]);
      }
    }
  }
  if (pr) {
    for (int i = 0; i < cntline; i++) {
      if (i != 0) printf(",");
      printf("{");
      for (int j = 0; j < c[i]; j++) {
        if (j != 0) printf(",");
        printf("%d", mas[i][j] + 1);
      }
      printf("}");
    }
    printf("\n");
    return 0;
  }
  long long res = 0;
  for (int i = 0; i < cntline; i++) {
    for (int j = 0; j < c[i]; j++) {
      int val = mas[i][j];
      res += ((long long)i << (val << 2));
    }
  }
  return res;
}
vector<long long> path;
void go(long long id) {
  path.push_back(id);
  vis[id] = true;
  int nxt = -1;
  int mindeg = 1e9;
  for (int i = 0; i < (int)(v[id]).size(); i++) {
    if (!vis[v[id][i]]) {
      if (deg[v[id][i]] < mindeg) {
        mindeg = deg[v[id][i]];
        nxt = v[id][i];
      }
      deg[v[id][i]]--;
    }
  }
  if (nxt != -1) go(nxt);
}
int main() {
  scanf("%d", &n);
  pown[0] = 1;
  for (int i = 1; i <= n; i++) pown[i] = pown[i - 1] * (long long)16;
  long long mask = 0;
  st[mask] = ++cnt;
  queue<long long> q;
  q.push(mask);
  num[1] = 0;
  while (!q.empty()) {
    long long m = q.front();
    long long curid = st[m];
    parsemask(m);
    int cntline = 0;
    for (int i = 0; i < n; i++) {
      if (c[i] != 0) cntline = i + 1;
    }
    q.pop();
    for (int i = 0; i < n; i++) {
      long long curval = (m & ((1LL << (4 * (i + 1))) - 1)) >> (4 * i);
      long long nxt = m - (curval << (i * 4));
      for (long long j = 0, maxj = min((long long)n, (long long)(cntline + 1));
           j < maxj; j++) {
        if ((int)(v[curid]).size() > 40) {
          i = n;
          break;
        }
        if (curval != j) {
          long long pm = parsemask(nxt);
          if (st.find(pm) == st.end()) {
            st[pm] = ++cnt;
            num[cnt] = pm;
            q.push(pm);
          }
          long long nxtid = st[pm];
          if (curid < nxtid) {
            v[nxtid].push_back(curid);
            v[curid].push_back(nxtid);
            deg[nxtid]++;
            deg[curid]++;
          }
        }
        nxt += pown[i];
      }
    }
  }
  printf("%d\n", cnt);
  go(1);
  for (int i = 0; i < (int)(path).size(); i++) {
    long long mask = num[path[i]];
    parsemask(mask, true);
  }
  return 0;
}
