#include<unordered_set>
#include<map>
#include<iostream>
#include<cstdio>
#include<string>
#include<string_view>
#include<algorithm>
using namespace std;

const static string_view ASCII("abcdefghijklmnopqrstuvwxyz");

int N;

string canonical(const string& s) {
    map<char, string> m;
    auto it = ASCII.cbegin();
    string res;
    for (char c : s) {
        if (m.find(c) == m.end()) {
            m[c] = *it;
            ++it;
        }
        res += m[c];
    }
    //cout<<"can:\t"<<s<<"\t"<<res<<endl;
    return res;
}

void rec(int n, string s, unordered_set<string>* seen) {
    if (n==N) {
        string can = canonical(s);
        //seen->insert(can);
        if (!seen->count(can)){
            seen->insert(can);
        }
    } else {
        for (char c : ASCII.substr(0, n+1)) {
            s.push_back(c);
            rec(n+1, s, seen);
            s.pop_back();
        }
    }
}

int main() {    
    cin>>N;
    unordered_set<string> seen;
    rec(0, "", &seen);
    vector<string> ans(seen.begin(), seen.end());
    sort(ans.begin(), ans.end());
    for(const auto& s : ans) {
        cout<<s<<endl;
    }
}