#include <bits/stdc++.h>
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using namespace std;
struct UnionFind {
  int num;
  vector<int> rs, ps;
  UnionFind() {}
  UnionFind(int n) : num(n), rs(n, 1), ps(n, 0) {
    iota(ps.begin(), ps.end(), 0);
  }
  int find(int x) { return (x == ps[x] ? x : ps[x] = find(ps[x])); }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rs[x] < rs[y]) swap(x, y);
    rs[x] += rs[y];
    ps[y] = x;
    num--;
  }
  int size(int x) { return rs[find(x)]; }
  int count() const { return num; }
};
using ll = long long;
using P = std::pair<ll, int>;
ll N;
ll dp[20][20];
std::vector<P> pre[20][20];
std::set<std::string> ans;
void dfs(int i, int j, const std::string& s) {
  if (!i) {
    ans.insert(s);
  }
  for (int idx = (0); idx < (pre[i][j].size()); ++idx) {
    char ch = 'a' + pre[i][j][idx].first;
    std::string t = s + ch;
    dfs(i - 1, j - pre[i][j][idx].second, t);
  }
}
int main() {
  std::cin >> N;
  dp[0][0] = 1;
  for (int i = (0); i < (N); ++i)
    for (int j = (0); j < (i + 1); ++j) {
      dp[i + 1][j] += dp[i][j] * j;
      if (dp[i][j])
        for (int k = (0); k < (j); ++k) pre[i + 1][j].emplace_back(P(k, 0));
      dp[i + 1][j + 1] += dp[i][j];
      if (dp[i][j]) pre[i + 1][j + 1].emplace_back(P(j, 1));
    }
  for (int j = (0); j < (N + 1); ++j) {
    dfs(N, j, "");
  }
  for (auto it = ans.begin(); it != ans.end(); ++it) {
    std::string t = *it;
    std::reverse((t).begin(), (t).end());
    std::cout << t << std::endl;
  }
  return 0;
}
