#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <limits>
using namespace std;
const int infinit = std::numeric_limits<int>::max();
int sumaMaxima = -infinit;
int sumaMaximaSubarbore(int nodCurent, vector<bool> &vizitate, const vector<int>& costuri, const vector<vector<int>>& listaAdiacenta){
vizitate[nodCurent] = true;
int sumaCurenta = costuri[nodCurent];
for(auto vecin : listaAdiacenta[nodCurent]){
if(!vizitate[vecin]){
int sumaSubarbore = sumaMaximaSubarbore(vecin, vizitate, costuri, listaAdiacenta);
// daca suma subarborelui este pozitiva, o adaugam la suma curenta
if(sumaSubarbore > 0){
sumaCurenta += sumaSubarbore;
}
}
}
sumaMaxima = max(sumaCurenta, sumaMaxima);
return sumaCurenta;
}
int main() {
ifstream in("asmax.in");
ofstream out("asmax.out");
int noduri, extremitateInitiala, extremitateFinala, apelFunctie;
in >> noduri;
vector<vector<int>> listaAdiacenta (noduri + 1, vector<int>());
vector<int> costuriVarfuri(noduri + 1);
for(int i = 1; i <= noduri; i++){
in >> costuriVarfuri[i];
}
for(int i = 0; i < noduri - 1; i++){
in >> extremitateInitiala >> extremitateFinala;
listaAdiacenta[extremitateInitiala].push_back(extremitateFinala);
listaAdiacenta[extremitateFinala].push_back(extremitateInitiala);
}
vector<bool> vizitate(noduri + 1, false);
apelFunctie = sumaMaximaSubarbore(1, vizitate, costuriVarfuri, listaAdiacenta);
out << sumaMaxima;
in.close();
out.close();
return 0;
}