#![allow(unused_imports)]
#![allow(non_snake_case)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn main() {
    let n = read::<usize>();
    let a = read_vec::<i64>();
    let mut simple_edges: Vec<Vec<usize>> = vec![Vec::new(); n];
    for i in 0..n - 1 {
        let v = read_vec::<usize>();
        let (a, b) = (v[0] - 1, v[1] - 1);
        simple_edges[a].push(b);
        simple_edges[b].push(a);
    }

    let root = 0;
    let mut tree: Vec<Vec<usize>> = vec![Vec::new(); n];
    let mut parent_dict: HashMap<usize, usize> = HashMap::new();
    make_tree(root, n, &simple_edges, &mut tree, &mut parent_dict);
    let mut topological_sorted_indexes = vec![root];
    topological_dfs(root, &tree, &mut topological_sorted_indexes);

    let mut children_a = a.clone();
    for &ti in topological_sorted_indexes.iter().rev() {
        if tree[ti].is_empty() {
            continue;
        }
        let a_sum = tree[ti].iter().map(|&x| children_a[x]).sum::<i64>();
        if 2 * a[ti] < a_sum || a[ti] > a_sum {
            debug!(ti, a[ti], a_sum);
            println!("NO");
            return;
        }
        children_a[ti] = 2 * children_a[ti] - a_sum;
        let inner = a[ti] - children_a[ti];

        if !tree[ti].is_empty() {
            let a_max = tree[ti].iter().map(|&x| children_a[x]).max().unwrap();
            if a_max - children_a[ti] > inner {
                debug!(ti, a_max - children_a[ti], inner);
                println!("NO");
                return;
            }
        }
        if ti == root {
            if tree[ti].len() >= 2 {
                if children_a[ti] > 0 {
                    debug!(ti, children_a[ti]);
                    println!("NO");
                    return;
                }
            } else {
                if a_sum != a[ti] {
                    debug!(ti, children_a[ti]);
                    println!("NO");
                    return;
                }
            }
        }
    }
    println!("YES");
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

fn make_tree(
    cur_idx: usize,
    parent_idx: usize,
    edges: &Vec<Vec<usize>>,
    tree: &mut Vec<Vec<usize>>,
    parent_dict: &mut HashMap<usize, usize>,
) {
    for child_idx in edges[cur_idx].iter() {
        if *child_idx == parent_idx {
            continue;
        }
        tree[cur_idx].push(*child_idx);
        parent_dict.insert(*child_idx, cur_idx);
        make_tree(*child_idx, cur_idx, edges, tree, parent_dict);
    }
}

fn topological_dfs(cur_idx: usize, tree: &Vec<Vec<usize>>, result: &mut Vec<usize>) {
    for child_idx in tree[cur_idx].iter() {
        result.push(*child_idx);
        topological_dfs(*child_idx, tree, result);
    }
}


Measured memory_bytes: 60152