import queue

def read():
    n = int(input())
    edges = []
    for i in range(n - 1):
      edges.append(tuple(map(int, input().split(' '))))
    return (n, edges)

def parse_matrix(n, edges):
    matrix = [[0 for i in range(n + 1)] for j in range(n + 1)]
    for a, b in edges:
        matrix[a][b] = 1
        matrix[b][a] = 1
    return matrix

def parse_relations(n, edges):
    relations = {}
    for a, b in edges:
        if not relations.get(a):
            relations[a] = []
        if not relations.get(b):
            relations[b] = []
        relations[a].append(b)
        relations[b].append(a)
    return relations

def chop(relations, res, fr, flag):
    q = queue.Queue()
    q.put(fr)
    res[fr] = flag
    #new_s_to = s2 if s_to == s1 else s1
    while not q.empty():
        fr = q.get()
        flag = 3 - res[fr]
        for v in relations[fr]:
            if res[v] == 0:
                q.put(v)
                #s_to.add(v)
                res[v] = flag
                #chop(relations, s1, s2, v, new_s_to)

def compute(n, edges):
    # matrix = parse_matrix(n, edges)
    relations = parse_relations(n, edges)

    #s1, s2 = set(), set()
    res = [0] * (n + 1)
    chop(relations, res, 1, 1)
    s1, s2 = 0, 0
    for i in res[1:]:
        if i == 1:
            s1 += 1
        else:
            s2 += 1

    return s1 * s2 - (n - 1)

n, edges = read()
new_edges_count = compute(n, edges)

print(new_edges_count)


import queue

def read():
    n = int(input())
    edges = []
    for i in range(n - 1):
      edges.append(tuple(map(int, input().split(' '))))
    return (n, edges)

def parse_matrix(n, edges):
    matrix = [[0 for i in range(n + 1)] for j in range(n + 1)]
    for a, b in edges:
        matrix[a][b] = 1
        matrix[b][a] = 1
    return matrix

def parse_relations(n, edges):
    relations = {}
    for a, b in edges:
        if not relations.get(a):
            relations[a] = []
        if not relations.get(b):
            relations[b] = []
        relations[a].append(b)
        relations[b].append(a)
    return relations

def chop(relations, s1, s2, fr, s_to):
    q = queue.Queue()
    q.put(fr)
    s_to.add(fr)
    #new_s_to = s2 if s_to == s1 else s1
    while not q.empty():
        fr = q.get()
        s_to = s2
        if fr in s1:
            s_to = s1
        new_s_to = s2 if s_to == s1 else s1
        for v in relations[fr]:
            if v not in new_s_to:
                q.put(v)
                #s_to.add(v)
                new_s_to.add(v)
                #chop(relations, s1, s2, v, new_s_to)

def compute(n, edges):
    # matrix = parse_matrix(n, edges)
    relations = parse_relations(n, edges)

    s1, s2 = set(), set()

    chop(relations, s1, s2, 1, s1)

    return len(s1) * len(s2) - (n - 1)

n, edges = read()
new_edges_count = compute(n, edges)

print(new_edges_count)


def read():
    n = int(input())
    edges = []
    for i in range(n - 1):
      edges.append(tuple(map(int, input().split(' '))))

    return (n, edges)

def parse_matrix(n, edges):
    matrix = [[0 for i in range(n + 1)] for j in range(n + 1)]
    for a, b in edges:
        matrix[a][b] = 1
        matrix[b][a] = 1
    return matrix

def compute(n, matrix):
    s1, s2 = set(), set()

    for i in range(n + 1):
        for j in range(n + 1):
            if matrix[i][j] == 1:
                if i not in s1 and i not in s2:
                    if j not in s1:
                        s1.add(i)
                    else:
                        s2.add(i)
                if j not in s1 and j not in s2:
                    if i not in s1:
                        s1.add(j)
                    else:
                        s2.add(j)

    new_edges_count = 0
    for v1 in s1:
        for v2 in s2:
            if matrix[v1][v2] == 0:
                matrix[v1][v2] = 1
                matrix[v2][v1] = 1
                new_edges_count += 1

    return new_edges_count

n, edges = read()
matrix = parse_matrix(n, edges)
new_edges_count = compute(n, matrix)

print(new_edges_count)


def read():
    n = int(input())
    edges = []
    for i in range(n - 1):
      edges.append(tuple(map(int, input().split(' '))))
    return (n, edges)

def parse_matrix(n, edges):
    matrix = [[0 for i in range(n + 1)] for j in range(n + 1)]
    for a, b in edges:
        matrix[a][b] = 1
        matrix[b][a] = 1
    return matrix

def parse_relations(n, edges):
    relations = {}
    for a, b in edges:
        if not relations.get(a):
            relations[a] = []
        if not relations.get(b):
            relations[b] = []
        relations[a].append(b)
        relations[b].append(a)
    return relations

def chop(relations, s1, s2, fr, s_to):
    new_s_to = s2 if s_to == s1 else s1
    for v in relations[fr]:
        if v not in s_to:
            s_to.add(v)
            chop(relations, s1, s2, v, new_s_to)

def compute(n, edges):
    matrix = parse_matrix(n, edges)
    relations = parse_relations(n, edges)

    s1, s2 = set(), set()

    chop(relations, s1, s2, 1, s1)

    return len(s1) * len(s2) - (n - 1)

n, edges = read()
new_edges_count = compute(n, edges)

print(new_edges_count)


import collections

n = int(input(""))
graph = collections.defaultdict(list)
for i in range(n-1):
	edge = list(map(int,input("").split(" ")))
	graph[edge[0]].append(edge[1])
	graph[edge[1]].append(edge[0])

visited = []
red = 0
green = 0

color = 0
stack = [(1,0)]

while stack:
	node,color = stack.pop(0)
	visited.append(node)
	if color == 0:
		red+=1
	else:
		green +=1
	for children in graph[node]:
		if children not in visited:
			stack.append((children,(color+1)%2))

print(red*green - (n-1))


import collections

n = int(input(""))
graph = collections.defaultdict(list)
for i in range(n-1):
	edge = list(map(int,input("").split(" ")))
	graph[edge[0]].append(edge[1])
	graph[edge[1]].append(edge[0])

visited = []
red = 1
green = 0

color = 1
stack = [1]

while stack:
	node = stack.pop(0)
	visited.append(node)

	for children in graph[node]:
		if children not in visited:
			if color%2 == 0:
				red+=1
			else:
				green+=1

			stack.append(children)
	color = (color+1)%2

print(red*green - (n-1))


import collections

n = int(input(""))
graph = collections.defaultdict(list)
for i in range(n-1):
	edge = list(map(int,input("").split(" ")))
	graph[edge[0]].append(edge[1])
	graph[edge[1]].append(edge[0])

visited = []
red = 0
green = 0
def dfs(graph,node,color,visited):
	global red
	global green
	visited.append(node)
	if color%2 == 0:
		red+=1
	else:
		green+=1

	for children in graph[node]:
		if children not in visited:
			dfs(graph,children,(color%2)+1,visited)

dfs(graph,1,0,visited)

print(red*green - (n-1))


import collections

n = int(input(""))
graph = collections.defaultdict(list)
for i in range(n-1):
	edge = list(map(int,input("").split(" ")))
	graph[edge[0]].append(edge[1])
	graph[edge[1]].append(edge[0])

visited = [False]*(n+1)
red = 0
green = 0

color = 0
stack = [(1,0)]

while stack:
	node,color = stack.pop(0)
	visited[node] = True
	if color == 0:
		red+=1
	else:
		green +=1
	for children in graph[node]:
		if visited[children] == False:
			stack.append((children,(color+1)%2))

print(red*green - (n-1))


import sys

if __name__ == "__main__":
	nodes = int(input())
	adjacency_list = { node : set() for node in range(1, nodes + 1)  }
	for _ in range(nodes - 1):
		a, b = [int(x) for x in input().split()]
		adjacency_list[a].add(b)
		adjacency_list[b].add(a)

	sets = [set(), set()]
	start_node = 1
	start_level = 0
	stack = [(start_node, start_level)]
	visited = [False] * (nodes + 1)
	while stack:
		node, level = stack.pop(-1)
		visited[node] = True

		sets[level % 2].add(node)
		for neighbor in adjacency_list[node]:
			if not visited[neighbor]:
				stack.append((neighbor, level + 1))

	max_edges = len(sets[0]) * len(sets[1])
	print(max_edges - (nodes - 1))


