CodeEff/ECCO huggingface dataset:
# Original solution
N = int(eval(input()))

#文字数分aで埋める
#末尾をbにする
#一桁上の文字+1文字までは許容するルールで増加させていく

import itertools

stop_combination = [chr(i) for i in range(97,97+N)]
combination_list = list(itertools.product(stop_combination, repeat=N))

printed_expression = set()

for combination in combination_list:
    #print(combination,":",end="")

    if list(combination) == stop_combination:
        print((''.join(map(str, combination))))
        break

    character_dict = dict()
    character_number = 0
    alternative_expression = ""

    for character in combination:
        if character not in character_dict:
            character_dict[character] = character_number
            alternative_expression += str(character_number)
            character_number += 1
        else:
            alternative_expression += str(character_dict[character])

    #print(alternative_expression)

    if alternative_expression not in printed_expression:
        print((''.join(map(str, combination))))
        printed_expression.add(alternative_expression)

# Optimized solution
N = int(eval(input()))

#文字数分aで埋める
#末尾をbにする
#一桁上の文字+1文字までは許容するルールで増加させていく

ans = [0 for _ in range(N)]
stop = [i for i in range(N)]

def ans_print(ans_list):
    ans = list()
    for a in ans_list:
        ans.append(chr(a+97)) #97でaが出る

    print((''.join(map(str, ans))))
    return 0

def ans_check(ans):
    max_in_ans = 0

    for i in range(1,N):
        if max_in_ans + 1 < ans[i]:
            ans[i-1] += 1
            ans[i] = 0
            return ans_check(ans)
        else:
            max_in_ans = max(max_in_ans,ans[i])
    else:
        return ans

if N == 1:
    print("a")
else:
    while 1:
        ans_check(ans)
        ans_print(ans)
        ans[-1] += 1
        if ans == stop:
            ans_print(ans)
            break
# Original solution
N = int(input())

def it(remain,n):
    if remain == 0:
        yield []
    else:
        for x in range(n+1):
            for d in it(remain-1,max(x+1,n)):
                d.append(x)
                yield d


print(*(''.join(chr(x+ord('a')) for x in reversed(d)) for d in it(N,0)), sep='\n')



# Optimized solution
N = int(input())

def it(i,n):
    if i == N:
        yield [None]*N
    else:
        for x in range(n):
            for d in it(i+1,n):
                d[i] = x
                yield d
        for d in it(i+1,n+1):
            d[i] = n
            yield d

print(*(''.join(chr(x+ord('a')) for x in d) for d in it(0,0)), sep='\n')
# Original solution
N = int(eval(input()))
k = "abcdefghij"
A = []
Q = [(1,1,"a")]
while Q:
    q = Q.pop()
    if q[0]==N:
        A.append(q[2])
        continue
    for i in range(q[1]+1):
        Q.append((q[0]+1,max(q[1],i+1),q[2]+k[i]))
A.sort()
for a in A:print(a)

# Optimized solution
N = int(eval(input()))
S = "abcdefghijklmn"
Q = [(1,1,"a")]
A = []
while Q:
    q = Q.pop(-1)
    if q[0]==N:
        A.append(q[2])
        continue
    for i in range(q[1]+1):
        Q.append((q[0]+1,max(q[1],i+1),q[2]+S[i]))
for a in sorted(A):print(a)
# Original solution


def dfs(string,n):
    if len(string)==n:
        print(string)
    else:
        s=string
        for i in range(97,max([ord(j)for j in string])+2):
            dfs(string+chr(i),n)
        

dfs("a",int(eval(input())))

# Optimized solution
n=int(eval(input()))
def d(s):
    if len(s)==n:
        print(s)
    else:
        for i in range(97,ord(max(s))+2):
            d(s+chr(i))
d("a")
# Original solution
k = "a",
for _ in range(int(input()) - 1):
  k = {a + b for a in k for b in a + chr(ord(max(a)) + 1)}
print(*sorted(k), sep='\n')


# Optimized solution
k = "a",
for _ in range(int(eval(input())) - 1):
  k = {a + b for a in k for b in a + chr(ord(max(a)) + 1)}
for i in sorted(k):print(i)
# Original solution
# D
N = int(eval(input()))

al = [chr(ord('a') + i) for i in range(26)]

