// includes
#include <cstdio>
#include <cstdint>
#include <iostream>
#include <iomanip>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <utility>
#include <functional>
#include <cmath>
#include <climits>
#include <bitset>

// macros
#define ll long long int
#define pb push_back
#define mk make_pair
#define pq priority_queue
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define rep(i, n) FOR(i, 0, n)
#define rrep(i, n) for(int i=((int)(n)-1);i>=0;i--)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())

using namespace std;

//  types
typedef pair<int, int> P;
typedef pair<ll, int> Pl;
typedef pair<ll, ll> Pll;
typedef pair<double, double> Pd;
 
// constants
const int inf = 1e9;
const ll linf = 1LL << 50;
const double EPS = 1e-10;
const int mod = 1e9 + 7;

// solve
template <class T>bool chmax(T &a, const T &b){if(a < b){a = b; return 1;} return 0;}
template <class T>bool chmin(T &a, const T &b){if(a > b){a = b; return 1;} return 0;}

vector<int> edge[5001];
vector<int> child[5001];
int par[5001], num[5001];
ll dp1[5001][5001], dp2[5001][5001];

void dfs1(int i){
  num[i] = 1;
  rep(j, edge[i].size()){
    int to = edge[i][j];
    if(par[to] >= 0)continue;
    par[to] = i;
    child[i].pb(to);
    dfs1(to);
    num[i] += num[to];
  }
}

vector<ll> a;
int n;

ll dp[5001][5001];

void dfs(int i){
  rep(j, child[i].size()){
    dfs(child[i][j]);
  }
  if(child[i].size() == 0){
    if(a[i] < 0){
      dp2[i][1] = a[i];
    }else{
      dp1[i][1] = dp2[i][1] = a[i];
    }
    return;
  }
  if(a[i] > 0){
    dp[0][0] = linf;
    dp[0][1] = a[i];
    int curr = 1;
    int prev = 1;
    rep(j, child[i].size()){
      int to = child[i][j];
      curr += num[to];
      rep(k, curr+1){
        dp[j+1][k] = linf;
        for(int l = max(1, k-prev); l <= k; l++){
          if(l > num[to])break;
          if((dp1[to][l] < linf || dp2[to][l] < 0))chmin(dp[j+1][k], dp[j][k-l]);
        }
        if(a[to] > 0){
          for(int l = max(1, k+1-prev); l <= k; l++){
            if(l > num[to])break;
            chmin(dp[j+1][k], dp[j][k-l+1] + dp1[to][l]);
          }
        }
      }
      prev = curr;
    }
    rep(j, num[i]+1)dp1[i][j] = dp[child[i].size()][j];
  }

  dp[0][0] = linf;
  dp[0][1] = a[i];
  int curr = 1;
  int prev = 1;
  rep(j, child[i].size()){
    int to = child[i][j];
    curr += num[to];
    rep(k, curr+1){
      dp[j+1][k] = linf;
        for(int l = max(1, k-prev); l <= k; l++){
          if(l > num[to])break;
          if((dp1[to][l] < linf || dp2[to][l] < 0))chmin(dp[j+1][k], dp[j][k-l]);
        }
        for(int l = max(1,k+1-prev); l <= k; l++){
          if(l > num[to])break;
          chmin(dp[j+1][k], dp[j][k-l+1] + dp1[to][l]);
          chmin(dp[j+1][k], dp[j][k-l+1] + dp2[to][l]);
        }
    }
    prev = curr;
  }
  rep(j, num[i]+1)dp2[i][j] = dp[child[i].size()][j];

}

int main(int argc, char const* argv[])
{
  cin >> n;
  a = vector<ll>(n, 0);
  rep(i, n)cin >> a[i];
  rep(i, n - 1){
    int x, y;
    cin >> x >> y;
    x--; y--;
    edge[x].pb(y);
    edge[y].pb(x);
  }
  fill(par, par + n, -1);
  par[0] = 0;
  dfs1(0);

  rep(i, n+1){
    rep(j, n+1){
      dp1[i][j] = dp2[i][j] = linf;
    }
  }

  dfs(0);
  FOR(i, 1, n+1){
    if(dp1[0][i] < linf || dp2[0][i] < 0){
      cout << i - 1 << endl;
      return 0;
    }
  }

	return 0;
}


Measured memory_bytes: 585216