// Original C++ solution (slower):
#include <iostream>

#include <string>

#include <algorithm>

#include <functional>

#include <vector>

#include <stack>

#include <queue>

#include <deque>

#include <set>

#include <map>

#include <cstdio>

#include <cmath>

#include <tuple>

#include <iomanip>

#include <numeric>

#include <unordered_map>

#include <sstream>   

#include<limits.h>

#include<float.h>

#include<list>

#include <array>

#include <complex>

using namespace std;

#define i64  long long

#define int  long long

 

#define I32_MAX 2147483647

#define I64_MAX 9223372036854775807LL

#define I64_MAX2 1223372036854775807LL

#define INF I64_MAX2

#define MOD 1000000007

#define MEM_SIZE 10000

#define DEBUG_OUT true

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



// int DP[MEM_SIZE][MEM_SIZE] = {0};

// int GMEM[MEM_SIZE][MEM_SIZE] = {0};

template<typename T> void DEBUG(T e){if(DEBUG_OUT == false)return;std::cout << e << std::endl;}

template<typename T> void DEBUG(const std::vector<T>& v){if(DEBUG_OUT == false)return;for(const auto& e : v){ std::cout << e << " "; } std::cout << std::endl;}

template<typename T> void DEBUG(const std::vector<std::vector<T> >& vv){if(DEBUG_OUT == false)return;for(const auto& v : vv){ DEBUG(v); } }

template<class T,class X> void DEBUG(X d, T e){if(DEBUG_OUT == false)return;std::cout <<d<<" ";DEBUG(e);};

template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}

template< typename T1, typename T2 > inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template< typename T1, typename T2 > inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }



//CODE



void DFS(int N,int depth,int num,string str,vector<string> &vec)

{

  if(depth == N)

  {

    // DEBUG(num,str);

    vec.push_back(str);

    return;

  }

  for (int i = 0; i < num+1; i++)

  {

    string str2 = str + char('a' + i);

    if(char('a' + i) >= 'a' + depth+1) return;

    DFS(N,depth+1,max(num,i+1),str2,vec);

  }

  



}

void solve(void)

{

  int N;

  cin>>N;

  string str = "a";

  vector<string> vec;

  DFS(N,1,1,str,vec);

  sort(ALL(vec));

  for (int i = 0; i < vec.size(); i++)

  {

    cout<<vec[i]<<endl;

  }

  

  

  return;

}





int32_t main(int32_t argc, const char *argv[])

{

  std::ios::sync_with_stdio(false);

  std::cin.tie(0);



  std::cout << std::fixed;

  std::cout << std::setprecision(9);

  solve();

  



 

  return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include <algorithm>

#include <functional>

#include <vector>

#include <stack>

#include <queue>

#include <deque>

#include <set>

#include <map>

#include <cstdio>

#include <cmath>

#include <tuple>

#include <iomanip>

#include <numeric>

#include <unordered_map>

#include <sstream>   

#include<limits.h>

#include<float.h>

#include<list>

#include <array>

#include <complex>

#include<stdio.h>

#include<string.h>



using namespace std;

#define int  long long

 

#define I32_MAX 2147483647

#define I64_MAX 9223372036854775807LL

#define I64_MAX2 1223372036854775807LL

#define INF I64_MAX2

#define MOD 1000000007

#define MEM_SIZE 10000

#define DEBUG_OUT true

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

// int DP[MEM_SIZE][MEM_SIZE] = {0};

// int GMEM[MEM_SIZE][MEM_SIZE] = {0};

template<typename T> void DEBUG(T e){if(DEBUG_OUT == false)return;std::cout << e << std::endl;}

template<typename T> void DEBUG(const std::vector<T>& v){if(DEBUG_OUT == false)return;for(const auto& e : v){ std::cout << e << " "; } std::cout << std::endl;}

template<typename T> void DEBUG(const std::vector<std::vector<T> >& vv){if(DEBUG_OUT == false)return;for(const auto& v : vv){ DEBUG(v); } }

template<class T,class X> void DEBUG(X d, T e){if(DEBUG_OUT == false)return;std::cout <<d<<" ";DEBUG(e);};

template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}

template< typename T1, typename T2 > inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template< typename T1, typename T2 > inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }



  vector<string> ANS;

  void DFS(int D,int N,string str,int k)

  {

    // DEBUG("call",D);

    if(D==N)

    {

      cout<<str<<endl;

      return;

    }

    for (int i = 0; i <= k; i++)

    {

      DFS(D+1,N,str+char('a'+i),max(k,i+1));

    }

    return;

  }

void solve(void)

{

  int N;

  cin>>N;

  DFS(0,N,"",0);

  sort(ALL(ANS));



  return;

}



int32_t main(int32_t argc, const char *argv[])

{

  std::ios::sync_with_stdio(false);

  std::cin.tie(0);



  std::cout << std::fixed;

  std::cout << std::setprecision(9);

  solve();



  return 0;

}


// Fastest known solution for this problem: