// Slower C++ solution:
#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

const int maxn=2e5+100;

typedef long long LL;

int n;

LL a[maxn],p[5];



int main(int argc, char const *argv[])

{

    while (scanf("%d",&n)!=EOF)

    {

        memset(a,0,sizeof(a));

        for (int i=1;i<=n;i++)

        {

            scanf("%lld",&a[i]);

            a[i]+=a[i-1];

        }



        LL ans=3e14;

        for (int i=2;i<=n-1;i++)

        {

            int x=lower_bound(a+1,a+i+1,a[i]/2)-a;

            int y=lower_bound(a+1,a+n+1,a[i]+(a[n]-a[i])/2)-a;

            if (x!=1) x--;

            if (y!=i+1) y--;



            p[0]=a[x];

            p[1]=a[i]-a[x];

            p[2]=a[y]-a[i];

            p[3]=a[n]-a[y];

            ans=min(ans,abs(max(p[0],max(p[1],max(p[2],p[3])))-min(p[0],min(p[1],min(p[2],p[3])))));



            int x1=x+1,y1=y;

            p[0]=a[x1];

            p[1]=a[i]-a[x1];

            p[2]=a[y1]-a[i];

            p[3]=a[n]-a[y1];

            ans=min(ans,abs(max(p[0],max(p[1],max(p[2],p[3])))-min(p[0],min(p[1],min(p[2],p[3])))));



            int x2=x,y2=y+1;

            p[0]=a[x2];

            p[1]=a[i]-a[x2];

            p[2]=a[y2]-a[i];

            p[3]=a[n]-a[y2];

            ans=min(ans,abs(max(p[0],max(p[1],max(p[2],p[3])))-min(p[0],min(p[1],min(p[2],p[3])))));



            int x3=x+1,y3=y+1;

            p[0]=a[x3];

            p[1]=a[i]-a[x3];

            p[2]=a[y3]-a[i];

            p[3]=a[n]-a[y3];

            ans=min(ans,abs(max(p[0],max(p[1],max(p[2],p[3])))-min(p[0],min(p[1],min(p[2],p[3])))));

        }

        printf("%lld\n", ans);

    }

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.8153233210763522x):
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>

#include <algorithm>

#include <string>

#include <vector>

#include <stack>

#include <deque>

#include <queue>

#include <list>

#include <limits>

#include <set>

#include <map>

#include <functional>



#include <inttypes.h>

#include <limits.h>

#include <stdint.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>



using namespace std;

typedef long long ll;



#ifndef PRId64

#define PRId64 "lld"

#endif

#ifndef SCNd64

#define SCNd64 "lld"

#endif

#define SC sc()

#define PT pr()

#define FORi(i,b,e) for (int i = (b), _ = (e); i < _; ++i)

#define FORe(i,b,e) for (int i = (b), _ = (e); i <= _; ++i)

#define FORre(i,b,e) for (int i = (b), _ = (e); i >= _; --i)



static int sc_ret = 0;

struct sc

{

    sc& operator()(char& v) { v = sc_ret = getchar(); return *this; }

    sc& operator()(int& v) { sc_ret = scanf("%d", &v); return *this; }

    sc& operator()(unsigned& v) { sc_ret = scanf("%u", &v); return *this; }

    sc& operator()(double& v) { sc_ret = scanf("%lf", &v); return *this; }

    sc& operator()(char* v) { sc_ret = scanf("%s", v); return *this; }

    sc& operator()(string& v) { sc_ret = (bool)(cin >> v); return *this; }

    sc& operator()(ll& v) { sc_ret = scanf("%" SCNd64, &v); return *this; }

    sc& ch(char& v) { sc_ret = scanf(" %c", &v); return *this; }

    sc& gets(char* v) { sc_ret = fgets(v, INT_MAX, stdin) != 0; v[strlen(v) - 1] = 0; return *this; }

    operator bool() const { return sc_ret > 0; }

    void read(int& v)

    {

        int x = 0, k = 1;

        char c = getchar();

        while (c < '0' || c > '9')

        {

            if (c == '-') k = -1;

            c = getchar();

        }

        while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c - 48), c = getchar();

        v = x * k;

    }

};

struct pr

{

    pr& ln() { putchar('\n'); return *this; }

