const INF: i64 = 1 << 60;

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());
    let n: usize = sc.read();
    let a: Vec<i64> = sc.vec(n);
    let mut graph = vec![vec![]; n];
    for _ in 1..n {
        let u = sc.read::<usize>() - 1;
        let v = sc.read::<usize>() - 1;
        graph[u].push(v);
        graph[v].push(u);
    }

    let (power, dp) = dfs(0, 0, &graph, &a);
    // eprintln!("{:?}", power);
    // eprintln!("{:?}", dp);

    let mut ans = n - 1;
    for i in 0..power.len() {
        if power[i] < INF {
            update_min(&mut ans, i);
        }
    }
    for i in 0..dp.len() {
        if dp[i] < 0 {
            update_min(&mut ans, i);
        }
    }

    println!("{}", ans);
}

fn dfs(v: usize, p: usize, graph: &Vec<Vec<usize>>, a: &Vec<i64>) -> (Vec<i64>, Vec<i64>) {
    let power = a[v];
    let mut power_top = vec![];
    if power > 0 {
        power_top.push(power);
    }
    let mut dp = vec![power];
    for &next in graph[v].iter().filter(|&&next| next != p) {
        let (child_power, child_dp) = dfs(next, v, graph, a);

        let mut next_dp = vec![INF; child_dp.len() + dp.len()];
        let mut next_power = vec![INF; child_dp.len() + power_top.len()];

        for child_dp_cut in 0..child_dp.len() {
            for dp_cut in 0..dp.len() {
                update_min(
                    &mut next_dp[child_dp_cut + dp_cut],
                    child_dp[child_dp_cut] + dp[dp_cut],
                );
                if child_dp[child_dp_cut] < 0 {
                    update_min(&mut next_dp[child_dp_cut + dp_cut + 1], dp[dp_cut]);
                }
            }
            for power_cut in 0..power_top.len() {
                if child_dp[child_dp_cut] < 0 {
                    update_min(
                        &mut next_power[power_cut + child_dp_cut + 1],
                        power_top[power_cut],
                    );
                }
            }
        }

        for child_power_cut in 0..child_power.len() {
            for dp_cut in 0..dp.len() {
                update_min(
                    &mut next_dp[child_power_cut + dp_cut],
                    child_power[child_power_cut] + dp[dp_cut],
                );

                if child_power[child_power_cut] < INF {
                    update_min(&mut next_dp[child_power_cut + dp_cut + 1], dp[dp_cut]);
                }
            }
            for power_cut in 0..power_top.len() {
                update_min(
                    &mut next_power[power_cut + child_power_cut],
                    child_power[child_power_cut] + power_top[power_cut],
                );
                if child_power[child_power_cut] < INF {
                    update_min(
                        &mut next_power[power_cut + child_power_cut + 1],
                        power_top[power_cut],
                    );
                }
            }
        }

        power_top = next_power;
        dp = next_dp;
    }

    // eprintln!("v={} power={:?} dp={:?}", v, power_top, dp);
    (power_top, dp)
}

fn update_min<T: PartialOrd>(a: &mut T, b: T) {
    if *a > b {
        *a = b;
    }
}

pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        Self(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}


Measured memory_bytes: 4336