Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class Graph:

    def __init__(self, size):
        self.size = size
        self.vertices = [0] * size
        self.edges = [None] * size
        for i in range(size):
            self.edges[i] = []

    def add_edge(self, frm, to):
        self.edges[frm].append(to)
        self.edges[to].append(frm)

    def get_connect(self, v):
        return self.edges[v]

def calc(value):
    return value * (value + 1) // 2



def solve(graph, color, stack):
    ans = calc(graph.size)
    stack_key = 0
    stack[stack_key] = 0
    #print('stack') # debug
    #print(stack) # debug
    def dfs(v, parent):
        nonlocal ans, stack, stack_key
        #print('v', v) # debug
        if graph.vertices[v] == color:
            stack_key += 1
            stack[stack_key] = 0
        else:
            stack[stack_key] += 1
        for to in graph.edges[v]:
            if to == parent:
                continue
            dfs(to, v)
            if graph.vertices[v] == color:
                ans -= calc(stack[stack_key])
                stack[stack_key] = 0
        if graph.vertices[v] == color:
            stack_key -= 1
    dfs(0, -1)
    ans -= calc(stack[stack_key])
    return ans





if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    graph.vertices = list(map(int, input().split()))
    for i in range(n - 1):
        frm, to = list(map(int, input().split()))
        frm -= 1
        to -= 1
        graph.add_edge(frm, to)

    stack = [None] * (graph.size + 1)
    for i in range(1, n + 1):
        ans = solve(graph, i, stack)
        print(ans)

    #print('\33[32m' + 'end' + '\033[0m') # debug


Fixed submission:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class BIT: # binary indexed tree
    """
    http://hos.ac/slides/20140319_bit.pdf
    """

    NORMAL = 0
    ROLLBACK = 1

    def __init__(self, size):
        self.size = size
        self.data = [0] * (size + 1) # var[0] is dummy
        self.status = BIT.NORMAL
        self.history = []

    def add(self, pos, val):
        assert pos > 0, pos
        if self.status == BIT.NORMAL:
            self.history.append((pos, val))
        k = pos
        while k <= self.size:
            self.data[k] += val
            # for next
            k += k & -k

    def sum(self, pos):
        s = 0
        k = pos
        while k > 0:
            s += self.data[k]
            # for next
            k -= k & -k
        return s

    def sum_section(self, frm, to):
        to_val = self.sum(to)
        frm_val = self.sum(frm)
        return to_val - frm_val

    def save(self):
        self.history = []

    def rollback(self):
        self.status = BIT.ROLLBACK
        for (pos, val) in self.history:
            self.add(pos, -1 * val)
        self.history = []
        self.status = BIT.NORMAL

class Graph:

    def __init__(self, size):
        self.size = size
        self.vertices = [0] * size # var[0] is dummy
        self.edges = [None] * size # var[0] is dummy
        for i in range(size):
            self.edges[i] = []

    def add_edge(self, frm, to):
        self.edges[frm].append(to)
        self.edges[to].append(frm)

def make_mybit(size):
    bit = BIT(size)
    for i in range(size):
        bit.add(i + 1, 1)
    bit.save()
    return bit

def init_color_s(size):
    color_s = [None] * graph.size
    for i in range(graph.size):
        color_s[i] = []
    return color_s

def dfs(graph):
    parent_s = [0] * graph.size
    in_s = [0] * graph.size
    out_s = [0] * graph.size
    order = 0 # starts from 1
    color_s = init_color_s(graph.size)
    def _dfs(v, prev):
        nonlocal order
        order += 1
        parent_s[v] = prev
        in_s[v] = order
        c = graph.vertices[v]
        color_s[c].append(v)
        for to in graph.edges[v]:
            if to == prev:
                continue
            _dfs(to, v)
        out_s[v] = order
    _dfs(0, -1)
    return parent_s, in_s, out_s, color_s

def calc(v):
    return v * (v + 1) // 2

def get_connected(bit, v, in_s, out_s):
    #print('v') # debug
    #print(v) # debug
    large_key = out_s[v]
    small_key = in_s[v] - 1
    return bit.sum_section(small_key, large_key)

