#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"

using namespace std;

const long long int MOD = 1000000007;
//const int MOD = 998244353;

long long int N, M, K, H, W, L, R;
//int N, M, K, H, W, L, R;

void Calculate_Depth(vector<vector<int>>&edge, vector<int>&depth, int stnode) {
	depth[stnode] = 0;
	queue<int>Q;
	Q.push(stnode);
	while (!Q.empty()) {
		int cn = Q.front();
		Q.pop();
		for (auto i : edge[cn]) {
			if (depth[i] > depth[cn] + 1) {
				depth[i] = depth[cn] + 1;
				Q.push(i);
			}
		}
	}
	return;
}

void Search(vector<vector<long long int>>&m_min, vector<vector<long long int>>&p_all, vector<int>&max_num, int node, vector<vector<int>>&edge, vector<int>&depth, vector<int>&v) {
	if (v[node] > 0)p_all[node][0] = v[node];
	else m_min[node][0] = v[node];
	max_num[node] = 0;
	//cout << node << endl;
	//cout << m_all[node][0] << " " << p_min[node][0] << endl;
	for (auto i : edge[node]) {
		if (depth[i] < depth[node])continue;
		//cout << node << " " << i << endl;
		Search(m_min, p_all, max_num, i, edge, depth, v);
	//	cout << node << " " << i << endl;
		vector<long long int>box_m_min(max_num[node] + max_num[i] + 2, MOD*MOD);
		vector<long long int>box_p_all(max_num[node] + max_num[i] + 2, MOD*MOD);
		for (int j = 0; j <= max_num[node]; j++) {
			for (int k = 0; k <= max_num[i]; k++) {
				box_m_min[j + k] = min(box_m_min[j + k], m_min[node][j] + m_min[i][k]);
				if (p_all[i][k] != MOD * MOD)box_m_min[j + k] = min(box_m_min[j + k], m_min[node][j] + p_all[i][k]);
				if (p_all[node][j] != MOD * MOD)box_m_min[j + k] = min(box_m_min[j + k], p_all[node][j] + m_min[i][k]);
				if (p_all[node][j] != MOD * MOD&&p_all[i][k] != MOD * MOD)box_p_all[j + k] = min(box_p_all[j + k], p_all[node][j] + p_all[i][k]);
				if (m_min[i][k] < 0 || p_all[i][k] != MOD * MOD) {
				//	cout << "hi " << node << " " << i << " " << j << " " << k << endl;
					box_m_min[j + k + 1] = min(box_m_min[j + k + 1], m_min[node][j]);
				//	cout << j + k + 1 << " " << box_m_min[j + k + 1] << endl;
					if (p_all[node][j] != MOD * MOD)box_p_all[j + k + 1] = min(box_p_all[j + k + 1], p_all[node][j]);
				}
			}
		}
		max_num[node] += max_num[i] + 1;
		m_min[node] = box_m_min;
		p_all[node] = box_p_all;
	}
	return;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N;
	vector<int>v(N);
	for (auto &i : v)cin >> i;
	vector<vector<long long int>>m_min(N, vector<long long int>(N, MOD*MOD));
	vector<vector<long long int>>p_all(N, vector<long long int>(N, MOD*MOD));
	vector<int>max_num(N);
	vector<vector<int>>edge(N);
	for (int i = 1; i < N; i++) {
		cin >> L >> R;
		L--;
		R--;
		edge[L].push_back(R);
		edge[R].push_back(L);
	}
	vector<int>depth(N, MOD);
	Calculate_Depth(edge, depth, 0);
	Search(m_min, p_all, max_num, 0, edge, depth, v);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
	//		cout << i << " " << j << " " << m_min[i][j] << " " << p_all[i][j] << endl;
		}
	}
	for (int i = 0; i < N; i++) {
		if (m_min[0][i] < 0 || p_all[0][i] != MOD * MOD) {
			cout << i << endl;
			return 0;
		}
	}
	return 0;
}

Measured memory_bytes: 392960