/***************************************************
* Alex Palcuie
* Romania
* alex [dot] palcuie [at] gmail [dot] com
* http://palcu.blogspot.com/
* 2013
****************************************************/
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <bitset>
#include <algorithm>
#include <utility>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iterator>
#include <cstring>
using namespace std;
// Defines
#define NAME(n) #n
#define pr(x) db((x), (#x))
#define prv(v,n) dbv((v), (#v), (n))
#define prw(v) dbw((v), (#v))
#define X first
#define Y second
#define pb push_back
// Helpers
template <typename T>
inline void db(const T x, const char * name){
cerr << name << " = " << x << '\n';
}
template <typename T> inline void dbv(const T * v, const char * name, int n){
fprintf(stderr, "=== %s ===\n", name);
for(int i=0; i<n; i++)
cerr << v[i] << " ";
cerr << '\n';
}
template <typename T> inline void dbs(T x){
cerr << x << ' ';
}
template<typename T>
void dbw(const std::vector<T>& t, const char * name){
fprintf(stderr, "=== %s ===\n", name);
unsigned n = t.size();
for(typename std::vector<T>::size_type i=0; i<n; ++i)
std::cerr << t[i] << ' ';
cerr << '\n';
}
// Constants
const int N = 1<<10;
const int INF = 0x3f3f3f3f;
// Globals
int nNoduri, val[N], sumePartiale[N];
vector<int> v[N];
bool visit[N];
bool nuInPrimulArbore[N];
// Structs
// Functions
int calcSumePartiale(int nod){
int sum = val[nod];
visit[nod] = true;
/*for(int i=0; i<v[nod].size(); i++)
printf("%d ", v[nod][i]);
printf("\n");*/
for(int i=0; i<v[nod].size(); i++){
int newNod = v[nod][i];
if(!visit[newNod]){
//pr(newNod);
sum += calcSumePartiale(newNod);
}
}
sumePartiale[nod] = sum;
return sum;
}
void scadeParinte(int nod, int val, int s[N]){
s[nod] -= val;
for(int i=0; i<v[nod].size(); i++){
int newNod = v[nod][i];
if(newNod < nod && !nuInPrimulArbore[newNod])
scadeParinte(newNod, val, s);
}
}
int solve(int a, int b, int c){
int sums[N], i;
vector<int> sol;
memcpy(sums, sumePartiale, sizeof(sumePartiale));
int k[] = {a, b, c};
for(int j=0; j<3; j++){
int a = k[j];
nuInPrimulArbore[a] = true;
for(i=0; i<v[a].size(); i++)
if(v[a][i] < a)
scadeParinte(v[a][i], sums[a], sums);
}
sol.pb(sums[1]);sol.pb(sums[a]);sol.pb(sums[b]);sol.pb(sums[c]);
vector<int>::iterator myMin = min_element(sol.begin(), sol.end());
vector<int>::iterator myMax = max_element(sol.begin(), sol.end());
return *myMax - *myMin;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("petrica.in","r",stdin);
freopen("petrica.out","w",stdout);
#endif
int i, a, b, j, k;
scanf("%d", &nNoduri);
for(i=0; i<nNoduri; i++) scanf("%d", &val[i+1]);
while(!feof(stdin)){
scanf("%d %d\n", &a, &b);
v[a].pb(b);
v[b].pb(a);
}
calcSumePartiale(1);
//prv(sumePartiale, nNoduri+1);
int sol = INF; nuInPrimulArbore[1] = true;
for(i=2; i<=nNoduri-2; i++)
for(j=i+1; j<=nNoduri-1; j++)
for(k=j+1; k<=nNoduri; k++){
sol = min(sol, solve(i,j,k));
nuInPrimulArbore[i] = nuInPrimulArbore[j] = nuInPrimulArbore[k] = false;
}
printf("%d\n", sol);
return 0;
}