#ifndef BZ
#pragma GCC optimize "-O3"
#endif
#include <bits/stdc++.h>

#define FASTIO
#define ALL(v) (v).begin(), (v).end()
#define rep(i, l, r) for (int i = (l); i < (r); ++i)

#ifdef FASTIO
#define scanf abacaba
#define printf abacaba
#endif

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

using namespace std;


/*
ll pw(ll a, ll b) {
	ll ans = 1; while (b) {
		while (!(b & 1)) b >>= 1, a = (a * a) % MOD;
		ans = (ans * a) % MOD, --b;
	} return ans;
}
*/

const int MAXN = 5100;
const ll INF = 1e18;

int n;
ll a[MAXN];

vector<int> eds[MAXN];
int was[MAXN];

array<vector<ll>, 2> dfs1(int v) {
	was[v] = 1;
	array<vector<ll>, 2> cur;
	if (a[v] < 0)
		cur[0].push_back(INF), cur[1].push_back(a[v]);
	else
		cur[0].push_back(a[v]), cur[1].push_back(a[v]);
	for (int u: eds[v]) {
		if (was[u])
			continue;
		auto tmp = dfs1(u);
		array<vector<ll>, 2> tmp2;
		tmp2[0].resize(cur[0].size() - 1 + tmp[0].size() - 1 + 1, INF);
		tmp2[1].resize(cur[0].size() - 1 + tmp[0].size() - 1 + 1, INF);
		for (int i = 0; i < cur[0].size(); ++i)
			for (int j = 0; j < tmp[0].size(); ++j) {
				tmp2[0][i + j] = min(tmp2[0][i + j], cur[0][i] + tmp[0][j]);
				tmp2[1][i + j] = min(tmp2[1][i + j], cur[1][i] + tmp[1][j]);
			}
		cur = tmp2;
	}
	cur[0].push_back(INF);
	cur[1].push_back(INF);
	for (int i = 0; i + 1 < cur[0].size(); ++i) {
		if (cur[0][i] < INF)
			cur[0][i + 1] = min(cur[0][i + 1], 0ll);
		if (cur[1][i] < 0)
			cur[0][i + 1] = min(cur[0][i + 1], 0ll);
	}
	for (int i = 0; i < cur[0].size(); ++i)
		cur[1][i] = min(cur[1][i], cur[0][i]);
	return cur;
}

int main() {
#ifdef FASTIO
	ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#endif
	cin >> n;
	for (int i = 0; i < n; ++i)
		cin >> a[i];
	for (int i = 0; i < n - 1; ++i) {
		int a, b;
		cin >> a >> b;
		--a, --b;
		eds[a].push_back(b);
		eds[b].push_back(a);
	}
	auto go = dfs1(0);
	int ans = n;
	for (int i = 0; i < go[0].size(); ++i)
		if (go[0][i] < INF || go[1][i] < 0)
			ans = min(ans, i + 1);
	cout << ans - 1 << "\n";
	return 0;
}