def dfs(S, i):
    if len(S) == N:
        yield ''.join(S)
        return
    for j in range(i):
        for w in dfs(S + [al[j]], i):
            yield w
    for w in dfs(S + [al[i]], i + 1):
        yield w

for w in dfs([], 0):
    print(w)

# Optimized solution
# D
N = int(eval(input()))

al = [chr(ord('a') + i) for i in range(26)]

def dfs(S, i):
    if len(S) == N:
        yield S
        return
    for j in range(i):
        for w in dfs(S + al[j], i):
            yield w
    for w in dfs(S + al[i], i + 1):
        yield w

for w in dfs('', 0):
    print(w)
# Original solution
# D
N = int(eval(input()))

al = [chr(ord('a') + i) for i in range(26)]

def dfs(S, i):
    if len(S) == N:
        yield S
        return
    for j in range(i):
        for w in dfs(S + al[j], i):
            yield w
    for w in dfs(S + al[i], i + 1):
        yield w

for w in dfs('', 0):
    print(w)

# Optimized solution
# D
N = int(eval(input()))

al = [chr(ord('a') + i) for i in range(26)]

ans = ['a']
for i in range(N-1):
    tmp = []
    for s in ans:
        stop = ord(max(s)) + 1
        for i in range(ord('a'), stop+1):
            tmp.append(s + chr(i))
    ans = tmp
for s in ans:
    print(s)
# Original solution
import sys


def I(): return int(sys.stdin.readline())


def MI(): return list(map(int, sys.stdin.readline().split()))


def LMI(): return list(map(int, sys.stdin.readline().split()))


MOD = 10 ** 9 + 7

s = 'abcdefghijklmnop'
N = I()

for c1 in range(1):
    if N == 1:
        print((s[c1]))
        continue
    for c2 in range(2):
        if N == 2:
            print((s[c1]+s[c2]))
            continue
        for c3 in range(max(c1, c2) + 2):
            if N == 3:
                print((s[c1] + s[c2] + s[c3]))
                continue
            for c4 in range(max(c1, c2, c3) + 2):
                if N == 4:
                    print((s[c1] + s[c2] + s[c3] + s[c4]))
                    continue
                for c5 in range(max(c1, c2, c3, c4) + 2):
                    if N == 5:
                        print((s[c1] + s[c2] + s[c3] + s[c4] + s[c5] ))
                        continue
                    for c6 in range(max(c1, c2, c3, c4, c5) + 2):
                        if N == 6:
                            print((s[c1] + s[c2] + s[c3] + s[c4] + s[c5] + s[c6]))
                            continue
                        for c7 in range(max(c1, c2, c3, c4, c5, c6) + 2):
                            if N == 7:
                                print((s[c1] + s[c2] + s[c3] + s[c4] + s[c5] + s[c6] + s[c7] ))
                                continue
                            for c8 in range(max(c1, c2, c3, c4, c5, c6, c7) + 2):
                                if N == 8:
                                    print((s[c1] + s[c2] + s[c3] + s[c4] + s[c5] + s[c6] + s[c7] + s[c8]))
                                    continue
                                for c9 in range(max(c1, c2, c3, c4, c5, c6, c7, c8) + 2):
                                    if N == 9:
                                        print((s[c1]+s[c2]+s[c3]+s[c4]+s[c5]+s[c6]+s[c7]+s[c8]+s[c9]))
                                        continue
                                    for c10 in range(max(c1, c2, c3, c4, c5, c6, c7, c8, c9) + 2):
                                        print((s[c1]+s[c2]+s[c3]+s[c4]+s[c5]+s[c6]+s[c7]+s[c8]+s[c9]+s[c10]))


# Optimized solution
import sys

def I(): return int(sys.stdin.readline())
def MI(): return list(map(int, sys.stdin.readline().split()))
def LMI(): return list(map(int, sys.stdin.readline().split()))
MOD = 10 ** 9 + 7


s = 'abcdefghijklmnop'
N = I()


def f(n, seq, m):
    for i in range(m + 1):
        if n == N:
            print((seq + s[i]))
        else:
            f(n + 1, seq + s[i], max(m, i + 1))


