#include <bits/stdc++.h>
using namespace std;
struct UF {
  vector<int> par;
  vector<int> sz;
  vector<int> rank;
  UF(int n) : par(n), sz(n), rank(n) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
      sz[i] = 1;
      rank[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  void merge(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y]) {
      par[x] = y;
      sz[y] += sz[x];
    } else {
      par[y] = x;
      sz[x] += sz[y];
      if (rank[x] == rank[y]) rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int n) { return sz[find(n)]; }
};
set<string> se;
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  long long n;
  cin >> n;
  if (n == 1) {
    cout << 'a' << endl;
    return 0;
  }
  for (long long i = 0; i < (1LL << ((long long)n - 1)); i++) {
    UF uni(n + 10);
    vector<bool> used(n + 10);
    vector<char> hoge(n + 10);
    for (long long j = 0; j < n - 1; j++) {
      if (i & ((1LL << ((long long)j)))) {
        uni.merge(j, j + 1);
      }
    }
    char now = 'a';
    string s = "";
    for (int j = 0; j < n; j++) {
      long long po = uni.find(j);
      if (used[po] == false) {
        used[po] = true;
        hoge[po] = now;
        s.push_back(now);
        now++;
      } else {
        s.push_back(hoge[po]);
      }
    }
    se.insert(s);
  }
  for (auto &a : se) cout << a << endl;
  return 0;
}