n = int(input())
edges = {}
start = None
edge_count = 0
for _ in range(n-1):
    u, v = map(int, input().strip().split())
    if u in edges:
        edges[u].add(v)
    else:
        edges[u] = {v}

    if v in edges:
        edges[v].add(u)
    else:
        edges[v] = {u}
    edge_count += 1
    if start is None:
        start = u

A, B = set(), set()
visited = {start}
stack = [(start, True)]
while stack:
    n, i = stack.pop()
    if i:
        A.add(n)
    else:
        B.add(n)
    for neighb in edges[n]:
        if neighb not in visited:
            visited.add(neighb)
            stack.append((neighb, not i))

print(len(A)*len(B) - edge_count)


n = int(input())
edges = {}
start = None
edge_count = 0
for _ in range(n-1):
    u, v = map(int, input().strip().split())
    edges[u] = edges.get(u, []) + [v]
    edges[v] = edges.get(v, []) + [u]
    edge_count += 1
    if start is None:
        start = u

A, B = set(), set()
visited = set()
def dfs(n, i=True):
    visited.add(n)
    if i:
        A.add(n)
    else:
        B.add(n)
    for neighb in edges[n]:
        if neighb not in visited:
            dfs(neighb, not i)
dfs(start)
print(len(A)*len(B) - edge_count)


n = int(input())
edges = {}
start = None
edge_count = 0
for _ in range(n-1):
    u, v = map(int, input().strip().split())
    edges[u] = edges.get(u, []) + [v]
    edges[v] = edges.get(v, []) + [u]
    edge_count += 1
    if start is None:
        start = u

A, B = set(), set()
visited = {start}
stack = [start]
i = True
while stack:
    n = stack.pop()
    if i:
        A.add(n)
    else:
        B.add(n)
    for neighb in edges[n]:
        if neighb not in visited:
            visited.add(neighb)
            stack.append(neighb)
    i = not i

print(len(A)*len(B) - edge_count)


n = int(input())
edges = {}
start = None
edge_count = 0
for _ in range(n-1):
    u, v = map(int, input().strip().split())
    edges[u] = edges.get(u, []) + [v]
    edges[v] = edges.get(v, []) + [u]
    edge_count += 1
    if start is None:
        start = u

A, B = set(), set()
visited = {start}
stack = [(start, True)]
i = True
while stack:
    n, i = stack.pop()
    if i:
        A.add(n)
    else:
        B.add(n)
    for neighb in edges[n]:
        if neighb not in visited:
            visited.add(neighb)
            stack.append((neighb, not i))

print(len(A)*len(B) - edge_count)


import sys
sys.setrecursionlimit(2000000)
try:
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except:
    print('help')


try:
    import sys
    sys.setrecursionlimit(200000000)
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except Exception as inst:
    print(type(Exception),inst.args)


    import sys
    sys.setrecursionlimit(200000000)
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[0]*(n))
    t = sum(x)
    print(t*(n-t)-n+1)


try:
    import sys
    sys.setrecursionlimit(200000000)
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except Exception as inst:
    print(inst.args)


try:
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except:
    print(type(x),len(x))


n = int(input())
G = []
for i in range(n):
    G.append([])
for i in range(n-1):
    u,v = [int(x)-1 for x in input().split()]
    G[u].append((v,u))
    G[v].append((u,v))

options = G[0]
visited = [0]*n
visited[0] = 1
colors = [0]*n
while options:
    t = options.pop()
    if visited[t[0]] == 0:
        visited[t[0]] = 1
        colors[t[0]] = 1-colors[t[1]]
        options.extend(G[t[0]])

x = sum(colors)
print(x*(n-x)-n+1)


import sys
sys.setrecursionlimit(2000000)
try:
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except Exception as inst:
    print(type(inst),'what happened omg',inst.args)


try:
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except Exception as inst:
    print(type(Exception))


import sys
sys.setrecursionlimit(200000000)
n = int(input())
G = []

for _ in range(n):
    G.append([])
for i in range(n-1):
    x,y = [int(x)-1 for x in input().split()]
    G[x].append(y)
    G[y].append(x)

def dfs(graph,start,visited,colors):
    visited[start] = 1
    for adjacent in graph[start]:
        if visited[adjacent] == 0:
            visited[adjacent] = 1
            colors[adjacent] = 1-colors[start]
            colors = dfs(graph,adjacent,visited,colors)
    return colors

x = dfs(G,0,[0]*n,[0]*(n))
t = sum(x)
print(t*(n-t)-n+1)


try:
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except Exception as inst:
    print(type(Exception),inst.args)


n = int(input())
G = []
for i in range(n):
    G.append([])
for i in range(n-1):
    u,v = [int(x)-1 for x in input().split()]
    G[u].append(v)
    G[v].append(u)

options = G[0][:]
visited = [0]*n
visited[0] = 1
path = [0]
colors = [0]*n
while options:
    t = options.pop()
    if visited[t] == 0:
        visited[t] = 1
        colors[t] = 1-colors[path[-1]]
        path.append(t)
        options.extend(G[t])

x = sum(colors)
print(x*(n-x)-n+1)


try:
    import sys
    sys.setrecursionlimit(2000000)
    n = int(input())
    G = []

    for _ in range(n):
        G.append([])
    for i in range(n-1):
        x,y = [int(x)-1 for x in input().split()]
        G[x].append(y)
        G[y].append(x)

    def dfs(graph,start,visited,colors):
        visited[start] = 1
        for adjacent in graph[start]:
            if visited[adjacent] == 0:
                visited[adjacent] = 1
                colors[adjacent] = 1-colors[start]
                colors = dfs(graph,adjacent,visited,colors)
        return colors

    x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
    t = sum(x)
    print(t*(n-t)-n+1)
except Exception as inst:
    print(type(Exception))


import sys
sys.setrecursionlimit(2000000)

n = int(input())
G = []

for _ in range(n):
    G.append([])
for i in range(n-1):
    x,y = [int(x)-1 for x in input().split()]
    G[x].append(y)
    G[y].append(x)

def dfs(graph,start,visited,colors):
    visited[start] = 1
    for adjacent in graph[start]:
        if visited[adjacent] == 0:
            visited[adjacent] = 1
            colors[adjacent] = 1-colors[start]
            colors = dfs(graph,adjacent,visited,colors)
    return colors

x = dfs(G,0,[0]*n,[1]+[0]*(n-1))
t = sum(x)
print(t*(n-t)-n+1)


from sys import stdin, stdout, setrecursionlimit
import threading

# tail-recursion optimization
# In case of tail-recusion optimized code, have to use python compiler.
# Otherwise, memory limit may exceed.
# declare the class class Tail_Recursion_Optimization
class Tail_Recursion_Optimization:
    def __init__(self, recursion_limit, stack_size):
        setrecursionlimit(recursion_limit)
        threading.stack_size(stack_size)
        return None

class SOLVE:
    def dfs(self, u, node, color, A, B):

        (A if color[u] else B).append(u)

        for v in node[u]:
            if color[v] == None:
                color[v] = color[u] ^ 1
                self.dfs(v, node, color, A, B)

        return 0

    def solve(self):
        R = stdin.readline
        #f = open('input.txt');R = f.readline
        W = stdout.write

        ans = []

        n = int(R())
        node = [[] for i in range(n+1)]
        for i in range(n-1):
            u, v = [int(x) for x in R().split()]
            node[u].append(v)
            node[v].append(u)

        color    = [None for i in range(n+1)]
        A, B     = [], []
        color[1] = 1
        self.dfs(1, node, color, A, B)

        total = 0
        a, b = len(A), len(B)
        for i in range(1, n+1):
            total += (b if color[i] else a) - len(node[i])
        total //= 2

        W('%d' % total)
        return 0

def main():
    s = SOLVE()
    s.solve()
Tail_Recursion_Optimization(10**7, 2**26)
threading.Thread(target=main).start()


n = int(input())
edges = [[] for i in range(n)]
for i in range(n-1):
    u, v = map(int, input().split())
    edges[u-1].append(v-1)
    edges[v-1].append(u-1)

colors = [-1 for i in range(n)]
dfs = [(0,0)]
while len(dfs) > 0:
    node, color = dfs.pop()
    colors[node] = color
    for neighbor in edges[node]:
        if colors[neighbor] == -1:
            dfs.append((neighbor, 1-color))

