#include <bits/stdc++.h>
#include <ostream>

using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

const ll INF = TEN(18);

int n;
V<ll> a;
VV<int> g;

using P = pair<ll, ll>;
V<P> dfs(int p, int b) {
    V<P> dp = {{0, INF}};
    for (int d: g[p]) {
        if (d == b) continue;
        auto ndp = dfs(d, p);
        int k = int(ndp.size());
        ndp.push_back({INF, INF});
        for (int i = k - 1; i >= 0; i--) {
            if (ndp[i].first < INF / 2 || ndp[i].second < 0) ndp[i + 1].first = min(ndp[i + 1].first, 0LL);
        }
        int m = int(dp.size()) - 1;
        V<P> udp(m + k + 1, {INF, INF});
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= k; j++) {
                udp[i+j].first = min(udp[i+j].first, dp[i].first + ndp[j].first);
                udp[i+j].second = min(udp[i+j].second, dp[i].first + ndp[j].second);
                udp[i+j].second = min(udp[i+j].second, dp[i].second + ndp[j].first);
                udp[i+j].second = min(udp[i+j].second, dp[i].second + ndp[j].second);
            }
        }
        dp = udp;
    }
    int m = int(dp.size()) - 1;
    V<P> udp(m + 1);
    for (int i = 0; i <= m; i++) {
        if (a[p] > 0) {
            udp[i].first = dp[i].first + a[p];
            udp[i].second = dp[i].second + a[p];
        } else {
            udp[i].first = INF;
            udp[i].second = min(dp[i].first, dp[i].second) + a[p];
        }
    }

    return udp;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << setprecision(20) << fixed;

    cin >> n;
    a = V<ll>(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    g = VV<int>(n);
    for (int j = 0; j < n - 1; ++j) {
        int a, b;
        cin >> a >> b; a--; b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }

    auto dp = dfs(0, -1);

    for (int i = 0; i < n; i++) {
        if (dp[i].first < INF / 2 || dp[i].second < 0) {
            cout << i << endl;
            return 0;
        }
    }
    assert(false);
    return 0;
}