f(1, '', 0)
# Original solution
n = int(input())
A= 'a'
# 文字数を増やして, その各々の元に対して文字を追加する.
for _ in range(n - 1):
    A = {a + s for a in A for s in a + chr(ord(max(a)) + 1)}
    # print(A)
# 最後にsortして調整する.
#print(*A, sep = '\n')
print(*sorted(A), sep='\n')


# Optimized solution
n = int(eval(input()))
A = ['a']
S = 'abcdefghij'
for _ in range(n-1):
    B = []
    for a in A:
        for s in S[:len(set(a)) + 1]:
            B.append(a + s)
    A = B[::]
print(('\n'.join(A)))
# Original solution
n = int(eval(input()))
A = ['a']
S = 'abcdefghij'
for _ in range(n-1):
    B = []
    for a in A:
        for s in S[:len(set(a)) + 1]:
            B.append(a + s)
    A = B[::]
print(('\n'.join(A)))

# Optimized solution
n = int(eval(input()))
A = ['a']
S = 'abcdefghij'
for _ in range(n-1):
    A = [ a + s for a in A for s in S[:len(set(a)) + 1]]
print(('\n'.join(A)))
# Original solution
n = int(input())
A = 'a'
S ='abcdefghij'
for _ in range(n-1):
    A = [a + s for a in A for s in S[:len(set(a))+1]]
print(*A, sep='\n')


# Optimized solution
n = int(eval(input()))
A = 'a'
S = 'abcdefghij'
for _ in range(n-1):
    A = [ a + s for a in A for s in S[:len(set(a)) + 1]]
print(('\n'.join(A)))
# Original solution
import sys
import time
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.readline
N = int(eval(input()))

groups = []

def dfs(s, n):
    if n == N:
        bits = [-1] * N
        for i, ss in enumerate(s):
            if bits[i] != -1:
                continue
            for ii in range(i+1, N):
                if s[ii] == ss:
                    bits[ii] = i
        if bits not in groups:
            groups.append(bits)
            print(s)
        return
    # for ns in 'abcdefghijklmnopqrstuvwxyz'[:n+1]:
    for ns in 'abcdefghij'[:n+1]:
        dfs(s+ns, n+1)

dfs('', 0)


# Optimized solution
import sys
import time
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.readline
N = int(eval(input()))

def dfs(s, n, m):
    if n > N:
        print((''.join([chr(ss) for ss in s])))
        return True
    for ns in range(97, m+2):
        s[n-1] = ns
        dfs(s, n+1, max(m, ns))

s = [0] * N
dfs(s, 1, 96)
# Original solution
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))

N = INT()

import itertools
import collections

alphabet = 'abcdefghijklmnopqrstuvwxyz'

a_set = set()
for w in itertools.product(list(range(N)), repeat=N):
    # print(w, end=", ")
    seen = {}

    i = 0
    for l in w:
        if l not in list(seen.keys()):
            seen[l] = i
            i += 1

    # print(seen, end="")

    ans = [0] * N

    for i in range(len(ans)):
        ans[i] = seen[w[i]]

    if tuple(ans) not in a_set:
        print(("".join([alphabet[i] for i in ans])))
        a_set.add(tuple(ans))






# Optimized solution
# https://atcoder.jp/contests/panasonic2020/tasks/panasonic2020_d

N = int(eval(input()))

alphabet = "abcdefghijklmnopqrstuvwxyz"

curr_str = []

def print_str(curr_str):
    string = ""
    for i in curr_str:
        string += alphabet[i]
    print(string)


def dfs(index, curr_str, curr_char):
    if curr_char > index:
        return None
    if curr_char > max(curr_str) + 1:
        return None

    if index == N-1:
        print_str(curr_str + [curr_char])
        return None

    for i in range(N):
        dfs(index+1, curr_str+[curr_char], i)


if N == 1:
    print("a")
else:    
    for i in range(N):
        dfs(1, [0], i)
# Original solution
N = int(eval(input()))

a_num = 97

def dfs(s, n): #s: 現在の文字列, n: 残りの文字数, cnt: 現在の文字列の最大の値
    if n == 0:
        print(s)
        return
    for i in range(ord("a"), ord(max(s))+2):
        dfs(s+chr(i), n-1)

dfs("a", N-1)


# Optimized solution
N = int(eval(input()))

a_num = 97