blue = len([x for x in colors if x==0])
red = n - blue

total_graph_edges = blue*red
print(blue*red - (n-1))


def TotalEdges(graph):
    total = 0
    for i in graph:
        total += len(graph[i])

    return int(total/2)

def DFS(graph,vertex,isVisited,colors):
    stack = [vertex]
    while stack:
        curr = stack.pop()
        if not isVisited[curr-1]:
            isVisited[curr-1] = True
            if colors[curr-1] == 0:
                colors[curr-1] = 1
            for kid in graph[curr]:
                stack.append(kid)
                colors[kid-1] = 3-colors[curr-1]

def Solve(graph,n):
    colors = [0]*n
    isVisited = [False]*n
    #print (parents)
    for i in graph:
        DFS(graph,i,isVisited,colors)
    first = 0
    second = 0
    #print (colors)
    for i in colors:
        if i == 1:
            first += 1
        else:
            second += 1

    print ((first*second)-TotalEdges(graph))

def main():
    n = int(input())

    graph = {}
    for i in range(1,n+1):
        graph[i] = []

    parents = {}
    for i in range(1,n+1):
        parents[i] = []

    for i in range(n-1):
        start,end = map(int,input().split())
        graph[start].append(end)
        graph[end].append(start)

    Solve(graph,n)

main()


def TotalEdges(graph):
    total = 0
    for i in graph:
        total += len(graph[i])

    return int(total)

def DFS(graph,vertex,isVisited,colors,parents):
    stack = [vertex]
    while stack:
        curr = stack.pop()
        if not isVisited[curr-1]:
            isVisited[curr-1] = True
            if colors[curr-1] == 0:
                if parents[curr] == []:
                    colors[curr-1] = 1
                else:
                    parent = parents[curr][0]
                    colors[curr-1] = 3-colors[parent-1]

def Solve(graph,n,parents):
    colors = [0]*n
    isVisited = [False]*n
    for i in graph:
        DFS(graph,i,isVisited,colors,parents)
    first = 0
    second = 0

    for i in colors:
        if i == 1:
            first += 1
        else:
            second += 1

    print ((first*second)-TotalEdges(graph))

def main():
    n = int(input())

    graph = {}
    for i in range(1,n+1):
        graph[i] = []

    parents = {}
    for i in range(1,n+1):
        parents[i] = []

    for i in range(n-1):
        start,end = map(int,input().split())
        graph[start].append(end)
        parents[end].append(start)

    Solve(graph,n,parents)

main()


from collections import deque, defaultdict
typ = defaultdict(int)
p = defaultdict(list)

n = int(input())
for _ in range(n-1):
    tmp = list(map(int,input().split()))
    u, v = tmp[0], tmp[1]
    p[u].append(v)
    p[v].append(u)

deq = deque()
deq.append((1,1))

s1 = 0
s2 = 0
while len(deq):
    cur = deq.popleft()
    v, t = cur[0], cur[1]
    typ[v] = t
    if t == 1:
        s1 += 1
    else:
        s2 += 1
    for i in p[v]:
        if not typ[i]:
            deq.append((i,(t*2)%3))
print(s1*s2-n+1)


'''input
10
3 8
6 2
9 7
10 1
3 5
1 3
6 7
5 4
3 6
'''
n = int(input())
g = {i:set() for i in range(1, n+1)}
for _ in range(n-1):
	u, v = map(int, input().split())
	g[u].add(v)
	g[v].add(u)
c = [-1] * (n+1)
c[1] = 0
v = [False] * (n+1)
s = [1]
# f = 1
while s:
	x = s.pop(0)
	if v[x]: continue
	v[x] = True
	for y in g[x]:
		if c[y] == -1:
			c[y] = 1 - c[x]
			s.append(y)
	# print(s)
print(c.count(0)*c.count(1) - n + 1)
# z, o = [], []
# e = 0
# for i in range(1, n+1):
# 	if c[i]:
# 		o.append(i)
# 	else:
# 		z.append(i)
# for x in z:
# 	for y in o:
# 		if y not in g[x]:
# 			e += 1
# print(e)


'''input
3
1 2
1 3
'''
n = int(input())
g = {i:set() for i in range(1, n+1)}
for _ in range(n-1):
	u, v = map(int, input().split())
	g[u].add(v)
	g[v].add(u)
c = [-1] * (n+1)
c[1] = 0
v = [False] * (n+1)
s = [1]
# f = 1
while s:
	x = s.pop(0)
	if v[x]: continue
	v[x] = True
	for y in g[x]:
		if c[y] == -1:
			c[y] = 1 - c[x]
			s.append(y)
	# print(s)
z, o = [], []
e = 0
for i in range(1, n+1):
	if c[i]:
		o.append(i)
	else:
		z.append(i)
for x in z:
	for y in o:
		if y not in g[x]:
			e += 1
print(e)


'''input
3
1 2
1 3
'''
n = int(input())
g = {i:set() for i in range(1, n+1)}
for _ in range(n-1):
	u, v = map(int, input().split())
	g[u].add(v)
	g[v].add(u)
c = [-1] * (n+1)
c[1] = 0
v = [False] * (n+1)
s = [1]
f = 1
while s:
	x = s.pop()
	if v[x]: continue
	v[x] = True
	for y in g[x]:
		if c[y] == -1:
			c[y] = f
	f = 1 - f
	s += g[x]
z, o = [], []
e = 0
for i in range(1, n+1):
	if c[i]:
		o.append(i)
	else:
		z.append(i)
for x in z:
	for y in o:
		if y not in g[x]:
			o.remove(y)
			e += 1
print(e)


'''input
3
1 2
1 3
'''
n = int(input())
g = {i:set() for i in range(1, n+1)}
for _ in range(n-1):
	u, v = map(int, input().split())
	g[u].add(v)
	g[v].add(u)
c = [-1] * (n+1)
c[1] = 0
v = [False] * (n+1)
s = [1]
f = 1
while s:
	x = s.pop()
	if v[x]: continue
	v[x] = True
	for y in g[x]:
		if c[y] == -1:
			c[y] = f
	f = 1 - f
	s += g[x]
z, o = [], []
e = 0
for i in range(1, n+1):
	if c[i]:
		o.append(i)
	else:
		z.append(i)
for x in z:
	for y in o:
		if y not in g[x]:
			e += 1
		# 	o.remove(y)
		# e += 1
print(e)


from collections import defaultdict

n = int(input())
degree = [0 for i in range(n+1)]

def BFS(d,x,visited):

	visited[x] = 1
	queue = [(x,1)]

	l1 = set()
	l2 = set()

	while len(queue):
		temp,j = queue.pop()
		visited[temp] = 1
		if j%2 == 1:
			l1.add(temp)
		else:
			l2.add(temp)
		for i in d[temp]:

			if visited[i] == 0:
				queue.append((i,j+1))
	return l1,l2

d = defaultdict(list)
for i in range(n-1):

	u,v = map(int,input().split())
	d[u].append(v)
	d[v].append(v)

	degree[u] = degree[u] + 1
	degree[v] = degree[v] + 1
visited = [0 for i in range(n+1)]
l1,l2 = BFS(d,1,visited)
s = 0
for i in range(1,n+1):

	if i in l1:
		s = s + len(l2)-degree[i]
	elif i in l2:
		s = s + len(l1)-degree[i]

