#![allow(unused_imports)]
use num::Integer;
use proconio::*;
use std::ops::*;
use std::collections::VecDeque;

fn main() {
   input! {
       n: usize,
       mut c: [usize; n],
       e: [(usize, usize); n-1]
   }
   let mut to = vec![Vec::<usize>::new(); n];
   for (a, b) in &e {
      to[a - 1].push(b - 1);
      to[b - 1].push(a - 1);
   }
   for x in &mut c {
      *x -= 1;
   }
   let mut vin = vec![0; n];
   let mut vout = vec![0; n];

   if false {
       let mut stack = VecDeque::<usize>::new();
       stack.push_back(0);
       let mut k = 0;
       let mut yet = vec![false; n];
       while let Some(v) = stack.back().map(|v| *v as usize) {
           if !yet[v] {
               vin[v] = k;
               k += 1;
               yet[v] = true;
           }
           let mut flag = true;
           for u in to[v].iter().copied() {
               if yet[u] {
                   continue;
               }
               flag = false;
               stack.push_back(u);
           }
           if flag {
               vout[v] = k;
               stack.pop_back();
           }
       }
   }

   dfs(0, None, &mut vin, &mut vout, &to);
   let mut vs = vec![Vec::<usize>::new(); n];
   for (i, x) in c.iter().enumerate() {
      vs[*x].push(i);
   }

   let mut res = vec![c2(n as i64); n];
   let mut d = BIT::<i64>::new(n, 0);
   for i in 0..n {
      d.add(i, 1);
   }
   for i in 0..n {
      vs[i].sort_by_key(|a| -(vin[*a] as i32));
      let mut history = Vec::<(usize, i64)>::new();
      for v in vs[i].iter().copied() {
         let mut cnt = 1;
         for u in to[v].iter().copied() {
            if (vin[u] < vin[v]) {
               continue;
            }
            let num = d.range(vin[u], vout[u]);
            res[i] -= c2(num as i64);
            cnt += num;
         }
         d.add(vin[v], -cnt);
         history.push((vin[v], cnt));
      }
      res[i] -= c2(d.range(0, n));
      for (i, cnt) in history {
         d.add(i, cnt);
      }
   }
   for r in res {
      println!("{}", r);
   }
}

fn c2(n: i64) -> i64 {
   n * (n + 1) / 2
}


static mut K: usize = 0;
fn dfs(
   u: usize,
   p: Option<usize>,
   vin: &mut Vec<usize>,
   vout: &mut Vec<usize>,
   to: &Vec<Vec<usize>>,
) {
   unsafe {
      vin[u] = K;
      K += 1;
   }
   for v in &to[u] {
      if matches!(p, Some(x) if x == *v) {
         continue;
      }
      dfs(*v, Some(u), vin, vout, to);
   }
   unsafe {
      vout[u] = K;
   }
}

#[derive(Debug, Clone)]
struct BIT<T> {
   n: usize,
   d: Vec<T>,
}

impl<T: Copy + Clone + Sub + AddAssign> BIT<T> {
   fn new(n: usize, x: T) -> BIT<T> {
      BIT {
         n: n,
         d: vec![x; n + 1],
      }
   }

   fn add(&mut self, i: usize, a: T) {
      let mut i = (i + 1) as i32;
      while i <= self.n as i32 {
         self.d[i as usize] += a;
         i += i & (-i);
      }
   }

   fn sum(&self, i: usize) -> T {
      let mut i = (i + 1) as i32;
      let mut sum = self.d[0];
      while i > 0 {
         sum += self.d[i as usize];
         i -= i & (-i);
      }
      sum
   }

   // [l, r)
   fn range(&self, l: usize, r: usize) -> <T as Sub>::Output {
      match (l, r) {
         (0, r) => self.sum(r - 1) - self.d[0],
         (_, _) => self.sum(r - 1) - self.sum(l - 1),
      }
   }
}


Measured memory_bytes: 52228