//Link : https://codeforces.com/contest/1194/problem/B

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf ((ll)1e18)
#define N 5005

vector<int> tdj[N],adj[N];
int A[N],dsu[N];

int f(int x) {
    if(dsu[x]==x) {
        return x;
    }
    return dsu[x] = f(dsu[x]);
}
void merge(int x,int y) {
    x = f(x),y = f(y);
    if(x!=y) {
        dsu[x] = y;
    }
}
ll v[N];
ll dp[N][2][N];
int subTreeSize[N];

bool isSame(int x,int y) {
    if((v[x]>0 && v[y]>0) || (v[x]<0 && v[y]<0)) {
        return true;
    } else {
        return false;
    }
}

ll tmp[2][N];

void dfs(int node,int p) {
    subTreeSize[node] = 1;
    dp[node][0][0] = v[node];
    dp[node][1][0] = inf;
    for(int ch : adj[node]) {
        if(ch!=p) {
            dfs(ch,node);
            for(int i=0;i<subTreeSize[node]+subTreeSize[ch];++i) {
                tmp[0][i] = inf;
                tmp[1][i] = inf;
            }
            bool isEqual = isSame(node,ch);
            for(int i=0;i<subTreeSize[node];++i) {
                for(int j = 0;j<subTreeSize[ch];++j) {
                    if(isEqual) {
                        if(dp[node][0][i]!=inf && dp[ch][0][j]!=inf)
                            tmp[0][i+j] = min(tmp[0][i+j],dp[node][0][i] + dp[ch][0][j]);
                    } else {
                        if(dp[node][0][i]!=inf && dp[ch][0][j]!=inf)
                            tmp[1][i+j] = min(tmp[1][i+j],dp[node][0][i] + dp[ch][0][j]);
                    }
                    if(dp[node][0][i]!=inf && dp[ch][1][j]<0)
                        tmp[0][i+j+1] = min(tmp[0][i+j+1],dp[node][0][i]);
                    if(dp[node][0][i]!=inf && dp[ch][0][j]!=inf) {
                        tmp[0][i+j+1] = min(tmp[0][i+j+1],dp[node][0][i]);
                    }
                    if(dp[node][1][i]!=inf && dp[ch][1][j]<0)
                        tmp[1][i+j+1] = min(tmp[1][i+j+1],dp[node][1][i]);
                    if(dp[node][1][i]!=inf && dp[ch][0][j]!=inf) {
                        tmp[1][i+j+1] = min(tmp[1][i+j+1],dp[node][1][i]);
                    }

                    if(dp[node][0][i]!=inf && dp[ch][1][j]!=inf)
                        tmp[1][i+j] = min(tmp[1][i+j], dp[node][0][i] + dp[ch][1][j]);
                    if(dp[node][1][i]!=inf && dp[ch][1][j]!=inf)
                        tmp[1][i+j] = min(tmp[1][i+j], dp[node][1][i] + dp[ch][1][j]);
                    if(dp[node][1][i]!=inf && dp[ch][0][j]!=inf)
                        tmp[1][i+j] = min(tmp[1][i+j], dp[node][1][i] + dp[ch][0][j]);
                }
            }
            subTreeSize[node] += subTreeSize[ch];
            for(int j = 0;j<subTreeSize[node];++j) {
                dp[node][0][j] = tmp[0][j];
                dp[node][1][j] = tmp[1][j];
            }
        }
    }
}

void solve() {
  int n;scanf("%d",&n);
  for(int i=1;i<=n;++i) {
      scanf("%d",&A[i]);
      dsu[i] = i;
  }
  for(int i=0;i<n-1;++i) {
      int a,b;scanf("%d %d",&a,&b);
      tdj[a].push_back(b);
  }
  for(int i=1;i<=n;++i) {
      if(A[i]>0) {
          continue;
      }
      for(int ch : tdj[i]) {
          if(A[ch]<0) {
              merge(ch,i);
          }
      }
  }
  for(int i=1;i<=n;++i) {
      v[f(i)] += A[i];
  }
  for(int i=1;i<=n;++i) {
      int node = f(i);
      for(int ch : tdj[i]) {
          int ccx = f(ch);
          if(node!=ccx) {
              adj[node].push_back(ccx);
              adj[ccx].push_back(node);
          }
      }
  }
  int root = -1;
  for(int i=1;i<=n;++i) {
      if(f(i)==i) {
          root = i;
      }
  }
  dfs(root,0);
  int ret = n;
  for(int i=0;i<n;++i) {
      if(dp[root][0][i] !=inf) {
          ret = min(ret,i);
      }
      if(dp[root][1][i]<0) {
          ret = min(ret,i);
      }
  }
  printf("%d\n",ret);
}

int main() {
    ///freopen("input.txt","r",stdin);
    solve();
    return 0;
}


Measured memory_bytes: 391808