#include <bits/stdc++.h>
using namespace std;
int64_t mod = 1e9 + 7;
int64_t mod1 = 1e9 + 5;
int64_t power(int64_t a, int64_t b) {
  if (b == 0)
    return 1;
  else if (b % 2 == 0)
    return power((((a % mod) * (a % mod)) % mod), b / 2) % mod;
  else
    return ((a % mod) * (power((((a % mod) * (a % mod)) % mod), b / 2) % mod)) %
           mod;
}
vector<complex<int64_t> > hull, vecs;
int64_t dot(complex<int64_t> a, complex<int64_t> b) {
  return (conj(a) * b).real();
}
int64_t cross(complex<int64_t> a, complex<int64_t> b) {
  return (conj(a) * b).imag();
}
void add_line(int64_t k, int64_t b) {
  complex<int64_t> nw = {k, b};
  complex<int64_t> iota = {0, 1};
  while (!vecs.empty() && dot(vecs.back(), nw - hull.back()) < 0) {
    hull.pop_back();
    vecs.pop_back();
  }
  if (!hull.empty()) {
    vecs.push_back(iota * (nw - hull.back()));
  }
  hull.push_back(nw);
}
int64_t get(int64_t real) {
  complex<int64_t> query = {real, 1};
  auto it = lower_bound(
      vecs.begin(), vecs.end(), query,
      [](complex<int64_t> a, complex<int64_t> b) { return cross(a, b) > 0; });
  return dot(query, hull[it - vecs.begin()]);
}
vector<int64_t> v[11];
int64_t n;
void recurse(int64_t i) {
  if (i == n) {
    char ch[n + 1];
    int64_t c = 0;
    for (int64_t j = 0; j < n; j++) {
      char ch1 = 'a' + j;
      if (v[j].size() == 0) break;
      for (int64_t k = 0; k < v[j].size(); ++k) {
        c++;
        ch[v[j][k]] = ch1;
      }
    }
    if (c != n) return;
    for (int64_t j = 0; j < n; j++) cout << ch[j];
    cout << '\n';
    return;
  } else {
    for (int64_t j = 0; j <= i; j++) {
      v[j].push_back(i);
      recurse(i + 1);
      v[j].pop_back();
    }
  }
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  cin >> n;
  recurse(0);
}
