#include <bits/stdc++.h> 

using namespace std;

#define fcout(d) cout << fixed << setprecision(d)
#define rep(i,n) for(int (i) = 0; (i) < (n); ++(i))
#define rep1(i,n) for(int (i) = 1; (i) <= (n); ++(i))
#define repU(i,bottom,ceiling) for(int (i) = (bottom); (i) <= (ceiling); ++(i))
#define repD(i,ceiling,bottom) for(int (i) = (ceiling); (i) >= (bottom); --(i))
#define pub push_back
#define pob pop_back
#define prf printf
#define scf scanf
#define mkp make_pair
#define fir first
#define sec second
#define clr(a) memset((a),0,sizeof(a))
#define all(a)  begin((a)),end((a))

typedef long long ll;
typedef unsigned long long ull;
typedef double db;

const vector<pair<int,int>> DIR = { {1,0},{0,1},{-1,0},{0,-1},{1,1},{-1,1},{-1,-1},{1,-1} };
const int INF = -1 + (1<<30);
const int MOD = (int)1e9 + 7;

template<typename T> inline T gcd(T a,T b){ if(a % b){ return gcd(b,a % b); }else{ return b; } }

template<typename T> inline T lcm(T a,T b){ return a / gcd(a,b) * b; }

inline long long Pow(const long long n,long long m,const int mod = MOD){
	long long res = 1,pow = n;
	while(m) {
		if(m & 1) res = (res * pow) % mod;
		pow = (pow * pow) % mod;
		m >>= 1;
	}
	return res;
}

inline vector<long long> Frac(const int range,const int mod = MOD){
	vector<long long> frac;
	frac.push_back(1);
	for(int i = 1; i <= range; ++i) frac.push_back((long long)frac.back() * i % mod);
	return frac;
}

inline long long Comb(const int n,const int m,const int mod = MOD){
	if(n < m || m < 0) return 0;
	vector<long long> frac(Frac(n,mod));
	long long rev = Pow((long long)frac[m] * frac[n-m] % mod,mod-2,mod);
	return rev * frac[n] % mod;
}

template<typename T> inline bool v_find(const vector<T> v,const T obj){
	auto itr = find(v.begin(), v.end(), obj);
	size_t index = distance(v.begin(),itr);
	if (index != v.size()) { return true; }
	return false; 
}

template<typename T> inline bool v_erase(vector<T> &v,const T obj){
	auto itr = find(v.begin(), v.end(), obj);
	size_t index = distance(v.begin(),itr);
	if (index != v.size()) {
		v.erase(itr);
		return true;
	}
	return false;	
}

template<class T,class U> inline auto LB(const T v,const U in){ return lower_bound(v.begin(),v.end(),in); }

template<class T,class U> inline auto UB(const T v,const U in){ return upper_bound(v.begin(),v.end(),in); }

inline unsigned long long next_subset(unsigned long long subset){
	unsigned long long tem = subset + (subset & -subset);
	unsigned long long btm = (~tem & subset) / (subset & -subset) >> 1;
	return btm | tem;
}

ll n,a,s[200005]={};

//区間(l,r]における二分探索
int midsearch_1(int i,float obj){
	int upper = i; 
	int lower = 0;
	while(upper-lower > 1){
		int mid = (upper+lower)/2;
		if(s[i]-s[mid] > s[mid]) lower = mid;
		else upper = mid;
	}
	return upper;
}

int midsearch_2(int i,float obj){
	int upper = n; 
	int lower = i;
	while(upper-lower > 1){
		int mid = (upper+lower)/2;
		if(s[mid]-s[i] < s[n]-s[mid]) lower = mid;
		else upper = mid;
	}
	return upper;
}

inline void solve(){
	ll ans = 2e18,m,M;
	cin>>n;
	s[0]=0;
	rep(i,n){ cin>>a; s[i+1] = s[i]+a; }
	repU(i,2,n-2){
		int l = midsearch_1(i,(float)s[i]/2);
		int r = midsearch_2(i,(float)(s[n]+s[i+1])/2);
		rep(j,2)rep(k,2){
			M = max(max(s[l-j],s[i]-s[l-j]),max(s[r-k]-s[i],s[n]-s[r-k]));
			m = min(min(s[l-j],s[i]-s[l-j]),min(s[r-k]-s[i],s[n]-s[r-k]));
			ans = min(ans,M-m);
		}
	}
	cout<<ans<<endl;
	return;
}

inline void input(){
	return;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	input();
	solve();
	return 0;
}





Measured memory_bytes: 1792