#include <bits/stdc++.h>
#define FOR(i, begin, end) for(int i=(begin);i<(end);i++)
#define REP(i, n) FOR(i,0,n)
#define IFOR(i, begin, end) for(int i=(end)-1;i>=(begin);i--)
#define IREP(i, n) IFOR(i,0,n)
#define SORT(a) sort(a.begin(), a.end())
#define REVERSE(a) reverse(a.begin(), a.end())
#define Lower_bound(v, x) distance(v.begin(), lower_bound(v.begin(), v.end(), x))
#define Upper_bound(v, x) distance(v.begin(), upper_bound(v.begin(), v.end(), x))
#define int long long
#define INF 1000000000000000000
using namespace std;

#define ANS(f) if(f) cout << "YES" << endl; else cout << "NO" << endl;

typedef vector<int> vec;
typedef vector<vec> mat;
typedef pair<int, int> Pii;

template<typename T>
void readv(vector<T> &a){ REP(i, a.size()) cin >> a[i]; }
void readi(vector<int> &a){ REP(i, a.size()){cin >> a[i]; a[i]--;} }
void debug(mat m){REP(i, m.size()){ REP(j, m[i].size()){ cout << m[i][j] << ","; } cout << endl; }}

struct edge{int to, cost;};

class Graph
{
public:
    int V;
    vector<vector<edge>> G;
    vector<mat> dp;
    vec sz;

    Graph(int V): V(V){
        G = vector<vector<edge>>(V, vector<edge>(0));
        dp = vector<mat>(V);
        sz = vec(V, 1);
    }

    void add_edge(int from, int to, int cost){
        G[from].push_back(edge({to, cost}));
    }

    void add_edge2(int v1, int v2, int cost){
        add_edge(v1, v2, cost);
        add_edge(v2, v1, cost);
    }

    void dfs(int v, vec &A, int par){
        vec chi(0);
        REP(k, G[v].size()){
            if(G[v][k].to != par){
                chi.push_back(G[v][k].to);
                dfs(G[v][k].to, A, v);
            }
        }
        vector<mat> dq(chi.size() + 1);
        dq[0] = mat(2, vec(1, INF));
        if(A[v] > 0) dq[0][0][0] = A[v];
        else dq[0][1][0] = A[v];

        REP(i, chi.size()){
            int c = chi[i];
            dq[i + 1] = mat(2, vec(sz[v] + sz[c], INF));
            
            int m = INF;
            REP(j, sz[c]){
                if(dp[c][0][j] < INF || dp[c][1][j] < 0){
                    m = j;
                    break;
                }
            }
            if(m < INF){
                REP(j, sz[v]){
                    dq[i + 1][0][j + m + 1] = dq[i][0][j];
                    dq[i + 1][1][j + m + 1] = dq[i][1][j];
                }
            }

            REP(j, sz[c]) REP(k, sz[v]){
                if(dp[c][0][j] < INF && dq[i][0][k] < INF) dq[i + 1][0][j + k] = min(dq[i + 1][0][j + k], dp[c][0][j] + dq[i][0][k]);
                if(dp[c][1][j] < INF && dq[i][1][k] < INF) dq[i + 1][1][j + k] = min(dq[i + 1][1][j + k], dp[c][1][j] + dq[i][1][k]);
                if(dp[c][0][j] < INF && dq[i][1][k] < INF) dq[i + 1][1][j + k] = min(dq[i + 1][1][j + k], dp[c][0][j] + dq[i][1][k]);
                if(dp[c][1][j] < INF && dq[i][0][k] < INF) dq[i + 1][1][j + k] = min(dq[i + 1][1][j + k], dp[c][1][j] + dq[i][0][k]);
            }

            sz[v] += sz[c];
        }

        dp[v] = dq[chi.size()];
    }

};

signed main(){

    int N; cin >> N;
    Graph T(N);
    vec A(N); readv(A);
    int U, V;
    REP(i, N - 1){
        cin >> U >> V;
        T.add_edge2(U - 1, V - 1, 0);
    }
    T.dfs(0, A, -1);
    int ans = INF;
    REP(i, N){
        if(T.dp[0][0][i] < INF || T.dp[0][1][i] < 0){
            ans = i;
            break;
        }
    }
    cout << ans;
    
    return 0;
}

Measured memory_bytes: 245888