def longest_collatz(ceiling):
    """
    Returns the number below ceiling which produces the longest chain.
    """
    # Trades space for time
    term_lengths = [0, 1]
    for i in range(2, ceiling):
        terms = 1
        while i >= len(term_lengths):
            if i % 2 == 0:
                i = i // 2
            else:
                i = 3 * i + 1
            terms += 1
        term_lengths.append(term_lengths[i] + terms)
    return term_lengths.index(max(term_lengths))