    pr& operator()(char v) { putchar(v); return *this; }

    pr& operator()(int v) { printf("%d", v); return *this; }

    pr& operator()(double v) { printf("%.2f", v); return *this; }

    pr& operator()(const char* fmt, double v) { printf(fmt, v); return *this; }

    pr& operator()(const char* v) { printf("%s", v);return *this; }

    pr& operator()(string v) { printf("%s", v.c_str());return *this; }

    pr& operator()(ll v) { printf("%" PRId64, v);return *this; }



    void write(int v)

    {

        int cnt = 0; char c[15];

        if (v == 0)

        {

            putchar('0');

            return;

        }

        if (v < 0) putchar('-'), v = -v;

        while (v) c[++cnt] = (v % 10) + 48, v /= 10;

        while (cnt > 0) putchar(c[cnt--]);

    }

    template <typename T>

    void ln(T* arr, int size)

    {

        if (size > 0)

        {

            (*this)(arr[0]);

            for (int i = 1; i < size; ++i)

            {

                putchar(' ');

                (*this)(arr[i]);

            }

            putchar('\n');

        }

    }



    template <typename T>

    void muln(T* arr, int size)

    {

        for (int i = 0; i < size; ++i)

        {

            (*this)(arr[i]);

            putchar('\n');

        }

    }

};



const int inf = 0x3f3f3f3f;

const int mod = 1000000007;

const int maxn = 200000 + 10;

const int maxm = 100000 + 10;



ll a[maxn];



inline void getlr(int n, int m, int& l, int& r)

{

    l = (int)(lower_bound(a + 1, a + m - 1, a[m] / 2) - a);

    if (l > 1 && min(a[l], a[m] - a[l]) < min(a[l - 1], a[m] - a[l - 1])) --l;

    r = (int)(lower_bound(a + m + 1, a + n, (a[n] - a[m]) / 2 + a[m]) - a);

    if (r > m + 1 && min(a[r] - a[m], a[n] - a[r]) < min(a[r - 1] - a[m], a[n] - a[r - 1])) --r;

}



/*

10

1 1 1 1 1 1 1 1 2 9

*/

int main()

{

    int n, t, k;

    SC(n);

    FORe(i, 1, n)

    {

        int v;

        SC.read(v);

        a[i] = v + a[i - 1];

    }

    int ml = 2, mr = n - 2;

    for (int m = (ml + mr) / 2, cnt = 0; ml < mr - 1; )

    {

        int l, r;

        getlr(n, m, l, r);

        ll minl = min(a[l], a[m] - a[l]);

        ll minr = min(a[r] - a[m], a[n] - a[r]);

        ll maxl = max(a[l], a[m] - a[l]);

        ll maxr = max(a[r] - a[m], a[n] - a[r]);

        if (minl == minr && maxl == maxr)

        {

            ml = mr = m;

            break;

        }

        if (minl <= minr && maxl <= maxr)

        {

            ml = m;

            cnt = 0;

        }

        else if (minl >= minr && maxl >= maxr)

        {

            mr = m;

            cnt = 0;

        }

        else

        {

            if (++cnt > 10)

                break;

        }

        m = ml + ((mr - ml - 3) > 0 ?

            rand() % (mr - ml - 3) + 2

            : 1);

    }



    int l = 1, r = 3; ll ret = a[n];

    int c = max(2, (int)(lower_bound(a + 1, a + n, a[n] / 2) - a));

    //if (mr - ml > 100000)

    //{

    //    return 0;

    //}

    getlr(n, ml, l, r);

    FORe(i, ml, mr)

    {

        for (; l < i - 1; ++l)

        {

            if (min(a[l], a[i] - a[l]) >= min(a[l + 1], a[i] - a[l + 1]))

                break;

        }

        for (; r < n - 1; ++r)

        {

            if (min(a[r] - a[i], a[n] - a[r]) >= min(a[r + 1] - a[i], a[n] - a[r + 1]))

                break;

        }

        ret = min(ret, max(max(a[r] - a[i], a[n] - a[r]), max(a[l], a[i] - a[l]))

            - min(min(a[l], a[i] - a[l]), min(a[r] - a[i], a[n] - a[r])));

    }

    PT(ret);

    return 0;

}