def dfs(s, n, cnt): #s: 現在の文字列, n: 残りの文字数, cnt: 現在の文字列の最大の値
    if n == 0:
        print(s)
        return
    for i in range(cnt+2):
        if i == cnt+1:
            dfs(s+chr(a_num+i), n-1, cnt+1)
        else:
            dfs(s+chr(a_num+i), n-1, cnt)

dfs("a", N-1, 0)
# Original solution
N = int(eval(input()))-1

dic={}
ans=[]
#N=1
dic['a']=1
ans.append('a')

alp = ['a','b','c','d','e','f','g','h','i','j','k']


for i in range(N):
    ans_temp = ans
    dic_temp = dic
    #init for N
    ans = []
    dic={}
    #left a
    for j in ans_temp:
        new_j = 'a'+ j
        ans.append(new_j)
        dic[new_j]=dic_temp[j]
    # right append
    for l in ans_temp:
        num_alp = dic_temp[l]
        for m in range(num_alp+1):
            new_l = l+alp[m]

            if new_l not in ans:
                ans.append(new_l)
                if m==num_alp:
                    dic[new_l]=dic_temp[l]+1
                else:
                    dic[new_l]=dic_temp[l]

        
    
        
        

for i in ans:
    print(i)

# Optimized solution
N = int(eval(input()))-1

dic={}
ans=[]
#N=1
dic['a']=1
ans.append('a')

alp = ['a','b','c','d','e','f','g','h','i','j','k']


for i in range(N):
    ans_temp = ans
    dic_temp = dic
    #init for N
    ans = []
    dic={}
    dic_count={}
    #left a
    for j in ans_temp:
        new_j = 'a'+ j
        ans.append(new_j)
        dic[new_j]=dic_temp[j]
        dic_count[new_j]=1
    # right append
    for l in ans_temp:
        num_alp = dic_temp[l]
        for m in range(num_alp+1):
            new_l = l+alp[m]

            if dic_count.get(new_l) is None:
                ans.append(new_l)
                dic_count[new_j]=1
                if m==num_alp:
                    dic[new_l]=dic_temp[l]+1
                else:
                    dic[new_l]=dic_temp[l]

        
    
        
        

for i in ans:
    print(i)
# Original solution
#
# panasonic2020b d
#
import sys
from io import StringIO
import unittest


class TestClass(unittest.TestCase):
    def assertIO(self, input, output):
        stdout, stdin = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(input)
        resolve()
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, stdin
        self.assertEqual(out, output)

    def test_入力例_1(self):
        input = """1"""
        output = """a"""
        self.assertIO(input, output)

    def test_入力例_2(self):
        input = """2"""
        output = """aa
ab"""
        self.assertIO(input, output)


def resolve():
    global N
    N = int(eval(input()))

    T = []
    func("a", "a", T)

    for t in T:
        print(t)


def func(mw, s, T):
    if len(s) == N:
        T.append(s)
        return

    for i in range(ord(mw)-ord("a")+2):
        mw = max(mw, chr(ord("a")+i))
        ns = s + chr(ord("a")+i)
        func(mw, ns, T)


if __name__ == "__main__":
    # unittest.main()
    resolve()


# Optimized solution
#
# panasonic2020b d
#
import sys
from io import StringIO
import unittest


class TestClass(unittest.TestCase):
    def assertIO(self, input, output):
        stdout, stdin = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(input)
        resolve()
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, stdin
        self.assertEqual(out, output)

    def test_入力例_1(self):
        input = """1"""
        output = """a"""
        self.assertIO(input, output)

    def test_入力例_2(self):
        input = """2"""
        output = """aa
ab"""
        self.assertIO(input, output)


def resolve():
    global N
    N = int(eval(input()))

    dfs("a", "a")


def dfs(mw, s):
    if len(s) == N:
        print(s)
        return

    for i in range(ord(mw)-ord("a")+2):
        mw = max(mw, chr(ord("a")+i))
        ns = s + chr(ord("a")+i)
        dfs(mw, ns)


if __name__ == "__main__":
    # unittest.main()
    resolve()
# Original solution
alps = 'abcdefghijklmnopqrstuvwxyz'
def dfs(last, curr_s, sl, n):
    if len(curr_s) == n:
        sl.append(curr_s)
        return
    for i in range(0,last+2):
        s = curr_s + alps[i]
        dfs( max(last,i), s, sl, n )   


