#define _CRT_SECURE_NO_DEPRECATE
#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <memory.h>
#include <set>
#include <ctime>
#include <map>
#include <cstring>
#include <iterator>
#include <queue>
#include <assert.h>
#include <bitset>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <functional>

//#pragma comment(linker, "/STACK:512000000")

using namespace std;

#define pb emplace_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define forn(i, n) for (int i = 0; i < (n); ++i)
#define forab(i, a, b) for (int i = (a); i < (b); ++i)

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int infi = 1e9 + 7;
const ll infl = (ll)1e18 + (ll)7;

ll ar[5010];
ll dp[5010][5010][2];
ll ndp[5010][2];
void upd(ll& a, ll b) {
    a = min(a, b);
}
vector<vector<int> > g;
int dfs(int v, int p = -1) {
    int sz = 1;
    forn(i, 5010)
        dp[v][i][0] = dp[v][i][1] = infl;
    if (ar[v] > 0)
        dp[v][0][0] = ar[v];
    else
        dp[v][0][1] = ar[v];
    for (int to : g[v]) {
        if (to == p)
            continue;
        int cur_sz = dfs(to, v);
        forn(i, cur_sz + sz)
            ndp[i][0] = ndp[i][1] = infl;
        forn(i, cur_sz) {
            int flag = 0;
            if (dp[to][i][0] < infl / 2 || dp[to][i][1] < 0)
                flag = 1;
            ll a = dp[to][i][0];
            ll b = min(dp[to][i][0], dp[to][i][1]);
            forn(j, sz) {
                upd(ndp[i + j][0], a + dp[v][j][0]);
                upd(ndp[i + j][1], b + min(dp[v][j][0], dp[v][j][1]));
                if (flag) {
                    upd(ndp[i + j + 1][0], dp[v][j][0]);
                    upd(ndp[i + j + 1][1], dp[v][j][1]);
                }
            }
        }
        sz += cur_sz;
        forn(i, sz)
            dp[v][i][0] = ndp[i][0], dp[v][i][1] = ndp[i][1];
    }
    return sz;
}

int32_t main() {
    cin.sync_with_stdio(false);
    cin.tie(0);
    //srand(time(NULL));
    //freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
    //freopen("customs.in", "r", stdin); freopen("customs.out", "w", stdout);
    int n;
    cin >> n;
    forn(i, n)
        cin >> ar[i];
    g.resize(n);
    forn(i, n - 1) {
        int u, v;
        cin >> u >> v;
        --u, --v;
        g[u].pb(v);
        g[v].pb(u);
    }
    dfs(0);
    for (int i = 0; i < n; ++i) {
        if (dp[0][i][0] < infl / 2 || dp[0][i][1] < 0) {
            cout << i << '\n';
            return 0;
        }
    }
    assert(0);


    return 0;
}