Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python3
import sys


def solve(N: int):
    alph = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    print("a" * N)
    for i in range(N - 1, 0, -1):
        s = ("a" * i) + "b"
        if i == N - 1:
            print(s)
            continue
        r_len = N - 1 - i
        for j in range((r_len + 1) ** r_len + 1):
            if j == (r_len + 1) ** r_len:
                print(s, end="")
                for l in range(r_len):
                    print(alph[l+2], end="")
                print()
                continue
            nokori = j
            s2 = s
            prev_val = set()
            for k in range(r_len):
                if k == r_len - 1:
                    val = nokori
                else:
                    val = nokori // ((r_len + 1) ** (r_len - k - 1))
                prev_val.add(val)
                nokori = nokori % ((r_len + 1) ** (r_len - k - 1))
                s2 += alph[val]
                if val >= 3 and not val - 1 in prev_val:
                    break
            else:
                print(s2)
    # if N >= 3:
    #     for i in range(N):
    #         print(alph[i], end="")
    #     print()



# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    solve(N)

if __name__ == '__main__':
    main()


Fixed submission:
#!/usr/bin/env python3
import sys


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

def solve(N: int):
    dfs("", 0, N)

def dfs(s: str, mx: int, N: int):
    if len(s) == N:
        print(s) 
    else:
        for i in range(mx + 1):
            dfs(s + ALH[i], mx + 1 if i == mx else mx, N)

# def solve(N: int):
#     alph = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
#     print("a" * N)
#     for i in range(N - 1, 0, -1):
#         s = ("a" * i) + "b"
#         if i == N - 1:
#             print(s)
#             continue
#         r_len = N - 1 - i
#         for j in range((r_len + 1) ** r_len + 1):
#             if j == (r_len + 1) ** r_len:
#                 print(s, end="")
#                 for l in range(r_len):
#                     print(alph[l+2], end="")
#                 print()
#                 continue
#             nokori = j
#             s2 = s
#             prev_val = set()
#             for k in range(r_len):
#                 if k == r_len - 1:
#                     val = nokori
#                 else:
#                     val = nokori // ((r_len + 1) ** (r_len - k - 1))
#                 prev_val.add(val)
#                 nokori = nokori % ((r_len + 1) ** (r_len - k - 1))
#                 s2 += alph[val]
#                 if val >= 3 and not val - 1 in prev_val:
#                     break
#             else:
#                 print(s2)
    # if N >= 3:
    #     for i in range(N):
    #         print(alph[i], end="")
    #     print()



# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    solve(N)

if __name__ == '__main__':
    main()