Buggy python submission (verdict: Runtime Error):
import sys

sys.setrecursionlimit(1000000)

max_comb = None
max_value = 0


def memorize(c, value, memo, a):
    global max_comb
    global max_value

    memo[c] = value

    # for answer
    if c[0] != c[1] and \
            c[0] in a and \
            c[1] in a and \
            max_value < memo[c]:
        max_value = memo[c]
        max_comb = c


def comb(a_i, a_j, memo, a):
    c = (a_i, a_j)
    # print(a_i, a_j)

    if c in memo:
        return memo[c]

    if a_j == 1:
        memorize(c, a_i, memo, a)
        return a_i

    if a_i == a_j or a_j == 0:
        memorize(c, 1, memo, a)
        return 1

    value = comb(a_i - 1, a_j, memo, a) + comb(a_i - 1, a_j - 1, memo, a)
    memorize(c, value, memo, a)
    return memo[c]


if __name__ == '__main__':
    n = int(input())
    a = list(map(int, input().split()))

    # n = 5
    # a = [6, 9, 4, 2, 11]

    # find 1st, 2nd
    # max_a, second_max_a = -1, -2
    # for a_i in a:
    #     if max_a < a_i:
    #         second_max_a = max_a
    #         max_a = a_i
    #     elif second_max_a < a_i:
    #         second_max_a = a_i

    max_a = max(a)
    memo = dict()

    for a_i in a:
        if max_a != a_i:
            comb(max_a, a_i, memo, a)
            # comb(max_a, second_max_a, memo, a)
    #
    # for i in range(n - 1):
    #     for j in range(i + 1, n):
    #         comb(a_sorted[i], a_sorted[j], memo, a)
    #
    #         # print("comb:", a_sorted[i], a_sorted[j])

    print(max_comb[0], max_comb[1])


Fixed submission:
if __name__ == '__main__':
    n = int(input())
    a = list(map(int, input().split()))

    # n = 5
    # a = [6, 9, 4, 2, 11]

    max_a = max(a)
    max_half = max_a / 2

    best_a_j = a[0] if a[0] != max_a else a[1]
    min_d = max_half
    for a_j in a:
        if a_j == max_a:
            continue

        d = abs(a_j - max_half)
        if d < min_d:
            best_a_j = a_j
            min_d = d

    print(max_a, best_a_j)

Buggy python submission (verdict: Time Limit Exceeded):
import sys

sys.setrecursionlimit(1000000)

max_comb = None
max_value = 0


def memorize(c, value, memo):
    global max_comb
    global max_value

    memo[c] = value
    if max_value < memo[c]:
        max_value = memo[c]
        max_comb = c


def comb(a_i, a_j, memo):
    c = (a_i, a_j)
    # print(a_i, a_j)

    if c in memo:
        return memo[c]

    if a_j == 1:
        memorize(c, a_i, memo)
        return a_i

    if a_i == a_j or a_j == 0:
        memorize(c, 1, memo)
        return 1

    value = comb(a_i - 1, a_j, memo) + comb(a_i - 1, a_j - 1, memo)
    memorize(c, value, memo)
    return memo[c]


if __name__ == '__main__':
    n = int(input())
    a = list(map(int, input().split()))

    # n = 5
    # a = [6, 9, 4, 2, 11]
    a_sorted = sorted(a, reverse=True)

    memo = dict()
    for i in range(n - 1):
        for j in range(i + 1, n):
            comb(a_sorted[i], a_sorted[j], memo)

            # print("comb:", a_sorted[i], a_sorted[j])

    print(max_comb[0], max_comb[1])


Fixed submission:
if __name__ == '__main__':
    n = int(input())
    a = list(map(int, input().split()))

    # n = 5
    # a = [6, 9, 4, 2, 11]

    max_a = max(a)
    max_half = max_a / 2

    best_a_j = a[0] if a[0] != max_a else a[1]
    min_d = max_half
    for a_j in a:
        if a_j == max_a:
            continue

        d = abs(a_j - max_half)
        if d < min_d:
            best_a_j = a_j
            min_d = d

    print(max_a, best_a_j)

Buggy python submission (verdict: Runtime Error):
import sys

sys.setrecursionlimit(100000 + 2)

max_comb = None
max_value = 0


def memorize(c, value, memo):
    global max_comb
    global max_value

    memo[c] = value
    if max_value < memo[c]:
        max_value = memo[c]
        max_comb = c


def comb(a_i, a_j, memo):
    c = (a_i, a_j)
    # print(a_i, a_j)

    if c in memo:
        return memo[c]

    if a_j == 1:
        memorize(c, a_i, memo)
        return a_i

    if a_i == a_j or a_j == 0:
        memorize(c, 1, memo)
        return 1

    value = comb(a_i - 1, a_j, memo) + comb(a_i - 1, a_j - 1, memo)
    memorize(c, value, memo)
    return memo[c]


if __name__ == '__main__':
    n = int(input())
    a = list(map(int, input().split()))

    # n = 5
    # a = [6, 9, 4, 2, 11]
    a_sorted = sorted(a, reverse=True)

    memo = dict()
    for i in range(n - 1):
        for j in range(i + 1, n):
            comb(a_sorted[i], a_sorted[j], memo)

            # print("comb:", a_sorted[i], a_sorted[j])

    print(max_comb[0], max_comb[1])


Fixed submission:
if __name__ == '__main__':
    n = int(input())
    a = list(map(int, input().split()))

    # n = 5
    # a = [6, 9, 4, 2, 11]

    max_a = max(a)
    max_half = max_a / 2

    best_a_j = a[0] if a[0] != max_a else a[1]
    min_d = max_half
    for a_j in a:
        if a_j == max_a:
            continue

        d = abs(a_j - max_half)
        if d < min_d:
            best_a_j = a_j
            min_d = d

    print(max_a, best_a_j)