import sys

sys.setrecursionlimit(10 ** 6)





N = int(input())

ans = set()

a = ord('a')





def f(c, A, done):

    global N, a

    B = list(A)

    done = set(done)

    for i in range(N):

        if i not in done:

            B[i] = c

            done.add(i)

            break

    if len(done) == N:

        ans.add(''.join(B))

    else:

        for i in range(2 ** (N - len(done)) - 1, -1, -1):

            k = i

            C = B[:]

            tDone = set(x for x in range(N))

            nDone = set(x for x in done)

            for t in done:

                tDone.remove(t)

            while k > 0:

                y = min(tDone)

                if k & 1 == 1:

                    C[y] = c

                    nDone.add(y)

                tDone.remove(y)

                k >>= 1

            f(chr(ord(c) + 1), tuple(C), tuple(nDone))





A = [0] * N

f('a', tuple(A), ())

ans = list(ans)

ans.sort()

print(*ans, sep='\n')

import sys

sys.setrecursionlimit(10 ** 6)





N = int(input())

ans = []

a = ord('a')





def dfs(S, mx):

    global N

    if len(S) == N:

        ans.append(S)

    else:

        for c in range(0, mx + 2):

            dfs(S + chr(c + a), max(mx, c))





dfs('a', 0)

print(*ans, sep='\n')

import sys

sys.setrecursionlimit(10**6)
N = int(input())
ans = set()
a = ord("a")


def f(c, A, done):
    global N, a
    B = list(A)
    done = set(done)
    for i in range(N):
        if i not in done:
            B[i] = c
            done.add(i)
            break
    if len(done) == N:
        ans.add("".join(B))
    else:
        for i in range(2 ** (N - len(done)) - 1, -1, -1):
            k = i
            C = B[:]
            tDone = set(x for x in range(N))
            nDone = set(x for x in done)
            for t in done:
                tDone.remove(t)
            while k > 0:
                y = min(tDone)
                if k & 1 == 1:
                    C[y] = c
                    nDone.add(y)
                tDone.remove(y)
                k >>= 1
            f(chr(ord(c) + 1), tuple(C), tuple(nDone))


A = [0] * N
f("a", tuple(A), ())
ans = list(ans)
ans.sort()
print(*ans, sep="\n")

import sys

sys.setrecursionlimit(10**6)
N = int(input())
ans = []
a = ord("a")


def dfs(S, mx):
    global N
    if len(S) == N:
        ans.append(S)
    else:
        for c in range(0, mx + 2):
            dfs(S + chr(c + a), max(mx, c))


dfs("a", 0)
print(*ans, sep="\n")

-ans = set() +ans = [] -def f(c, A, done): -    global N, a -    B = list(A) -    done = set(done) -    for i in range(N): -        if i not in done: -            B[i] = c -            done.add(i) -            break -    if len(done) == N: -        ans.add("".join(B)) +def dfs(S, mx): +    global N +    if len(S) == N: +        ans.append(S) -        for i in range(2 ** (N - len(done)) - 1, -1, -1): -            k = i -            C = B[:] -            tDone = set(x for x in range(N)) -            nDone = set(x for x in done) -            for t in done: -                tDone.remove(t) -            while k > 0: -                y = min(tDone) -                if k & 1 == 1: -                    C[y] = c -                    nDone.add(y) -                tDone.remove(y) -                k >>= 1 -            f(chr(ord(c) + 1), tuple(C), tuple(nDone)) +        for c in range(0, mx + 2): +            dfs(S + chr(c + a), max(mx, c)) -A = [0] * N -f("a", tuple(A), ()) -ans = list(ans) -ans.sort() +dfs("a", 0)