def main():
    n = int(eval(input()))
    sl = []
    dfs(0, 'a', sl, n)
    # print(sl)
    for s in sl:
        print(s)

if __name__ == "__main__":
    main()

# Optimized solution
alps = 'abcdefghijklmnopqrstuvwxyz'

def dfs(last, curr_s, sl, n):
    if len(curr_s) == n:
        sl.append(curr_s)
        return

    for i in range(0,last+2):
        s = curr_s + alps[i]
        dfs(max(last,i), s, sl, n)


def main():
    n = int(eval(input()))
    sl = []
    dfs(0, 'a', sl, n)
    for s in sl: print(s)


if __name__ == "__main__":
    main()
# Original solution
from copy import deepcopy
def f(num,N,S):
    alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t"]
    if N == num:
        S.sort()
        for i in range(len(S)):
            print((S[i]))
        return
    else:
        tmp = []
        length = len(S)
        for i in range(length):
            ttmp = list(S[i])
            ttmp.sort()
            tttmp = alphabet.index(ttmp[-1])
            for j in range(tttmp+2):
                tmp.append(S[i]+alphabet[j])
                    
        S = deepcopy(tmp)
        S.sort()
        f(num+1,N,S)

N = int(eval(input()))
f(1,N,["a"])

# Optimized solution
from copy import deepcopy
def f(num,N,S):
    alphabet = ["a","b","c","d","e","f","g","h","i","j"]
    if N == num:
        for i in range(len(S)):
            print((S[i]))
        return
    else:
        tmp = []
        length = len(S)
        for i in range(length):
            ttmp = sorted(list(S[i]))
            for j in range(alphabet.index(ttmp[-1])+2):
                tmp.append(S[i]+alphabet[j])
        S = sorted(tmp)
        f(num+1,N,S)

N = int(eval(input()))
f(1,N,["a"])
# Original solution
from copy import deepcopy
def f(num,N,S):
    alphabet = ["a","b","c","d","e","f","g","h","i","j"]
    if N == num:
        for i in range(len(S)):
            print((S[i]))
        return
    else:
        tmp = []
        length = len(S)
        for i in range(length):
            ttmp = sorted(list(S[i]))
            for j in range(alphabet.index(ttmp[-1])+2):
                tmp.append(S[i]+alphabet[j])
        S = sorted(tmp)
        f(num+1,N,S)

N = int(eval(input()))
f(1,N,["a"])

# Optimized solution
def f(num,N,S):
    alphabet = ["a","b","c","d","e","f","g","h","i","j"]
    if N == num:
        for i in range(len(S)):
            print((S[i]))
        return
    else:
        tmp = []
        length = len(S)
        for i in range(length):
            ttmp = sorted(list(S[i]))
            for j in range(alphabet.index(ttmp[-1])+2):
                tmp.append(S[i]+alphabet[j])
        S = tmp
        f(num+1,N,S)
 
N = int(eval(input()))
f(1,N,["a"])
# Original solution
def f(num,N,S):
    alphabet = ["a","b","c","d","e","f","g","h","i","j"]
    if N == num:
        for i in S:
          print(i)
        return
    else:
        tmp = []
        length = len(S)
        for i in S:
            ttmp = sorted(list(i))
            for j in range(alphabet.index(ttmp[-1])+2):
                tmp.append(i+alphabet[j])
        f(num+1,N,tmp)
 
N = int(eval(input()))
f(1,N,["a"])

# Optimized solution
def saiki(n,A):

    if n == N:
        A.sort()
        for i in A:
            print(i)
        return

    alpha = list("abcdefghijklmnopqr")

    tmp = []

    for i in A:
        a = alpha.index(sorted(list(i))[-1])
        for j in range(a+2):
            tmp.append(i+alpha[j])
    
    saiki(n+1,tmp)

N = int(eval(input()))

saiki(1,["a"])
# Original solution
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from bisect import bisect_right, bisect_left
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor, gamma, log
from operator import mul
from functools import reduce
from copy import deepcopy

sys.setrecursionlimit(2147483647)
INF = 10 ** 20
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 10 ** 9 + 7


