// Original C++ solution (slower):
#pragma GCC optimize("Ofast")

  

#include <iostream>

#include <algorithm>

#include <vector>

#include <cstring>

#include <string>

#include <map>

#include <unordered_map>

#include <queue>

#include <stack>

#include <deque>

#include <set>

#include <unordered_set>

#include <list>

#include <tuple>

#include <iomanip>

#include <climits>

#include <cstdlib>

#include <cassert>

#include <numeric>

#include <math.h>

#include <random>



using namespace std;

  

#define rep(i,n) for(int i=0;i<(n);++i)

#define reps(i,n) for(int i=1;i<=(n);++i)

#define all(x) (x).begin(),(x).end()

#define Fixed fixed << setprecision(14)

#define int int64_t

using pii = pair<int,int>;

constexpr int INF  = 0x3f3f3f3f;

constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;

constexpr int mod1 = 1e9+7; 

constexpr int mod2 = 998244353;

 

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }

template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

 

template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;

template <class T> using max_heap = priority_queue<T>;

template <class A,class B> using umap = unordered_map<A,B>;

   

int gcd(int a,int b){ return b ? gcd(b,a % b) : a;}

int lcm(int a,int b){ return a / gcd(a,b) * b;}

inline int updiv(int a,int b){ return (a + b - 1) / b; }



int n;

vector<string> res;



void dfs(int k,string s,char maxc){

  if(k == n){

    res.emplace_back(s);

    return;

  }

  for(char c = 'a'; c <= maxc + 1 && c - 'a' <= k; ++c){

    dfs(k+1,s + string(1,c),max(maxc,c));

  }

  return;

}



signed main(void){

  cin.tie(nullptr);

  ios_base::sync_with_stdio(false);



  cin >> n;

  dfs(0,"",'a');



  sort(all(res));



  for(auto e : res){

    cout << e << '\n';

  }



  return 0;

}

// Optimized solution to the same problem (faster):
#pragma GCC optimize("Ofast")

  

#include <iostream>

#include <algorithm>

#include <vector>

#include <cstring>

#include <string>

#include <map>

#include <unordered_map>

#include <queue>

#include <stack>

#include <deque>

#include <set>

#include <unordered_set>

#include <list>

#include <tuple>

#include <iomanip>

#include <climits>

#include <cstdlib>

#include <cassert>

#include <numeric>

#include <math.h>

#include <random>



using namespace std;

  

#define rep(i,n) for(int i=0;i<(n);++i)

#define reps(i,n) for(int i=1;i<=(n);++i)

#define all(x) (x).begin(),(x).end()

#define Fixed fixed << setprecision(14)

#define int int64_t

using pii = pair<int,int>;

constexpr int INF  = 0x3f3f3f3f;

constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;

constexpr int mod1 = 1e9+7; 

constexpr int mod2 = 998244353;

 

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }

template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

 

template <class T> using min_heap = priority_queue<T,vector<T>,greater<T> >;

template <class T> using max_heap = priority_queue<T>;

template <class A,class B> using umap = unordered_map<A,B>;

   

int gcd(int a,int b){ return b ? gcd(b,a % b) : a;}

int lcm(int a,int b){ return a / gcd(a,b) * b;}

inline int updiv(int a,int b){ return (a + b - 1) / b; }



int n;

vector<string> res;



void dfs(int k,string s,char maxc){

  if(k == n){

    res.emplace_back(s);

    return;

  }

  for(char c = 'a'; c <= maxc + 1 && c - 'a' <= k; ++c){

    dfs(k+1,s + string(1,c),max(maxc,c));

  }

  return;

}



signed main(void){

  cin.tie(nullptr);

  ios_base::sync_with_stdio(false);



  cin >> n;

  dfs(0,"",'a');



  //sort(all(res));



  for(auto e : res){

    cout << e << '\n';

  }



  return 0;

}

// Fastest known solution for this problem: