#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

using tpl = tuple<ll, ll, ll>;
typedef pair<ll,ll> pii;
const ll INF = 1LL << 60;

void fastStream(){cin.tie(0);std::ios_base::sync_with_stdio(0);}

// TODO dpの値は-INFを初期値とする

ll rec1(int, int);
ll rec2(int, int);
ll rec1_sub(int, int, int, int, int);
ll rec2_sub(int, int, int, int, int);

ll N;
ll A[5010];
vector<pii> G[5010];
vector<pii> Gsub[5010];

// dp1[a][b] => ノードa以下をb本のケーブルを切って構成するとき、
// 条件を満たし、aの存在する連結成分の値がすべて正であるときの和の最小値
ll dp1[5010][5010]; 
// dp1_sub[a][b] => edge a以降を使う場合の、dp1と同じ条件を満たすような、構成要素の和の最小値
ll dp1_sub[5010][5010];

// dp2[a][b] => ノードa以下をb本のケーブルを切って構成するとき、
// 条件を満たし、aの存在する連結成分の値の和の最小値
ll dp2[5010][5010]; 
// dp2_sub[a][b] => edge a以降を使う場合の、dp2と同じ条件を満たすような、構成要素の和の最小値
ll dp2_sub[5010][5010];
int des[5010];

ll rec1(int pos, int k){
    if(dp1[pos][k] > -INF) return dp1[pos][k];
    // cout << "rec1 " << pos << " " << k << " " << des[pos] << endl;
    ll res = 0;
    if(des[pos] == 1){
        if(k == 0 && A[pos] > 0) res = A[pos];
        else res = INF;
    }
    else if(A[pos] < 0){
        res = INF;
    }
    else{
        int e_id = G[pos][0].second;
        res = rec1_sub(e_id, pos, 0, des[pos] - 1, k);
        if(res != INF) res = res + A[pos];
    }
    return dp1[pos][k] = res;
}

ll rec1_sub(int e_id, int pos, int e_num, int left_des, int k){
    if(dp1_sub[e_id][k] > -INF) return dp1_sub[e_id][k];
    ll res = INF;
    int to = G[pos][e_num].first;
    // cout << "rec1_sub" << " " << pos << " " << to << " " << left_des << " " << k << endl;
    int r_des = left_des - des[to];
    // e_idのエッジを切り離す処理
    for(int l_k = max(0, k - r_des); l_k <= min(k, des[to]); l_k++){
        int r_k = k - l_k;
        // if(r_k > r_des) continue;
        // 左を切り離す or そのまま使う
        ll l_res = INF;
        {
            // 切らない
            if(l_k != des[to]){
                l_res = rec1(to, l_k);
            }
            // 切り離す
            if(l_k > 0 && (rec1(to, l_k - 1) != INF || rec2(to, l_k - 1) < 0)){
                l_res = 0;
            }
        }
        ll r_res = 0;
        if(e_num != (int)G[pos].size() - 1){
            r_res = rec1_sub(G[pos][e_num + 1].second, pos, e_num + 1, left_des - des[to], r_k);
        }
        // cout << l_res << " " << r_res << endl;
        res = min(res, l_res + r_res);
    }
    return dp1_sub[e_id][k] = res;
}


ll rec2(int pos, int k){
    if(dp2[pos][k] > -INF) return dp2[pos][k];
    // cout << "rec2 " << pos << " " << k << " " << des[pos] << endl;
    ll res = 0;
    if(des[pos] == 1){
        if(k == 0) res = A[pos];
        else res = INF;
    }
    else{
        int e_id = G[pos][0].second;
        res = rec2_sub(e_id, pos, 0, des[pos] - 1, k);
        if(res != INF) res = res + A[pos];
    }
    return dp2[pos][k] = res;
}


ll rec2_sub(int e_id, int pos, int e_num, int left_des, int k){
    if(dp2_sub[e_id][k] > -INF) return dp2_sub[e_id][k];
    ll res = INF;
    int to = G[pos][e_num].first;
    int r_des = left_des - des[to];
    // cout << "rec2_sub" << " " << pos << " " << to << " " << left_des << " " << k << endl;
    // r_k <= r_desを満たすl_kから始める
    for(int l_k = max(0, k - r_des); l_k <= min(k, des[to]); l_k++){
        int r_k = k - l_k; 
        // if(r_k > r_des) continue;
        // 左を切り離す or そのまま使う
        ll l_res = INF;
        {
            // 切らない
            if(l_k != des[to]){
                l_res = rec2(to, l_k);
            }
            // 切り離す
            if(l_k > 0 && (rec1(to, l_k - 1) != INF || rec2(to, l_k - 1) < 0)){
                l_res = min(l_res, 0LL);
            }
        }
        ll r_res = 0;
        if(e_num != (int)G[pos].size() - 1){
            r_res = rec2_sub(G[pos][e_num + 1].second, pos, e_num + 1, left_des - des[to], r_k);
        }
        if(l_res != INF && r_res != INF)
            res = min(res, l_res + r_res);
    }
    return dp2_sub[e_id][k] = res;
}


int des_cnt(int pos, int par){
    int cnt = 1;
    for(pii p : Gsub[pos]){
        int to = p.first;
        if(to == par) continue;
        G[pos].push_back(p);
        cnt += des_cnt(to, pos);
    }
    return des[pos] = cnt;
}

int main(){

    cin >> N;
    for(ll i = 0; i < N; i++) cin >> A[i];
    for(ll i = 0; i < N - 1; i++){
        ll u, v;
        cin >> u >> v;
        u--; v--;
        Gsub[u].push_back(pii(v, i));
        Gsub[v].push_back(pii(u, i));
    }

    for(int i = 0; i < 5010; i++)
        for(int j = 0; j < 5010; j++)
            dp1[i][j] = dp2[i][j] = dp1_sub[i][j] = dp2_sub[i][j] = -INF;

    des_cnt(0, -1);


    for(int i = 0; i < N; i++){
        bool ok = false;
        if(rec1(0, i) != INF) ok = true;
        if(rec2(0, i) < 0) ok = true;
        if(ok){
            cout << i << endl;
            break;
        }
    }

    return 0;
}


Measured memory_bytes: 786176