# Original solution
# -*- coding: utf-8 -*-
def two_pointers(ary, l, r, split, ary_func, comb_func, comp_func):
    '''
    This function is supposed to be repeatedly called so that 'split' keeps
    renewing, under an assumption that 'split' increases monotonously.
    ('l' and 'r' just specify the region to be searched in 'ary')
    '''

    left = ary_func(ary, l, split)
    right = ary_func(ary, split, r)
    val = comb_func(left, right)

    for i in range(split + 1, r):
        tmp_left = ary_func(ary, l, i)
        tmp_right = ary_func(ary, i, r)
        tmp_val = comb_func(tmp_left, tmp_right)

        if comp_func(val, tmp_val):
            return i - 1, val, left, right
        else:
            left = tmp_left
            right = tmp_right
            val = tmp_val

    else:
        return r - 1, val, left, right


if __name__ == '__main__':
    from operator import add
    from itertools import accumulate

    n = int(eval(input()))
    a = [int(_) for _ in input().split()]
    cul_ary = [0] + list(accumulate(a, add))

    l_split = 1
    r_split = 3
    griefs = []
    for i in range(2, n - 1):
        # left
        l_split, l_diff, p, q = two_pointers(cul_ary,
                                             0,
                                             i,
                                             l_split,
                                             lambda ary, l, r: ary[r] - ary[l],
                                             lambda left, right: abs(left - right),
                                             lambda val1, val2: True if val1 < val2 else False)

        # right
        r_split, r_diff, r, s = two_pointers(cul_ary,
                                             i,
                                             n,
                                             r_split,
                                             lambda ary, l, r: ary[r] - ary[l],
                                             lambda left, right: abs(left - right),
                                             lambda val1, val2: True if val1 < val2 else False)

        griefs.append(max(p, q, r, s) - min(p, q, r, s))

    print((min(griefs)))


# Optimized solution
# -*- coding: utf-8 -*-
def two_pointers(ary, l, r, split, ary_func, comb_func, comp_func):
    '''
    This function is supposed to be repeatedly called so that 'split' keeps
    renewing, under an assumption that 'split' increases monotonously.
    ('l' and 'r' just specify the region to be searched in 'ary')
    '''

    left = ary_func(ary, l, split)
    right = ary_func(ary, split, r)
    val = comb_func(left, right)

    for i in range(split + 1, r):
        tmp_left = ary_func(ary, l, i)
        tmp_right = ary_func(ary, i, r)
        tmp_val = comb_func(tmp_left, tmp_right)

        if comp_func(val, tmp_val):
            return i - 1, val, left, right
        else:
            left = tmp_left
            right = tmp_right
            val = tmp_val

    else:
        return r - 1, val, left, right


if __name__ == '__main__':
    '''
    an example of using this function
    At-Coder ABC 102 - D
    '''

    from operator import add
    from itertools import accumulate

    n = int(eval(input()))
    a = [int(_) for _ in input().split()]
    cul_ary = [0] + list(accumulate(a, add))

    l_split = 1
    r_split = 3
    funcs = (lambda ary, l, r: ary[r] - ary[l],
             lambda left, right: abs(left - right),
             lambda val1, val2: True if val1 < val2 else False)
    griefs = []
    for i in range(2, n - 1):
        # left
        l_split, l_diff, p, q = two_pointers(cul_ary, 0, i, l_split, *funcs)

        # right
        r_split, r_diff, r, s = two_pointers(cul_ary, i, n, r_split, *funcs)

        griefs.append(max(p, q, r, s) - min(p, q, r, s))

    print((min(griefs)))