n = I()
L = [[[0]]]
for i in range(1, n):
    new_L = []
    for each_type in L:
        new_L += [each_type + [[i]]]
        for j in range(len(each_type)):
            new_type = deepcopy(each_type)
            new_type[j] += [i]
            new_L += [new_type]
    L = new_L


ans = []
for t in L:
    a = [''] * n
    cnt = 97
    for k in t:
        for l in k:
            a[l] = chr(cnt)
        cnt += 1
    ans += [''.join(a)]


for i in sorted(ans):
    print(i)



# Optimized solution
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from bisect import bisect_right, bisect_left
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor, gamma, log
from operator import mul
from functools import reduce
from copy import deepcopy

sys.setrecursionlimit(2147483647)
INF = 10 ** 20
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 10 ** 9 + 7


n = I()
def f(s, last):
    if len(s) == n:
        print(s)
    else:
        for i in range(97, last + 2):
            f(s + chr(i), last + 1 if i == last + 1 else last)


f('', 96)
# Original solution
n=int(eval(input()))
dic={0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g',7:'h',8:'i',9:'j'} 
#標準形の文字列は同型の文字列の中で辞書順最小であることから、新たに付け加えるべき文字は順にa,b,c...となる
ans=[['a',1]]
for i in range(1,n):
 tmp=[]
 for prev,val in ans:
   for j in range(val+1): 
    #(今見ている文字列に使われている文字の種類数+1)種類の文字を付け加える
     if j!=val: 
        #今見ている文字列に使われている文字を付け加えるとき、文字の種類数は増加しない
       tmp.append([prev+dic[j],val])
     else: 
      #今見ている文字列に使われていない文字を付け加えるとき、文字の種類数が増加する
       tmp.append([prev+dic[j],val+1])
 ans=tmp
ans=sorted(ans,key=lambda x:x[0]) 
#生成した標準形の文字列を辞書順昇順に並べ替える
for i in range(len(ans)):
 print((ans[i][0]))

# Optimized solution
import sys
sys.setrecursionlimit(100000)

def dfs(s, mx):
    if len(s) == N:
        print(s)
        return 0
    for c in range(ord("a"), mx + 2):
        t = s
        t += chr(c)
        dfs(t, max(mx, c))

N = int(eval(input()))
dfs("", ord("a") - 1)
# Original solution
N = int(eval(input()))
al = "abcdefghijklmnopqrstuvwxyz"
atoi = {s:i for i, s in enumerate(al)}
itoa = {i:s for i, s in enumerate(al)}

l = []
def func(s, i):
    if i == N:
        print(s)
        l.append(s)
        return
    # if al[:i] == s:
    #     for c in al[:i+1]:
    #         func(s + c, i+1)
    # else:
    #     for c in al:
    #         func(s + c, i+1 )

    # if i == N - 1:
    maxi = max([atoi[c] for c in s])
    for c in al[:maxi+2]:
        func(s+c, i+1)
    # else:
    #     for c in al[:i+1]:
    #         func(s+c, i+1) 

func("a", 1)



# Optimized solution
N = int(eval(input()))
al = "abcdefghijklmnopqrstuvwxyz"
atoi = {s:i for i, s in enumerate(al)}

def func(s, i):
    if i == N:
        print(s)
        return

    maxi = max([atoi[c] for c in s])
    for c in al[:maxi+2]:
        func(s+c, i+1)

func("a", 1)
# Original solution
# パナソニック2020D
from queue import deque
n = int(eval(input()))
q = deque([("a", "a")])
while True:
    s, m = q.pop()
    if len(s)==n:
        print(s)
    elif len(s)>=n+1:
        break
    for o in range(ord("a"), ord(m)+2):
        if ord(m)<o:
            m = chr(o)
        q.appendleft((s + chr(o), m))

# Optimized solution
# パナソニック2020D
import sys
write = lambda x: sys.stdout.write(x+"\n")
from queue import deque
n = int(eval(input()))
q = deque([("a", "a")])
while True:
    s, m = q.pop()
    if len(s)==n:
        write(s)
    elif len(s)>=n+1:
        break
    for o in range(ord("a"), ord(m)+2):
        if ord(m)<o:
            m = chr(o)
        q.appendleft((s + chr(o), m))