#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>

template <class T>
std::vector<T> vec(int len, T elem) { return std::vector<T>(len, elem); }

template <class Cost = int>
struct Edge {
    int src, dst;
    Cost cost;
    Edge(int src = -1, int dst = -1, Cost cost = 1)
        : src(src), dst(dst), cost(cost){};

    bool operator<(const Edge<Cost>& e) const { return this->cost < e.cost; }
    bool operator>(const Edge<Cost>& e) const { return this->cost > e.cost; }
};

template <class Cost = int>
using Graph = std::vector<std::vector<Edge<Cost>>>;

using lint = long long;
constexpr lint INF = 1LL << 45;

void solve() {
    int n;
    std::cin >> n;

    std::vector<lint> xs(n);
    for (auto& x : xs) std::cin >> x;

    Graph<> graph(n);
    for (int i = 0; i < n - 1; ++i) {
        int u, v;
        std::cin >> u >> v;
        --u, --v;
        graph[u].emplace_back(u, v);
        graph[v].emplace_back(v, u);
    }

    auto dp = vec(2, vec(n, vec(n, 0LL)));
    auto ndp = std::vector<lint>(n);
    auto esz = vec(n, 0);

    std::function<void(int, int)> dfs =
        [&](int v, int p) {
            std::fill(dp[0][v].begin(), dp[0][v].end(), INF);
            dp[0][v][0] = xs[v];

            if (xs[v] > 0) dp[1][v][0] = 1;

            for (auto e : graph[v]) {
                int u = e.dst;
                if (u == p) continue;

                dfs(u, v);

                std::fill(ndp.begin(), ndp.end(), INF);
                for (int i = 0; i <= esz[v]; ++i) {
                    for (int j = 0; j <= esz[u]; ++j) {
                        // negative merge
                        ndp[i + j] = std::min(ndp[i + j], dp[0][v][i] + dp[0][u][j]);

                        if (dp[1][u][j]) {
                            // cut
                            ndp[i + j + 1] = std::min(ndp[i + j + 1], dp[0][v][i]);
                        }
                    }
                }
                std::swap(dp[0][v], ndp);

                std::fill(ndp.begin(), ndp.end(), 0);
                for (int i = 0; i <= esz[v]; ++i) {
                    if (!dp[1][v][i]) continue;

                    for (int j = 0; j <= esz[u]; ++j) {
                        if (dp[0][u][j] < 0) {
                            // cut
                            while ((int)ndp.size() < i + j + 1) ndp.push_back(0);
                            ndp[i + j + 1] = 1;
                        }

                        if (dp[1][u][j]) {
                            // positive merge
                            while ((int)ndp.size() < i + j) ndp.push_back(0);
                            ndp[i + j] = 1;
                        }
                    }
                }
                std::swap(dp[1][v], ndp);

                esz[v] += esz[u] + 1;
            }

            // std::cerr << v << ": " << esz[v] << std::endl;
            // for (auto x : dp[0][v]) std::cerr << x << " ";
            // std::cerr << std::endl;
            // for (auto x : dp[1][v]) std::cerr << x << " ";
            // std::cerr << std::endl
            //           << std::endl;
        };

    dfs(0, -1);
    int ans = n;
    for (int i = 0; i < n; ++i) {
        if (dp[0][0][i] < 0 || dp[1][0][i]) {
            ans = std::min(ans, i);
            break;
        }
    }

    std::cout << ans << std::endl;
}

int main() {
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::ios::sync_with_stdio(false);

    solve();

    return 0;
}


Measured memory_bytes: 587904