def calc_for(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    #print('connected') # debug
    #print(connected) # debug
    return calc(connected)

def cut(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    bit.add(in_s[v], -1 * connected)

def solve(n, graph):
    bit = make_mybit(graph.size)
    parent_s, in_s, out_s, color_s = dfs(graph)
    #print('parent_s, in_s, out_s ') # debug
    #print(parent_s, in_s, out_s ) # debug
    #print('color_s') # debug
    #print(color_s) # debug
    for same_color_s in color_s:
        ans = calc(graph.size)
        bit.rollback()
        #print('bit.data') # debug
        #print(bit.data) # debug
        for v in same_color_s[::-1]:
            for to in graph.edges[v]:
                if to == parent_s[v]:
                    continue
                ans -= calc_for(bit, to, in_s, out_s)
            cut(bit, v, in_s, out_s)
        ans -= calc_for(bit, 0, in_s, out_s)
        #print('ans') # debug
        print(ans)






if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    vertices = list(map(int, input().split()))
    for i, c in enumerate(vertices):
        vertices[i] = c - 1
    graph.vertices = vertices
    for _ in range(n - 1):
        frm, to = list(map(int, input().split()))
        frm -= 1
        to -= 1
        graph.add_edge(frm, to)
    solve(n, graph)


    #print('\33[32m' + 'end' + '\033[0m') # debug

Buggy python submission (verdict: Runtime Error):
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class Graph:

    def __init__(self, size):
        self.size = size
        self.vertices = [0] * size
        self.edges = [None] * size
        for i in range(size):
            self.edges[i] = []

    def add_edge(self, frm, to):
        self.edges[frm].append(to)
        self.edges[to].append(frm)

    def get_connect(self, v):
        return self.edges[v]

def calc(value):
    return value * (value + 1) // 2



def solve(graph, color, stack):
    ans = calc(graph.size)
    stack_key = 0
    stack[stack_key] = 0
    #print('stack') # debug
    #print(stack) # debug
    def dfs(v, parent):
        nonlocal ans, stack, stack_key
        #print('v', v) # debug
        if graph.vertices[v] == color:
            stack_key += 1
            stack[stack_key] = 0
        else:
            stack[stack_key] += 1
        for to in graph.edges[v]:
            if to == parent:
                continue
            dfs(to, v)
            if graph.vertices[v] == color:
                ans -= calc(stack[stack_key])
                stack[stack_key] = 0
        if graph.vertices[v] == color:
            stack_key -= 1
    dfs(0, -1)
    ans -= calc(stack[stack_key])
    return ans





if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    graph.vertices = list(map(int, input().split()))
    for i in range(n - 1):
        frm, to = list(map(int, input().split()))
        frm -= 1
        to -= 1
        graph.add_edge(frm, to)

    stack = [None] * graph.size
    for i in range(1, n + 1):
        ans = solve(graph, i, stack)
        print(ans)

    #print('\33[32m' + 'end' + '\033[0m') # debug


Fixed submission:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class BIT: # binary indexed tree
    """
    http://hos.ac/slides/20140319_bit.pdf
    """

    NORMAL = 0
    ROLLBACK = 1

    def __init__(self, size):
        self.size = size
        self.data = [0] * (size + 1) # var[0] is dummy
        self.status = BIT.NORMAL
        self.history = []

    def add(self, pos, val):
        assert pos > 0, pos
        if self.status == BIT.NORMAL:
            self.history.append((pos, val))
        k = pos
        while k <= self.size:
            self.data[k] += val
            # for next
            k += k & -k

    def sum(self, pos):
        s = 0
        k = pos
        while k > 0:
            s += self.data[k]
            # for next
            k -= k & -k
        return s

    def sum_section(self, frm, to):
        to_val = self.sum(to)
        frm_val = self.sum(frm)
        return to_val - frm_val

    def save(self):
        self.history = []

    def rollback(self):
        self.status = BIT.ROLLBACK
        for (pos, val) in self.history:
            self.add(pos, -1 * val)
        self.history = []
        self.status = BIT.NORMAL

class Graph:

    def __init__(self, size):
        self.size = size
        self.vertices = [0] * size # var[0] is dummy
        self.edges = [None] * size # var[0] is dummy
        for i in range(size):
            self.edges[i] = []

    def add_edge(self, frm, to):
        self.edges[frm].append(to)
        self.edges[to].append(frm)

def make_mybit(size):
    bit = BIT(size)
    for i in range(size):
        bit.add(i + 1, 1)
    bit.save()
    return bit

def init_color_s(size):
    color_s = [None] * graph.size
    for i in range(graph.size):
        color_s[i] = []
    return color_s

def dfs(graph):
    parent_s = [0] * graph.size
    in_s = [0] * graph.size
    out_s = [0] * graph.size
    order = 0 # starts from 1
    color_s = init_color_s(graph.size)
    def _dfs(v, prev):
        nonlocal order
        order += 1
        parent_s[v] = prev
        in_s[v] = order
        c = graph.vertices[v]
        color_s[c].append(v)
        for to in graph.edges[v]:
            if to == prev:
                continue
            _dfs(to, v)
        out_s[v] = order
    _dfs(0, -1)
    return parent_s, in_s, out_s, color_s

def calc(v):
    return v * (v + 1) // 2

def get_connected(bit, v, in_s, out_s):
    #print('v') # debug
    #print(v) # debug
    large_key = out_s[v]
    small_key = in_s[v] - 1
    return bit.sum_section(small_key, large_key)

def calc_for(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    #print('connected') # debug
    #print(connected) # debug
    return calc(connected)

def cut(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    bit.add(in_s[v], -1 * connected)

def solve(n, graph):
    bit = make_mybit(graph.size)
    parent_s, in_s, out_s, color_s = dfs(graph)
    #print('parent_s, in_s, out_s ') # debug
    #print(parent_s, in_s, out_s ) # debug
    #print('color_s') # debug
    #print(color_s) # debug
    for same_color_s in color_s:
        ans = calc(graph.size)
        bit.rollback()
        #print('bit.data') # debug
        #print(bit.data) # debug
        for v in same_color_s[::-1]:
            for to in graph.edges[v]:
                if to == parent_s[v]:
                    continue
                ans -= calc_for(bit, to, in_s, out_s)
            cut(bit, v, in_s, out_s)
        ans -= calc_for(bit, 0, in_s, out_s)
        #print('ans') # debug
        print(ans)






if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    vertices = list(map(int, input().split()))
    for i, c in enumerate(vertices):
        vertices[i] = c - 1
    graph.vertices = vertices
    for _ in range(n - 1):
        frm, to = list(map(int, input().split()))
        frm -= 1
        to -= 1
        graph.add_edge(frm, to)
    solve(n, graph)


    #print('\33[32m' + 'end' + '\033[0m') # debug

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class BIT: # binary indexed tree
    """
    http://hos.ac/slides/20140319_bit.pdf
    """

    def __init__(self, size):
        self.size = size
        self.data = [0] * (size + 1) # var[0] is dummy

    def add(self, pos, val):
        assert(pos > 0)
        k = pos
        while k <= self.size:
            self.data[k] += val
            # for next
            k += k & -k

    def sum(self, pos):
        s = 0
        k = pos
        while k > 0:
            s += self.data[k]
            # for next
            k -= k & -k
        return s

    def make_copy(self):
        bit = BIT(self.size)
        bit.data = self.data[:]
        return bit

class Graph:

    def __init__(self, size):
        self.size = size
        self.vertices = [0] * (size + 1) # var[0] is dummy
        self.edges = [None] * (size + 1) # var[0] is dummy
        for i in range(1, size + 1):
            self.edges[i] = []

    def add_edge(self, frm, to):
        self.edges[frm].append(to)
        self.edges[to].append(frm)

    def vertex_ids(self):
        return range(1, len(self.vertices))

    def get_connect(self, v):
        return self.edges[v]


class Solver:

    def __init__(self, graph):
        self.graph = graph
        self.bit = BIT(graph.size)
        self.in_s = [None] * (graph.size + 1) # dummy 0 key
        self.out_s = [None] * (graph.size + 1) # dummy 0 key
        self.parent_s = [None] * (graph.size + 1) # dummy 0 key
        self.color_s =  [None] * (graph.size + 1) # dummy 0 key
        for i, _ in enumerate(self.color_s):
            self.color_s[i] = []

    def run(self):
        self.init_by_dfs()
        #print('self.in_s') # debug
        #print(self.in_s) # debug
        #print('self.out_s') # debug
        #print(self.out_s) # debug
        #print('self.parent_s') # debug
        #print(self.parent_s) # debug
        self.init_color_s()
        #print('self.color_s') # debug
        #print(self.color_s) # debug
        base_bit = self.make_base_bit()
        whole = self.calc(self.graph.size)
        #print('whole') # debug
        #print(whole) # debug
        for colored_v_s in self.color_s[1:]:
            #print('colored_v_s') # debug
            #print(colored_v_s) # debug
            bit = base_bit.make_copy()
            complement = self.solve(colored_v_s, bit)
            #print('complement') # debug
            #print(complement) # debug
            #print('ans') # debug
            print(whole - complement)

    def init_by_dfs(self):
        key = 1
        def dfs(v, parent):
            nonlocal key
            self.parent_s[v] = parent
            self.in_s[v] = key
            for to in self.graph.edges[v]:
                if to == parent:
                    continue
                key += 1
                dfs(to, v)
            self.out_s[v] = key
        dfs(1, 0)

    def init_color_s(self):
        for i, _ in enumerate(self.color_s):
            self.color_s[i] = []
        for v in self.in_s[::-1]:
            if v is None:
                continue
            c = self.graph.vertices[v]
            self.color_s[c].append(v)

    def make_base_bit(self):
        bit = BIT(self.graph.size)
        for i in range(1, self.graph.size + 1):
            bit.add(i, 1)
        return bit

    def solve(self, colored_v_s, bit):
        """
        calc path without colored node
        """
        #print('bit') # debug
        #print(bit.data) # debug
        ans = 0
        for v in colored_v_s:
            #print('v') # debug
            #print(v) # debug
            for to in self.graph.edges[v]:
                if to == self.parent_s[v]:
                    continue
                #print('to') # debug
                #print(to) # debug
                connected = self.calc_connected(to, bit)
                #print('connected') # debug
                #print(connected) # debug
                ans += self.calc(connected)
            self.cut(v, bit)
            #print('bit') # debug
            #print(bit.data) # debug
        connected = self.calc_connected(1, bit)
        ans += self.calc(connected)
        return ans

    def calc_connected(self, v, bit):
        large_key = self.out_s[v]
        large = bit.sum(large_key)
        small_key = self.in_s[v] - 1
        small = bit.sum(small_key)
        return large - small

    def calc(self, a):
        return a * (a + 1) // 2

    def cut(self, v, bit):
        connected = self.calc_connected(v, bit)
        key = self.in_s[v]
        bit.add(key, -1 * connected)









if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    graph.vertices = [0] + list(map(int, input().split()))
    for i in range(n - 1):
        frm, to = (map(int, input().split()))
        graph.add_edge(frm, to)
    ans = Solver(graph).run()

    #print('\33[32m' + 'end' + '\033[0m') # debug


Fixed submission:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class BIT: # binary indexed tree
    """
    http://hos.ac/slides/20140319_bit.pdf
    """

    NORMAL = 0
    ROLLBACK = 1

    def __init__(self, size):
        self.size = size
        self.data = [0] * (size + 1) # var[0] is dummy
        self.status = BIT.NORMAL
        self.history = []

    def add(self, pos, val):
        assert pos > 0, pos
        if self.status == BIT.NORMAL:
            self.history.append((pos, val))
        k = pos
        while k <= self.size:
            self.data[k] += val
            # for next
            k += k & -k

    def sum(self, pos):
        s = 0
        k = pos
        while k > 0:
            s += self.data[k]
            # for next
            k -= k & -k
        return s

    def sum_section(self, frm, to):
        to_val = self.sum(to)
        frm_val = self.sum(frm)
        return to_val - frm_val

    def save(self):
        self.history = []

    def rollback(self):
        self.status = BIT.ROLLBACK
        for (pos, val) in self.history:
            self.add(pos, -1 * val)
        self.history = []
        self.status = BIT.NORMAL

class Graph:

    def __init__(self, size):
        self.size = size
        self.vertices = [0] * size # var[0] is dummy
        self.edges = [None] * size # var[0] is dummy
        for i in range(size):
            self.edges[i] = []

    def add_edge(self, frm, to):
        self.edges[frm].append(to)
        self.edges[to].append(frm)

def make_mybit(size):
    bit = BIT(size)
    for i in range(size):
        bit.add(i + 1, 1)
    bit.save()
    return bit

def init_color_s(size):
    color_s = [None] * graph.size
    for i in range(graph.size):
        color_s[i] = []
    return color_s

def dfs(graph):
    parent_s = [0] * graph.size
    in_s = [0] * graph.size
    out_s = [0] * graph.size
    order = 0 # starts from 1
    color_s = init_color_s(graph.size)
    def _dfs(v, prev):
        nonlocal order
        order += 1
        parent_s[v] = prev
        in_s[v] = order
        c = graph.vertices[v]
        color_s[c].append(v)
        for to in graph.edges[v]:
            if to == prev:
                continue
            _dfs(to, v)
        out_s[v] = order
    _dfs(0, -1)
    return parent_s, in_s, out_s, color_s

def calc(v):
    return v * (v + 1) // 2

def get_connected(bit, v, in_s, out_s):
    #print('v') # debug
    #print(v) # debug
    large_key = out_s[v]
    small_key = in_s[v] - 1
    return bit.sum_section(small_key, large_key)

def calc_for(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    #print('connected') # debug
    #print(connected) # debug
    return calc(connected)

def cut(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    bit.add(in_s[v], -1 * connected)

def solve(n, graph):
    bit = make_mybit(graph.size)
    parent_s, in_s, out_s, color_s = dfs(graph)
    #print('parent_s, in_s, out_s ') # debug
    #print(parent_s, in_s, out_s ) # debug
    #print('color_s') # debug
    #print(color_s) # debug
    for same_color_s in color_s:
        ans = calc(graph.size)
        bit.rollback()
        #print('bit.data') # debug
        #print(bit.data) # debug
        for v in same_color_s[::-1]:
            for to in graph.edges[v]:
                if to == parent_s[v]:
                    continue
                ans -= calc_for(bit, to, in_s, out_s)
            cut(bit, v, in_s, out_s)
        ans -= calc_for(bit, 0, in_s, out_s)
        #print('ans') # debug
        print(ans)






if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    vertices = list(map(int, input().split()))
    for i, c in enumerate(vertices):
        vertices[i] = c - 1
    graph.vertices = vertices
    for _ in range(n - 1):
        frm, to = list(map(int, input().split()))
        frm -= 1
        to -= 1
        graph.add_edge(frm, to)
    solve(n, graph)


    #print('\33[32m' + 'end' + '\033[0m') # debug

Buggy python submission (verdict: Time Limit Exceeded):
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class BIT: # binary indexed tree
    """
    http://hos.ac/slides/20140319_bit.pdf
    """

    def __init__(self, size):
        self.size = size
        self.data = [0] * (size + 1) # var[0] is dummy

    def add(self, pos, val):
        assert(pos > 0)
        k = pos
        while k <= self.size:
            self.data[k] += val
            # for next
            k += k & -k

    def sum(self, pos):
        s = 0
        k = pos
        while k > 0:
            s += self.data[k]
            # for next
            k -= k & -k
        return s

    def make_copy(self):
        bit = BIT(self.size)
        bit.data = self.data[:]
        return bit

class Graph:

    def __init__(self, size):
        self.vertices = [0] * (size + 1) # var[0] is dummy
        self.edges = [None] * (size + 1) # var[0] is dummy
        for i in range(1, size + 1):
            self.edges[i] = set()

    def add_edge(self, frm, to):
        self.edges[frm].add(to)
        self.edges[to].add(frm)

    def size(self):
        return len(self.vertices) - 1

    def vertex_ids(self):
        return range(1, len(self.vertices))

    def get_connect(self, v):
        return self.edges[v]


class Solver:

    def __init__(self, graph):
        self.graph = graph
        self.bit = BIT(graph.size())
        self.in_s = [None] * (graph.size() + 1) # dummy 0 key
        self.out_s = [None] * (graph.size() + 1) # dummy 0 key
        self.parent_s = [None] * (graph.size() + 1) # dummy 0 key
        self.color_s =  [None] * (graph.size() + 1) # dummy 0 key
        for i, _ in enumerate(self.color_s):
            self.color_s[i] = []

    def run(self):
        self.init_by_dfs()
        #print('self.in_s') # debug
        #print(self.in_s) # debug
        #print('self.out_s') # debug
        #print(self.out_s) # debug
        #print('self.parent_s') # debug
        #print(self.parent_s) # debug
        self.init_color_s()
        #print('self.color_s') # debug
        #print(self.color_s) # debug
        base_bit = self.make_base_bit()
        whole = self.calc(self.graph.size())
        #print('whole') # debug
        #print(whole) # debug
        for colored_v_s in self.color_s[1:]:
            #print('colored_v_s') # debug
            #print(colored_v_s) # debug
            bit = base_bit.make_copy()
            complement = self.solve(colored_v_s, bit)
            #print('complement') # debug
            #print(complement) # debug
            #print('ans') # debug
            print(whole - complement)

    def init_by_dfs(self):
        key = 1
        def dfs(v, parent):
            nonlocal key
            self.parent_s[v] = parent
            self.in_s[v] = key
            for to in self.graph.edges[v]:
                if to == parent:
                    continue
                key += 1
                dfs(to, v)
            self.out_s[v] = key
        dfs(1, 0)

    def init_color_s(self):
        for i, _ in enumerate(self.color_s):
            self.color_s[i] = []
        for v in self.in_s[::-1]:
            if v is None:
                continue
            c = self.graph.vertices[v]
            self.color_s[c].append(v)

    def make_base_bit(self):
        bit = BIT(self.graph.size())
        for i in range(1, self.graph.size() + 1):
            bit.add(i, 1)
        return bit

    def solve(self, colored_v_s, bit):
        """
        calc path without colored node
        """
        #print('bit') # debug
        #print(bit.data) # debug
        ans = 0
        for v in colored_v_s:
            #print('v') # debug
            #print(v) # debug
            for to in self.graph.edges[v]:
                if to == self.parent_s[v]:
                    continue
                #print('to') # debug
                #print(to) # debug
                connected = self.calc_connected(to, bit)
                #print('connected') # debug
                #print(connected) # debug
                ans += self.calc(connected)
            self.cut(v, bit)
            #print('bit') # debug
            #print(bit.data) # debug
        connected = self.calc_connected(1, bit)
        ans += self.calc(connected)
        return ans

    def calc_connected(self, v, bit):
        large_key = self.out_s[v]
        large = bit.sum(large_key)
        small_key = self.in_s[v] - 1
        small = bit.sum(small_key)
        return large - small

    def calc(self, a):
        return a * (a + 1) // 2

    def cut(self, v, bit):
        connected = self.calc_connected(v, bit)
        key = self.in_s[v]
        bit.add(key, -1 * connected)









if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    graph.vertices = [0] + list(map(int, input().split()))
    for i in range(n - 1):
        frm, to = (map(int, input().split()))
        graph.add_edge(frm, to)
    ans = Solver(graph).run()

    #print('\33[32m' + 'end' + '\033[0m') # debug


Fixed submission:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10**7)
from pprint import pprint as pp
from pprint import pformat as pf
# @pysnooper.snoop()
#import pysnooper # debug

import math
#from sortedcontainers import SortedList, SortedDict, SortedSet # no in atcoder
import bisect

class BIT: # binary indexed tree
    """
    http://hos.ac/slides/20140319_bit.pdf
    """

    NORMAL = 0
    ROLLBACK = 1

    def __init__(self, size):
        self.size = size
        self.data = [0] * (size + 1) # var[0] is dummy
        self.status = BIT.NORMAL
        self.history = []

    def add(self, pos, val):
        assert pos > 0, pos
        if self.status == BIT.NORMAL:
            self.history.append((pos, val))
        k = pos
        while k <= self.size:
            self.data[k] += val
            # for next
            k += k & -k

    def sum(self, pos):
        s = 0
        k = pos
        while k > 0:
            s += self.data[k]
            # for next
            k -= k & -k
        return s

    def sum_section(self, frm, to):
        to_val = self.sum(to)
        frm_val = self.sum(frm)
        return to_val - frm_val

    def save(self):
        self.history = []

    def rollback(self):
        self.status = BIT.ROLLBACK
        for (pos, val) in self.history:
            self.add(pos, -1 * val)
        self.history = []
        self.status = BIT.NORMAL

class Graph:

    def __init__(self, size):
        self.size = size
        self.vertices = [0] * size # var[0] is dummy
        self.edges = [None] * size # var[0] is dummy
        for i in range(size):
            self.edges[i] = []

    def add_edge(self, frm, to):
        self.edges[frm].append(to)
        self.edges[to].append(frm)

def make_mybit(size):
    bit = BIT(size)
    for i in range(size):
        bit.add(i + 1, 1)
    bit.save()
    return bit

def init_color_s(size):
    color_s = [None] * graph.size
    for i in range(graph.size):
        color_s[i] = []
    return color_s

def dfs(graph):
    parent_s = [0] * graph.size
    in_s = [0] * graph.size
    out_s = [0] * graph.size
    order = 0 # starts from 1
    color_s = init_color_s(graph.size)
    def _dfs(v, prev):
        nonlocal order
        order += 1
        parent_s[v] = prev
        in_s[v] = order
        c = graph.vertices[v]
        color_s[c].append(v)
        for to in graph.edges[v]:
            if to == prev:
                continue
            _dfs(to, v)
        out_s[v] = order
    _dfs(0, -1)
    return parent_s, in_s, out_s, color_s

def calc(v):
    return v * (v + 1) // 2

def get_connected(bit, v, in_s, out_s):
    #print('v') # debug
    #print(v) # debug
    large_key = out_s[v]
    small_key = in_s[v] - 1
    return bit.sum_section(small_key, large_key)

def calc_for(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    #print('connected') # debug
    #print(connected) # debug
    return calc(connected)

def cut(bit, v, in_s, out_s):
    connected = get_connected(bit, v, in_s, out_s)
    bit.add(in_s[v], -1 * connected)

def solve(n, graph):
    bit = make_mybit(graph.size)
    parent_s, in_s, out_s, color_s = dfs(graph)
    #print('parent_s, in_s, out_s ') # debug
    #print(parent_s, in_s, out_s ) # debug
    #print('color_s') # debug
    #print(color_s) # debug
    for same_color_s in color_s:
        ans = calc(graph.size)
        bit.rollback()
        #print('bit.data') # debug
        #print(bit.data) # debug
        for v in same_color_s[::-1]:
            for to in graph.edges[v]:
                if to == parent_s[v]:
                    continue
                ans -= calc_for(bit, to, in_s, out_s)
            cut(bit, v, in_s, out_s)
        ans -= calc_for(bit, 0, in_s, out_s)
        #print('ans') # debug
        print(ans)






if __name__ == '__main__':
    n = int(input())
    graph = Graph(n)
    vertices = list(map(int, input().split()))
    for i, c in enumerate(vertices):
        vertices[i] = c - 1
    graph.vertices = vertices
    for _ in range(n - 1):
        frm, to = list(map(int, input().split()))
        frm -= 1
        to -= 1
        graph.add_edge(frm, to)
    solve(n, graph)


    #print('\33[32m' + 'end' + '\033[0m') # debug