#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using lint = long long int;
long long int INF = 1001001001001001LL;
int inf = 1000000007;
long long int MOD = 1000000007LL;
double PI = 3.1415926535897932;

template<typename T1,typename T2>inline void chmin(T1 &a,const T2 &b){if(a>b) a=b;}
template<typename T1,typename T2>inline void chmax(T1 &a,const T2 &b){if(a<b) a=b;}

#define ALL(a) a.begin(),a.end()
#define RALL(a) a.rbegin(),a.rend()

/* do your best */

// やっと会えたね，二乗の木 DP たん
// https://drken1215.hatenablog.com/entry/2019/01/13/024000
vector<lint> a;
vector<vector<lint>> g;

vector<pair<lint, lint>> merge(const vector<pair<lint, lint>> &dpl, const vector<pair<lint, lint>> &dpr) {

  int n = dpl.size();
  int m = dpr.size();
  
  vector<pair<lint, lint>> dp(n + m, {INF, 0});
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      // 和
      // マージする
      chmin(dp[i + j].first, dpl[i].first + dpr[j].first);
      // r はカットする
      if (dpr[j].first < 0 or dpr[j].second) {
        chmin(dp[i + j + 1].first, dpl[i].first);
      }

      // すべて正にできるか
      dp[i + j].second |= dpl[i].second & dpr[j].second;
      // r はカットする
      if (dpr[j].first < 0 or dpr[j].second) {
        dp[i + j + 1].second |= dpl[i].second;
      }
    }
  }

  return dp;
}

// この書き方は半ばテンプレート気味
vector<pair<lint, lint>> dfs(int cur, int par = -1) {

  vector<pair<lint, lint>> dp(1);
  dp[0].first = a[cur];
  dp[0].second = (a[cur] > 0);
  for (auto nxt : g[cur]) {
    if (nxt == par) continue;
    vector<pair<lint, lint>> cdp = dfs(nxt, cur);
    dp = merge(dp, cdp);
  }

  return dp;
}

int main() {
  
  int n; cin >> n;
  a.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }

  g.resize(n);
  for (int i = 0; i < n - 1; i++) {
    int u, v; cin >> u >> v;
    u--;
    v--;
    g[u].push_back(v);
    g[v].push_back(u);
  }

  auto dp = dfs(0);
  int ans = inf;
  for (int i = 0; i < n; i++) {
    if (dp[i].first < 0) {
      ans = min(ans, i);
    }
    if (dp[i].second == true) {
      ans = min(ans, i);
    }
  }

  cout << ans << endl;
  return 0;
}