print(s//2)


from collections import defaultdict

n = int(input())
degree = [0 for i in range(n+1)]

def BFS(d,x,visited):

	visited[x] = 1
	queue = [(x,1)]

	l1 = set()
	l2 = set()

	while len(queue):
		temp,j = queue.pop()
		visited[temp] = 1
		if j%2 == 1:
			l1.add(temp)
		else:
			l2.add(temp)
		for i in d[temp]:

			if visited[i] == 0:
				queue.append((i,j+1))
	return l1,l2

d = defaultdict(list)
for i in range(n-1):

	u,v = map(int,input().split())
	d[u].append(v)
	d[v].append(u)

	degree[u] = degree[u] + 1
	degree[v] = degree[v] + 1
visited = [0 for i in range(n+1)]
l1,l2 = BFS(d,1,visited)
s = 0
for i in range(1,n+1):

	if i in l1:
		s = s + len(l2)-degree[i]
	elif i in l2:
		s = s + len(l1)-degree[i]

print(s//2)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

# Reads a string from stdin, splits it by space chars, converts each substring
# to floating point numbber, adds it to a list and returns the list as a result.
def get_floats():
    return [ float(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = set()
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        a.sort()
        links.add((a[0], a[1]))

    left, right = set(), set()
    linked = set()
    while len(left) + len(right) < n:
        changes = set()
        for pair in links:
            a, b = pair
            if a in left or b in right or not left:
                left.add(a)
                right.add(b)
                changes.add(pair)
            elif a in right or b in left:
                right.add(a)
                left.add(b)
                changes.add(pair)
        linked |= changes
        links -= changes

    count = len(left) * len(right) - len(linked)
    print("%d" % count)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

# Reads a string from stdin, splits it by space chars, converts each substring
# to floating point numbber, adds it to a list and returns the list as a result.
def get_floats():
    return [ float(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    import sys

    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = [ set() for i in range(n) ]
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        for j in range(2):
            a[j] -= 1
        links[a[0]].add(a[1])
        links[a[1]].add(a[0])

    left, right = set(), set()
    looked = [ False for i in range(n) ]
    stack = [ 0 ]
    while stack:
        index = stack.pop(0)
        if not looked[index]:
            if index in left or not left:
                right |= links[index]
                left.add(index)
            else:
                left |= links[index]
                right.add(index)
            looked[index] = True
            for i in links[index]:
                stack.append(i)

    count = len(left) * len(right) - n + 1
    print("%d" % count)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

# Reads a string from stdin, splits it by space chars, converts each substring
# to floating point numbber, adds it to a list and returns the list as a result.
def get_floats():
    return [ float(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    import sys

    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = list()
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        a.sort()
        links.append((a[0], a[1]))

    links.sort(key=lambda x: x[0])

    left, right = set(), set()
    if links:
        item = links.pop(0)
        left.add(item[0])
        right.add(item[1])

    while links:
        linked = list()
        for pair in links:
            a, b = pair
            if a in left:
                right.add(b)
            elif a in right:
                left.add(b)
            elif b in left:
                right.add(a)
            elif b in right:
                left.add(a)
            else:
                linked.append(pair)
        links = linked

    count = len(left) * len(right) - n + 1
    print("%d" % count)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

# Reads a string from stdin, splits it by space chars, converts each substring
# to floating point numbber, adds it to a list and returns the list as a result.
def get_floats():
    return [ float(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    import sys

    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = [ set() for i in range(n) ]
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        for i in range(2):
            a[i] -= 1
        links[a[0]].add(a[1])
        links[a[1]].add(a[0])

    left, right = set(), set()
    for i in range(n):
        if i in left or not left:
            right |= links[i]
            left.add(i)
        else:
            left |= links[i]
            right.add(i)

    count = len(left) * len(right) - n + 1
    print("%d" % count)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------
LEFT = 0
RIGHT = 1

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    import sys

    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = [ set() for i in range(n) ]
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        for j in range(2):
            a[j] -= 1
        links[a[0]].add(a[1])
        links[a[1]].add(a[0])

    count = [ 0, 0 ]
    looked = [ False for i in range(n) ]
    stack = [ (0, LEFT) ]
    while stack:
        index, side = stack.pop(0)
        if not looked[index]:
            looked[index] = True
            count[side] += 1
            for i in links[index]:
                stack.append((i, 1 - side))

    res = count[LEFT] * count[RIGHT] - n + 1
    print("%d" % res)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

# Reads a string from stdin, splits it by space chars, converts each substring
# to floating point numbber, adds it to a list and returns the list as a result.
def get_floats():
    return [ float(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    import sys

    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = [ set() for i in range(n) ]
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        for j in range(2):
            a[j] -= 1
        links[a[0]].add(a[1])
        links[a[1]].add(a[0])

    left, right = set(), set()
    for i in range(n):
        if i in left or not left:
            right |= links[i]
            left.add(i)
        else:
            left |= links[i]
            right.add(i)

    count = len(left) * len(right) - n + 1
    print("%d" % count)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

# Reads a string from stdin, splits it by space chars, converts each substring
# to floating point numbber, adds it to a list and returns the list as a result.
def get_floats():
    return [ float(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = set()
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        a.sort()
        links.add((a[0], a[1]))

    left, right = set(), set()
    copy = set() | links
    while links:
        linked = set()
        for pair in links:
            a, b = pair
            if a in left:
                right.add(b)
            elif b in right:
                left.add(a)
            elif a in right:
                left.add(b)
            elif b in left:
                right.add(a)
            elif not left:
                left.add(a)
                right.add(b)
            else:
                linked.add(pair)
        links = linked

    count = len(left) * len(right) - len(copy)
    print("%d" % count)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

# Reads a string from stdin, splits it by space chars, converts each substring
# to floating point numbber, adds it to a list and returns the list as a result.
def get_floats():
    return [ float(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = set()
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        a.sort()
        links.add((a[0], a[1]))

    left, right = set(), set()
    linked = set()
    while len(left) + len(right) < n:
        changes = set()
        for pair in links:
            a, b = pair
            if a in left or b in right or not left:
                left.add(a)
                right.add(b)
                changes.add(pair)
            elif a in right or b in left:
                right.add(a)
                left.add(b)
                changes.add(pair)
        linked |= changes
        links -= changes

    count = 0

    for l in left:
        for r in right:
            if (min(l, r), max(l, r)) not in linked:
                count += 1

    print("%d" % count)


#!/usr/bin/env python3
# encoding: utf-8

#----------
# Constants
#----------
LEFT = 0
RIGHT = 1

#----------
# Functions
#----------

# Reads a string from stdin, splits it by space chars, converts each
# substring to int, adds it to a list and returns the list as a result.
def get_ints():
    return [ int(n) for n in input().split() ]

#----------
# Execution start point
#----------

if __name__ == "__main__":
    import sys

    a = get_ints()
    assert len(a) == 1
    n = a[0]

    links = [ set() for i in range(n) ]
    for i in range(n-1):
        a = get_ints()
        assert len(a) == 2
        for j in range(2):
            a[j] -= 1
        links[a[0]].add(a[1])
        links[a[1]].add(a[0])

    count = [ 0, 0 ]
    looked = [ False for i in range(n) ]
    stack = dict()
    stack[0] = LEFT
    while stack:
        index, side = stack.popitem()
        if not looked[index]:
            looked[index] = True
            count[side] += 1
            for i in links[index]:
                stack[i] = 1 - side

    res = count[LEFT] * count[RIGHT] - n + 1
    print("%d" % res)


from collections import defaultdict
n = int(input())
graph = defaultdict(set)
for i in range(n - 1):
    a, b = input().split()
    graph[a].add(b)
    graph[b].add(a)
start = next(iter(graph.keys()))
left, right = set([start]), set()
frontier = [(start, True)]
while frontier:
    node, is_left = frontier.pop()
    for neighbor in graph[node]:
        if is_left and neighbor in right or not is_left and neighbor in left:
            continue
        frontier.append((neighbor, not is_left))
        if is_left:
            right.add(neighbor)
        else:
            left.add(neighbor)

print(sum(len(right) - len(graph[a]) for a in left))


from collections import defaultdict
n = int(input())
graph = defaultdict(set)
num_edges = n - 1
for i in range(num_edges):
    a, b = input().split()
    graph[a].add(b)
    graph[b].add(a)
start = next(iter(graph.keys()))
left, right = set([start]), set()
frontier = [(start, True)]
while frontier:
    node, is_left = frontier.pop()
    for neighbor in graph[node]:
        if is_left and neighbor in right or not is_left and neighbor in left:
            continue
        frontier.append((neighbor, not is_left))
        if is_left:
            right.add(neighbor)
        else:
            left.add(neighbor)

print(len(left) * len(right) - num_edges)


n = int(input())
store = [[] for _ in range (n + 1)]
mark = [ 0 for _ in range(n + 1)]
markX = [ 0 for _ in range(n + 1)]
sumA = 0
part = 0
left = [1]
l,r = (0,0)
for i in range(n-1):
    u,v = map(int,input().split())
    store[v].append(u)
    store[u].append(v)
temp = []
if n !=1:
    l +=1
    mark[1]= len(store[1])
    for ii in store[1]:
        temp.append(ii)
        markX[ii] = 1
    while(len(temp)>0):
        next = []
        part^=1
        if part:
            for item in temp:
                if not mark[item]:
                    r+=1
                    for ii in store[item]:
                        if markX[ii] == 0:
                            markX[ii] = 1
                            next.append(ii)
                    mark[item] = 1
        else:
            for item in temp:
                if not mark[item]:
                    for ii in store[item]:
                        if markX[ii] == 0:
                            markX[ii] = 1
                            next.append(ii)
                    left.append(item)
                    mark[item] = len(store[item])

        temp= next[::]
for v in left:
    sumA += r - mark[v]
print(sumA)


n = int(input())
store = [[] for _ in range (10**5 + 1)]
mark = [ 0 for _ in range(10**5 + 1)]
sumA = 0
a = []
left= []
right = []
for i in range(n-1):
    u,v = map(int,input().split())
    store[v].append(u)
    store[u].append(v)
    a.append([u,v])
if n !=1:
    next = a.pop(0)
    left.append(next[0])
    right.append(next[1])
    mark[next[0]] = 'l'
    mark[next[1]] = 'r'
    while(len(a)>0):
        next = a.pop(0)
        if mark[next[0]]==0 and mark[next[1]] ==0:
            a.append(next)
        elif mark[next[0]]==0:
            if mark[next[1]]=='l':
                mark[next[0]] = 'r'
                right.append(next[0])
            else:
                mark[next[0]] = 'l'
                left.append(next[0])
        elif mark[next[1]]==0:
            if mark[next[0]]=='l':
                mark[next[1]] = 'r'
                right.append(next[1])
            else:
                mark[next[1]] = 'l'
                left.append(next[1])
need = len(right)
for num in left:
    sumA+= need- len(store[num])
print(sumA)


n = int(input())
store = [0 for _ in range (10**5 + 1)]
mark = [ 0 for _ in range(10**5 + 1)]
sumA = 0
a = []
left= []
right = []
l,r = (1,1)
for i in range(n-1):
    u,v = map(int,input().split())
    store[v]+=1
    store[u]+=1
    a.append([u,v])
if n !=1:
    next = a.pop(0)
    left.append(next[0])
    right.append(next[1])
    mark[next[0]] = 'l'
    mark[next[1]] = 'r'
    while(len(a)>0):
        next = a.pop(0)
        if mark[next[0]]==0 and mark[next[1]] ==0:
            a.append(next)
        elif mark[next[0]]==0:
            if mark[next[1]]=='l':
                mark[next[0]] = 'r'
                r+=1
            else:
                mark[next[0]] = 'l'
                left.append(next[0])
        elif mark[next[1]]==0:
            if mark[next[0]]=='l':
                mark[next[1]] = 'r'
                r+=1
            else:
                mark[next[1]] = 'l'
                left.append(next[1])
for num in left:
    sumA+= r- store[num]
print(sumA)


n = int(input())
store = [[] for _ in range (n + 1)]
mark = [ 0 for _ in range(n + 1)]
sumA = 0
part = 0
left = [1]
l,r = (0,0)
for i in range(n-1):
    u,v = map(int,input().split())
    store[v].append(u)
    store[u].append(v)
temp = []
if n !=1:
    l +=1
    mark[1]= len(store[1])
    temp=temp+store[1]
    while(len(temp)>0):
        next = []
        part^=1
        if part:
            for item in temp:
                if not mark[item]:
                    r+=1
                    next= next+store[item]
                    mark[item] = 1
        else:
            for item in temp:
                if not mark[item]:
                    next= next + store[item]
                    mark[item] = len(store[item])
                    left.append(item)
        temp= next[::]
for v in left:
    sumA += r - mark[v]
print(sumA)


# author : http://codeforces.com/profile/kautsiitd

n = int(input())
graph = [[] for i in range(n+1)]
for _ in range(n-1):
    a,b = map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)

group = [0,0]

def dfs(parent,currentNode,currentHeight):
    group[currentHeight%2] += 1
    for i in graph[currentNode]:
        if i!=parent:
            dfs(currentNode,i,currentHeight+1)

dfs(0,1,0)
print(group[0]*group[1]-n+1)


from collections import deque

n = int(input())
g = [[] for i in range(n+1)]
for i in range(n-1):
    u, v = map(int, input().split())
    g[u].append(v)
    g[v].append(u)

f = [0]*(n+1)
c = [1, 0]
q = deque()
q.appendleft((1, 0))
while q:
    u, p = q.pop()
    for v in g[u]:
        if v != p:
            f[v] = (f[u] + 1) % 2
            c[f[v]] += 1
            q.appendleft((v, u))

ans = 0
for u in range(1, n+1):
    n = len(g[u])
    opp = c[1-f[u]]
    ans += opp - n

print(ans // 2)


import sys, threading

def f(i):
	if i:
		f(i-1)

def main():
	f(100000)

sys.setrecursionlimit(1000000)
threading.stack_size(1024000)
thread = threading.Thread(target=main)
thread.start()
#main()


# author : http://codeforces.com/profile/kautsiitd

import sys
sys.setrecursionlimit(1000000)

n = int(input())
graph = [[] for i in range(n+1)]
for _ in range(n-1):
    a,b = map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)

group = [0,0]

def dfs(parent,currentNode,currentHeight):
    group[currentHeight%2] += 1
    for i in graph[currentNode]:
        if i!=parent:
            dfs(currentNode,i,currentHeight+1)

dfs(0,1,0)
print(group[0]*group[1]-n+1)


n=int(input())
d={}
for i in range(1,n+1):
    d[i]=[]

for _ in range(n-1):
    u,v=map(int,input().split(" "))
    d[u].append(v)
    d[v].append(u)

arr=[-1]*(n+1)
#print(d)
visited=[False]*(n+1)

stack=[1]
visited[1]=True
arr[1]=0
while len(stack)!=0:
    x=stack.pop(0)
    for i in d[x]:
        if not visited[i]:
            arr[i]=1-arr[x]
            stack.append(i)
            visited[i]=True

zero=0
one=0
for i in range(1,n+1):
    if arr[i]==0:
        zero+=1
    else:
        one+=1

print(zero*one-(n-1))


#include <cstdarg>
#include <cmath>
#include <cstdio>
#include <bits/stdc++.h>
using namespace std;

template <typename T>
T input(T& v) { cin >> v; return v; }
template<typename T, typename... Tail>
void input(T& v, Tail&... t) { cin >> v; input(t...); }
template <typename T>
void print(T t) { cout << t; }
template<typename T, typename... Args>
void print(T t, Args... args) { cout << t; print(args...); }

#define _for(i,s,e) for(i=s;i<e;i++)
#define _fok(i,s,e,k) for(i=s;i<e;i+=k)
typedef long long ll;

//
// gi gi gi gi gi gi gi gi gi gi gi gi
//
const int SZ = 1e5+10;
set<ll> g[SZ];
ll vis[SZ];
ll q[SZ];
void re(ll& x)
{
    bool f=false;char ch=getchar();x=0;
    while(ch<48)f=(ch=='-'),ch=getchar();
    while(47<ch)x=(x<<3)+(x<<1)+ch-48,ch=getchar();
    if(f)x=-x;
}
int main() {
    //freopen("in","r",stdin);
    ll n, i, u, v, size;
    re(n);
    ll a = 1, b = 0, k = 0;
    _for(i,0,n-1) {
        re(u); re(v);
        g[u].insert(v);
        g[v].insert(u);
    }
    ll is = 0, ie = 1;
    q[0] = v;
    for(;;size = 0) {
        _for(i,is,ie) {
            v = q[i];
            if(!vis[v]) for(auto u:g[v]) if(!vis[u]) q[ie + size++] = u;
            vis[v] = 1;
        }
        if(size == 0) break;
        if(k++ % 2) a += size; else b += size;
        is = ie; ie += size;
    }
    print(a * b - n + 1, "\n");
}


read = lambda: tuple(map(int, input().split()))
n = read()[0]
eds = []

g = {}
k = {}
for i in range(n - 1):
    u, v = read()
    k[v] = True
    eds += [(u, v)]
    if not u in g:
        g[u] = [v]
    else:
        g[u] += [v]

for ed in eds:
    if not ed[0] in k:
        root = ed[0]
        break

def req(vl):
    vs = []
    for v in vl:
        if v in g:
            vs += g[v]
    return vs

vs = [root]
k = 0

z = [0, 1]

while True:
    vs = req(vs)
    if len(vs) == 0: break
    z[k % 2] += len(vs)
    k += 1

print(z[0] * z[1] - n + 1)


read = lambda: tuple(map(int, input().split()))
n = read()[0]
eds = []

g = {}
k = {}
for i in range(n - 1):
    u, v = read()
    r = u
    k[v] = True
    if not u in g:
        g[u] = [v]
    else:
        g[u] += [v]

    if not v in g:
        g[v] = [u]
    else:
        g[v] += [u]

def req(vl, visited):
    vs = []
    for v in vl:
        if v in g and not v in visited:
            vs += [el for el in g[v] if not el in visited]
            visited[v] = True
    return vs

vs = [r]
k = 0

z = [0, 1]
visited = {}

while True:
    vs = req(vs, visited)
    if len(vs) == 0: break
    z[k % 2] += len(vs)
    k += 1

print(z[0] * z[1] - n + 1)


read = lambda: tuple(map(int, input().split()))
n = read()[0]
eds = []

g = {}
k = {}
for i in range(n - 1):
    u, v = read()
    if u > v: u, v = v, u
    k[v] = True
    eds += [(u, v)]
    if not u in g:
        g[u] = [v]
    else:
        g[u] += [v]

for ed in eds:
    if not ed[0] in k:
        root = ed[0]
        break

def req(vl):
    vs = []
    for v in vl:
        if v in g:
            vs += g[v]
    return vs

vs = [root]
k = 0

z = [0, 1]

while True:
    vs = req(vs)
    if len(vs) == 0: break
    z[k % 2] += len(vs)
    k += 1

print(z[0] * z[1] - n + 1)


n=int(input())
graph=[None]*(n+1)
for i in range(1,n+1):
	graph[i]=[]
for i in range(n-1):
	u,v=map(int,input().split())
	graph[u].append(v)
	graph[v].append(u)

is_u=[None]*(n+1)
is_u[1]=True
stack=[1]
while stack:
	top=stack.pop()
	vals=graph[top]
	for i in range(len(vals)):
		cur=vals[i]
		if is_u[cur]==None:
			is_u[cur]=not is_u[top]
			stack.append(cur)
count_u=is_u.count(True)
print(count_u*(n-count_u)-(n-1))


n=int(input())
graph=[None]*(n+1)
for i in range(n-1):
	u,v=map(int,input().split())
	if graph[u]==None:
		graph[u]=[v]
	else:
		graph[u].append(v)
	if graph[v]==None:
		graph[v]=[u]
	else:
		graph[v].append(u)

is_u=[None]*(n+1)
is_u[1]=True
stack=[1]
while stack:
	top=stack.pop()
	vals=graph[top]
	for i in range(len(vals)):
		cur=vals[i]
		if is_u[cur]==None:
			is_u[cur]=not is_u[top]
			stack.append(cur)
count_u=is_u.count(True)
print(count_u*(n-count_u)-(n-1))


n=int(input())
graph=[None]*(n+1)
for i in range(n-1):
	u,v=map(int,input().split())
	if graph[u]==None:
		graph[u]=[v]
	else:
		graph[u].append(v)
	if graph[v]==None:
		graph[v]=[u]
	else:
		graph[v].append(u)

is_u=[None]*(n+1)
for i in range(1,n+1):
	if is_u[i]==None:
		is_u[i]=True
		stack=[i]
		while stack:
			top=stack.pop()
			vals=graph[top]
			for j in range(len(vals)):
				cur=vals[j]
				if is_u[cur]==None:
					is_u[cur]=not is_u[top]
					stack.append(cur)
count_u=is_u.count(True)
print(count_u*(n-count_u)-(n-1))


n = int(input())
e = {}

for i in range(n-1):
    a, b = map(int, input().split(' '))

    x = e.get(a, [])
    x.append(b)
    e[a] = x
    x = e.get(b, [])
    x.append(a)
    e[b] = x

x = 1
y = 0

temp1 = [1]
temp2 = []
seen = set()
k = 0
while len(temp1) > 0:
    for i in temp1:
        seen.add(i)
        for j in e[i]:
            if j not in seen:
                temp2.append(j)
                if k%2 == 0: y += 1
                else: x += 1

    temp1 = temp2
    temp2 = []
    k += 1
print(x*y-n+1)


n = int(input())
e = {}

for i in range(n-1):
    a, b = map(int, input().split(' '))

    x = e.get(a, [])
    x.append(b)
    e[a] = x
    x = e.get(b, [])
    x.append(a)
    e[b] = x

c = set()
d = set()

c.add(1)
temp = [1]
seen = set()
while len(temp) > 0:
    i = temp.pop(0)
    seen.add(i)
    if i in c:
        for j in e[i]:
            d.add(j)
            if j not in seen: temp.append(j)
    else:
        for j in e[i]:
            c.add(j)
            if j not in seen: temp.append(j)

x = len(c)
y = len(d)

print(x*y-n+1)


import sys
sys.setrecursionlimit(3000000000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


n=int(input())
g=[[] for _ in range(n+1)]
for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

st=[(1,0,0)]
m=0
while st:
    u,p,c=st.pop()
    m += c
    st.extend((v,u,1-c) for v in g[u] if v!=p)

print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(10000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(50000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(1000000000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(1000000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(100000000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(2000000000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(10000000000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


import sys
sys.setrecursionlimit(5000000000)

n=int(input())
g=[[] for _ in range(n+1)]

for _ in range(n-1):
    u,v=map(int,input().split())
    g[u].append(v)
    g[v].append(u)

def dfs(u,p,c):
    return c+sum(dfs(v,u,1-c) for v in g[u] if v!=p)

m=dfs(1,0,0)
print(m*(n-m)-n+1)


#include <iostream>
#include <vector>
#include <queue>

using namespace std;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	int n;
	cin >> n;
	vector<vector<int>> g(n);
	for (int i = 1; i < n; ++i) {
		int u, v;
		cin >> u >> v;
		--u; --v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	vector<int> c(n, -1);
	c[0] = 0;
	queue<int> q;
	q.push(0);
	int count = 1;
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (int v : g[u]) {
			if (c[v] == -1) {
				c[v] = 1 - c[u];
				if (c[v] == 0)
					++count;
				q.push(v);
			}
		}
	}
	cout << (long long)count * (n - count) - n + 1 << '\n';
}


# -*- coding: utf-8 -*-
"""
Created on Thu Jun 11 09:37:22 2020

@author: Harshal
"""

import collections
graph= collections.defaultdict(list)
n=int(input())
for i in range(n-1):
    x,y=map(int,input().split())
    graph[x].append(y)
    graph[y].append(x)
count=[0]*2
def dfs(node,prev,color):
    count[color]+=1
    for i in graph[node]:
        if i !=prev:
            dfs(i,node,not color)
dfs(1,0,0)
print(count[0]*count[1]-n+1)


# -*- coding: utf-8 -*-
"""
Created on Thu Jun 11 09:37:22 2020

@author: Harshal
"""
n = int(input())
d = [[] for _ in range(n+1)]
for _ in range(n-1):
    u, v = map(int, input().split())
    d[u] += [v]
    d[v] += [u]
l = [None]*(n+1)
l[1] = 1
temp = [1]
while temp:
    top = temp.pop()
    for x in d[top]:
        if l[x] == None:
            l[x] = 1-l[top]
            temp.append(x)
s = l.count(1)
print(s*(n-s)-n+1)


n = int(input())
a = [[] for i in range(n)]
for i in range(n-1):
    f,s = map(int, input().split())
    a[s-1].append(f)
    a[f-1].append(s)

q = [1]
f1 = [1] + [0] * n

while len(q) != 0 :
    x = q.pop()
    for i in a[x-1]:
        if f1[i-1] == 0:
            q.append(i)
            f1[i-1] =- f1[x-1]
print(f1.count(-1) * (n-f1.count(-1)) - n+1)


n = int(input())
a = [[] for i in range(n)]
for i in range(n-1):
    f,s = map(int, input().split())
    a[s-1].append(f)
    a[f-1].append(s)
print(a)
q = [1]
f1 = [1] + [0] * n
print(f1)
while len(q) != 0 :
    x = q.pop()
    for i in a[x-1]:
        if f1[i-1] == 0:
            q.append(i)
            f1[i-1] =- f1[x-1]
print(f1.count(-1) * (n-f1.count(-1)) - n+1)


n=int(input())
a=[]

visited=[]
tovisit=[]
for i in range(n+1):
    a.append([])
    visited.append(0)
for i in range(n-1):
    u,v=map(int,input().split())
    a[u].append(v)
    a[v].append(u)
i=0
tovisit.append((1,1))
while(len(tovisit)>0):
    (x,y)=tovisit.pop()
    if(visited[x]):
        pass
    else:
        visited[x]=y
        for i in a[x]:
            tovisit.append((i,-1*y))
set1=0
set2=0
for i in range(1,n+1):
    if(visited[i]==1):
        set1+=1
    else:
        set2+=1
print(set1*set2-(n-1))


double_graph = {}
n = int(input())
R = set()
L = set()
for i in range(n-1):
    a1, a2 = input().split()
    if a1 not in double_graph.keys():
        double_graph[a1] = []
    if a2 not in double_graph.keys():
        double_graph[a2] = []
    double_graph[a1].append(a2)
    double_graph[a2].append(a1)

stack = [('1', 0)]
visited = {'1'}
L_R = [0, 0]

while stack:
    a1, count = stack.pop()
    L_R[count] += 1
    for a2 in double_graph[a1]:
        if a2 not in visited:
            stack.append((a2, 1 - count))
            visited.add(a2)

ans = L_R[0]*L_R[1] - n + 1
print(ans)


#!/usr/bin/env python3

N = int(input())
adj = [[] for _ in range(N)]

for _ in range(N - 1):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    adj[a].append(b)
    adj[b].append(a)

visited = {0}
cur_level = [0]
level_sizes = [1]

while cur_level:
    next_level = []
    for n in cur_level:
        for m in adj[n]:
            if m not in visited:
                next_level.append(m)
                visited.add(m)

    level_sizes.append(len(next_level))
    cur_level = next_level

out = 0
for i in range(3):
    A = level_sizes[i::3]
    acc = 0

    for n in A:
        out += n * acc
        acc += n

print(out)


#!/usr/bin/env python3

N = int(input())
adj = [[] for _ in range(N)]

for _ in range(N - 1):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    adj[a].append(b)
    adj[b].append(a)

visited = {0}
cur_level = [0]
levels = []

while cur_level:
    levels.append(cur_level)
    next_level = []
    for n in cur_level:
        for m in adj[n]:
            if m not in visited:
                next_level.append(m)
                visited.add(m)
    cur_level = next_level

color_0 = sum(map(len, levels[0::2]))
color_1 = sum(map(len, levels[1::2]))

out = 0
for i, level in enumerate(levels):
    for n in level:
        if i % 2 == 0:
            out += color_1 - len(adj[n])
        else:
            out += color_0 - len(adj[n])
        # print(n, out)

assert out % 2 == 0
print(out // 2)


from collections import defaultdict

n = int(input())
graph = defaultdict(list)
for i in range(n - 1):
    edge = list(map(int, input().split(' ')))
    graph[edge[0]] += [edge[1]]
    graph[edge[1]] += [edge[0]]

cs = [0, 0]

def dfs(v, side, prev):
    cs[side] += 1
    for next in graph[v]:
        if next != prev:
            dfs(next, 1-side, v)

dfs(1, 0, -1)

print(cs[0] * cs[1] - (n - 1))


from collections import defaultdict

n = int(input())
graph = defaultdict(list)
for i in range(n - 1):
    edge = list(map(int, input().split(' ')))
    graph[edge[0]] += [edge[1]]
    graph[edge[1]] += [edge[0]]

cs = [0, 0]

size = 0
vs = [-1] * (n + 3)
ps = [-1] * (n + 3)
ss = [-1] * (n + 3)

vs[size] = 1
ps[size] = -1
ss[size] = 0
size += 1

while size > 0:
    v = vs[size - 1]
    prev = ps[size - 1]
    side = ss[size - 1]
    size -= 1

    cs[side] += 1
    for next in graph[v]:
        if next != prev:
            vs[size] = next
            ps[size] = v
            ss[size] = 1 - side
            size += 1

print(cs[0] * cs[1] - (n - 1))


import sys, resource
from collections import defaultdict
resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))
sys.setrecursionlimit(1000000)

n = int(input())
graph = defaultdict(list)
for i in range(n - 1):
    edge = list(map(int, input().split(' ')))
    graph[edge[0]] += [edge[1]]
    graph[edge[1]] += [edge[0]]

cs = [0, 0]

def dfs(v, side, prev):
    cs[side] += 1
    for next in graph[v]:
        if next != prev:
            dfs(next, 1-side, v)

dfs(1, 0, -1)

print(cs[0] * cs[1] - (n - 1))


import sys
from collections import defaultdict
sys.setrecursionlimit(1000000)

n = int(input())
graph = defaultdict(list)
for i in range(n - 1):
    edge = list(map(int, input().split(' ')))
    graph[edge[0]] += [edge[1]]
    graph[edge[1]] += [edge[0]]

cs = [0, 0]

def dfs(v, side, prev):
    cs[side] += 1
    for next in graph[v]:
        if next != prev:
            dfs(next, 1-side, v)

dfs(1, 0, -1)

print(cs[0] * cs[1] - (n - 1))


from collections import Counter,defaultdict,deque
#alph = 'abcdefghijklmnopqrstuvwxyz'
#from math import factorial as fact
#import math

#tt = 1#int(input())
#total=0
#n = int(input())
#n,m,k = [int(x) for x in input().split()]
#n = int(input())
#n,m = [int(x) for x in input().split()]
n = int(input())

def BFS(cmap,v):
   #order = deque([[]])
   visited = [False]*len(cmap)
   q = deque([v])
   level = 0

   blue = 0
   red = 0
   while len(q)!=0:
      for i in range(len(q)):
         vertex = q.popleft()
         if not visited[vertex]:
            if level%2==0:
               blue+=1
            else:
               red+=1
            #order[-1].append(vertex)
            visited[vertex] = True
            #globalvisited[vertex] = True
            q.extend(cmap[vertex])
      level+=1
      #order.append([])
   return blue,red

connections = [[] for x in range(n)]
for i in range(n-1):
   a,b = [int(x)-1 for x in input().split()]
   connections[a].append(b)
   connections[b].append(a)

b,r = BFS(connections,0)
print(b*r-n+1)


n=int(input());l=[1]+[0]*n;d=[[]for _ in range(n)];c=[0]
for _ in range(n-1):
  a,b=map(int,input().split());d[a-1]+=[b-1];d[b-1]+=[a-1]
while c:
  x=c.pop()
  for y in d[x]:
    if not l[y]:
      c+=[y];l[y]=-l[x]
r=l.count(1);print(r*(n-r)-n+1)


n=int(input())
import sys
sys.setrecursionlimit(1000000000)
a=[set() for i in range(n)]
for i in range(n-1):
    first,second=input().split()
    first=int(first)
    second=int(second)
    a[first-1].add(second)
    a[second-1].add(first)
r=[0 for i in range(n+1)]
kol=[1,1]
def dfs(x,fl):
    global kol,r
    r[x]=1
    kol[fl]+=len(a[x-1])-1
    fl=(fl+1)%2
    for i in (a[x-1]):
        if r[i]==0:
            dfs(i,fl)
dfs(1,1)
print(kol[1]*kol[0]-n+1)


#include <bits/stdc++.h>
#define mp make_pair
#define sqr(x) (x)*(x)
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=500007;
const ll inf=1<<29;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll c[maxn],sum[maxn];
vector<int> g[maxn];
int du[maxn];
int main(){
    int t=read();
    while(t--){
        int n=read(),m=read();
        ll x=0;
        for(int i=1;i<=n;i++){
            sum[i]=0;g[i].clear();du[i]=0;
            c[i]=read();x+=c[i];
        }
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            sum[u]+=c[v];g[u].push_back(v);du[v]++;
        }
        for(int i=1;i<=n;i++){
            ll r=0;
            for(int k=0;k<g[i].size();k++)
            if(du[g[i][k]]==1) r+=c[g[i][k]];
            x=gcd(x,r);
        }
        for(int i=1;i<=n;i++) x=gcd(x,sum[i]);
        printf("%lld\n",x);
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define sqr(x) (x)*(x)
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=500007;
const ll inf=1<<29;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll c[maxn],sum[maxn];
struct node{
    vector<int> s;
    bool operator < (node a) const{
        if(s.size()!=a.s.size()) return s.size()<a.s.size();
        for(int i=0;i<s.size();i++){
            if(s[i]!=a.s[i]) return s[i]<a.s[i];
        }
        return false;
    }
}nd[maxn];
map<node,ll> aa;
int main(){
    int t=read();
    while(t--){
        int n=read(),m=read();
        ll x=0;
        for(int i=1;i<=n;i++){
            sum[i]=0;
            c[i]=read();
            nd[i].s.clear();
        }
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            sum[u]+=c[v];nd[v].s.push_back(u);
        }
        aa.clear();
        for(int i=1;i<=n;i++) sort(nd[i].s.begin(),nd[i].s.end()),aa[nd[i]]+=c[i];
        for(auto i:aa) if(i.first.s.size()>=1) x=gcd(x,i.second);
        printf("%lld\n",x);
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define sqr(x) (x)*(x)
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=500007;
const ll inf=1<<29;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll c[maxn],sum[maxn];
struct node{
    vector<int> s;
    bool operator < (node a) const{
        if(s.size()!=a.s.size()) return s.size()<a.s.size();
        for(int i=0;i<s.size();i++){
            if(s[i]!=a.s[i]) return s[i]<a.s[i];
        }
        return false;
    }
}nd[maxn];
map<node,ll> aa;
vector<int> g[maxn];
int du[maxn];
int main(){
    int t=read();
    while(t--){
        int n=read(),m=read();
        ll x=0;
        for(int i=1;i<=n;i++){
            sum[i]=0;g[i].clear();du[i]=0;
            c[i]=read();x+=c[i];
        }
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            sum[u]+=c[v];g[u].push_back(v);du[v]++;
        }
        for(int i=1;i<=n;i++){
            ll r=0;
            for(int k=0;k<g[i].size();k++)
            if(du[g[i][k]]==1) r+=c[g[i][k]];
            x=gcd(x,r);
        }
        for(int i=1;i<=n;i++) x=gcd(x,sum[i]);
        printf("%lld\n",x);
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define sqr(x) (x)*(x)
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=500007;
const ll inf=1<<29;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll c[maxn],sum[maxn];
struct node{
    vector<int> s;
    bool operator < (node a) const{
        if(s.size()!=a.s.size()) return s.size()<a.s.size();
        for(int i=0;i<s.size();i++){
            if(s[i]!=a.s[i]) return s[i]<a.s[i];
        }
        return false;
    }
}nd[maxn];
map<node,ll> aa;
vector<int> g[maxn];
int du[maxn];
int main(){
    int t=read();
    while(t--){
        int n=read(),m=read();
        ll x=0;
        for(int i=1;i<=n;i++){
            sum[i]=0;g[i].clear();du[i]=0;
            c[i]=read();x+=c[i];
        }
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            sum[u]+=c[v];g[u].push_back(v);du[v]++;
        }
        for(int i=1;i<=n;i++){
            ll r=0;
            for(int k=0;k<g[i].size();k++)
            if(du[g[i][k]]==1) r+=c[g[i][k]];
            x=gcd(x,r);
        }
        printf("%lld\n",x);
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define sqr(x) (x)*(x)
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=500007;
const ll inf=1<<29;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll c[maxn],sum[maxn];
struct node{
    vector<int> s;
    bool operator < (node a) const{
        if(s.size()!=a.s.size()) return s.size()<a.s.size();
        for(int i=0;i<s.size();i++){
            if(s[i]!=a.s[i]) return s[i]<a.s[i];
        }
        return false;
    }
}nd[maxn];
map<node,ll> aa;
vector<int> g[maxn];
int du[maxn];
int main(){
    int t=read();
    while(t--){
        int n=read(),m=read();
        ll x=0;
        for(int i=1;i<=n;i++){
            sum[i]=0;g[i].clear();
            c[i]=read();x+=c[i];
        }
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            sum[u]+=c[v];g[u].push_back(v);du[v]++;
        }
        for(int i=1;i<=n;i++){
            ll r=0;
            for(int k=0;k<g[i].size();k++)
            if(du[g[i][k]]==1) r+=c[g[i][k]];
            x=gcd(x,r);
        }
        for(int i=1;i<=n;i++) x=gcd(x,sum[i]);
        printf("%lld\n",x);
    }
    return 0;
}


#include <bits/stdc++.h>
#define mp make_pair
#define sqr(x) (x)*(x)
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=500007;
const ll inf=1<<29;
ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll c[maxn],sum[maxn];
struct node{
    vector<int> s;
    bool operator < (node a) const{
        if(s.size()!=a.s.size()) return s.size()<a.s.size();
        for(int i=0;i<s.size();i++){
            if(s[i]!=a.s[i]) return s[i]<a.s[i];
        }
        return false;
    }
}nd[maxn];
map<node,ll> aa;
int main(){
    int t=read();
    while(t--){
        int n=read(),m=read();
        ll x=0;
        for(int i=1;i<=n;i++){
            sum[i]=0;
            c[i]=read();x+=c[i];
            nd[i].s.clear();
        }
        for(int i=1;i<=m;i++){
            int u=read(),v=read();
            sum[u]+=c[v];nd[v].s.push_back(u);
        }
        aa.clear();
        for(int i=1;i<=n;i++) sort(nd[i].s.begin(),nd[i].s.end()),aa[nd[i]]+=c[i];
        for(auto i:aa) x=gcd(x,i.second);
        printf("%lld\n",x);
    }
    return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1500*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<100){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%2){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	int t,n,m,a,b;
	scanf("%i",&t);
	while(t--){
		scanf("%i%i",&n,&m);
		vector<ll> v(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&v[i]);
		vector<vector<int> > k(n);
		for(int i=0;i<m;i++){
			scanf("%i%i",&a,&b);
			k[b-1].push_back(a-1);
		}
		map<vector<int>,ll> sum;
		for(int i=0;i<n;i++){
			if(k[i].empty())
				continue;
			sort(k[i].begin(),k[i].end());
			sum[k[i]]+=v[i];
		}
		ll gcd=0;
		for(auto p:sum)
			gcd=g(gcd,p.second);
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1500*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<200){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%max(2,n/20)==0){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1600*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<10){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%2){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1500*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<200){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%max(2,n/10)==0){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1500*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<200){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%10==0){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1500*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<200){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%20==0){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1800*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<10){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%2){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=(ll)1600*max(n,m)/500000;
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<200){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%max(2,n/1000)==0){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}


// Problem : C. Instant Noodles
// Contest : Codeforces Round #626 (Div. 1, based on Moscow Open Olympiad in Informatics)
// URL : https://codeforces.com/contest/1322/problem/C
// Memory Limit : 512 MB
// Time Limit : 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cp-editor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

#define ll long long
#define pb push_back
#define sz(x) (int)(x).size()
#define mp make_pair
#define f first
#define s second
#define all(x) x.begin(), x.end()
#define D(x) cerr << #x << " is " << (x) << "\n";
#define ld long double

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; ///find_by_order(),order_of_key()
template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) { os << '{' << a.f << ", " << a.s << '}'; return os; }
template<class T> ostream& operator<<(ostream& os, const vector<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const deque<T>& a){os << '{';for(int i=0;i<sz(a);i++){if(i>0&&i<sz(a))os << ", ";os << a[i];}os<<'}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const set<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T> ostream& operator<<(ostream& os, const multiset<T,greater<T> >& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}
template<class T1,class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {os << '{';int i=0;for(auto p:a){if(i>0&&i<sz(a))os << ", ";os << p;i++;}os << '}';return os;}

ll g(ll a,ll b){return b==0?a:g(b,a%b);}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%i",&t);
	while(t--){
		int n,m;
		scanf("%i %i",&n,&m);
		ll vreme=max((ll)10,(ll)1800*max(n,m)/500000);
		ll beg=clock();
		vector<ll> vals(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&vals[i]);
		vector<vector<int> > koji(n);
		for(int i=0;i<m;i++){
			int a,b;
			scanf("%i %i",&a,&b);
			a--;b--;
			koji[a].pb(b);
		}
		vector<bool> taken(n);
		ll gcd=0;
		int tr=0;
		while(clock()-beg<vreme||tr<10){
		  tr++;
			vector<int> undo;
			ll sum=0;
			for(int i=0;i<n;i++){
				if(rng()%2){
					for(auto p:koji[i])
						if(!taken[p])
							taken[p]=1,undo.pb(p),sum+=vals[p];
				}
			}
			for(auto p:undo)
				taken[p]=0;
			gcd=g(gcd,sum);
		}
		printf("%lld\n",gcd);
	}
	return 0;
}