#pragma GCC optimize("Ofast")

#include <bits/stdc++.h>

using namespace std;

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

#define X first
#define Y second

//#include <boost/unordered_map.hpp>
//using namespace boost;

/*
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
rbtree T;
*/

namespace io{
	const int L = (1 << 20) + 1;
	
	char buf[L], *S , *T, c;
	 
	char getchar() {
		if(__builtin_expect(S == T, 0)) {
			T = (S = buf) + fread(buf, 1, L, stdin);
			return (S == T ? EOF : *S++);
		}
		return *S++;
	}
	
	int inp() {
		int x = 0, f = 1; char ch;
		for(ch = getchar(); !isdigit(ch); ch = getchar())
			if(ch == '-') f = -1;
		for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		return x * f;
	}
	
	unsigned inpu()
	{
		unsigned x = 0; char ch;
		for(ch = getchar(); !isdigit(ch); ch = getchar());
		for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		return x;
	}
	
	ll inp_ll() {
		ll x = 0; int f = 1; char ch;
		for(ch = getchar(); !isdigit(ch); ch = getchar())
			if(ch == '-') f = -1;
		for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		return x * f;
	}
	
	char B[25], *outs=B+20, *outr=B+20;
	template<class T>
	inline void print(register T a,register char x=0){
		if(x) *--outs = x, x = 0;
		
		if(!a)*--outs = '0';
		else 
			while(a)
				*--outs = (a % 10) + 48, a /= 10;
		
		if(x)
			*--outs = x;
		
		fwrite(outs, outr - outs , 1, stdout);
		outs = outr;
	}
};

using io :: print;
using io :: inp;
using io :: inpu;
using io :: inp_ll;

using i32 = int;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;

ll power(ll a, ll b, ll p)
{
	if (!b) return 1;
	ll t = power(a, b/2, p);
	t = t*t%p;
	if (b&1) t = t*a%p;
	return t;
}

const int MAXN = 5010;
const int MAXP = 10000000;
const u64 MOD = 1000000007;
const f80 MI = f80(1)/MOD;
const ll INF = 10000000000000000LL;
const ll inf = 5000000000000LL;

int n;
int a[MAXN];
vector<int> v[MAXN];

int size[MAXN];
ll F[MAXN][MAXN][2]; // 0/1 whether there is a computer
ll tmp[MAXN][2];

void fresh(ll &a, ll b)
{
	if (a > b) a = b;
}

void dfs(int x, int pre)
{
	size[x] = 1;
	if (a[x] > 0)
	{
		F[x][0][0] = F[x][0][1] = a[x];
	}
	else
	{
		F[x][0][1] = a[x];
	}
	for (auto y : v[x])
	{
		if (y == pre) continue;
		dfs(y, x);
		for (int s = 0; s <= size[x]+size[y]; ++ s)
		{
			tmp[s][0] = INF;
			tmp[s][1] = INF;
		}
		for (int sx = 0; sx <= size[x]; ++ sx)
			for (int sy = 0; sy <= size[y]; ++ sy)
			{
				fresh(tmp[sx+sy][0], F[x][sx][0]+F[y][sy][0]);
				fresh(tmp[sx+sy][1], F[x][sx][1]+F[y][sy][0]);
				fresh(tmp[sx+sy][1], F[x][sx][0]+F[y][sy][1]);
				fresh(tmp[sx+sy][1], F[x][sx][1]+F[y][sy][1]);
			}
		for (int s = 0; s <= size[x]+size[y]; ++ s)
		{
			F[x][s][0] = tmp[s][0];
			F[x][s][1] = tmp[s][1];
		}
		size[x] += size[y];
	}
	for (int s = 0; s <= size[x]; ++ s)
		if (F[x][s][0] != INF || F[x][s][1] < 0)
		{
			for (; s <= size[x]; ++ s)
			{
				fresh(F[x][s+1][0], 0);
				fresh(F[x][s+1][1], 0);
			}
			break;
		}
	/*
	for (int s = size[x]-1; s >= 0; -- s)
	{
		fresh(F[x][s+1][0], 0);
		fresh(F[x][s+1][1], 0);
		if (F[x][s][1] < 0)
		{
			fresh(F[x][s+1][0], 0);
			fresh(F[x][s+1][1], 0);
		}
	}
	*/
}

int main()
{
	
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i)
		scanf("%d", &a[i]);
	for (int i = 1; i < n; ++ i)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for (int i = 1; i <= n; ++ i)
		for (int j = 0; j <= n; ++ j)
			F[i][j][0] = F[i][j][1] = INF;
	dfs(1, 0);
	for (int i = 0; i <= n; ++ i)
		if (F[1][i][0] == 0)
		{
			cout << i-1 << endl;
			break;
		}
	
	return 0;
}


Measured memory_bytes: 394112