Buggy python submission (verdict: Runtime Error):
N = int(input())

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

ver_num = int(N * (N + 1) * (N + 2) / 6)

edge_num = 0
for e in edge_list:
    edge_num += (N + 1 - (e.max() + 1)) * (e.min() + 1)
    
print(ver_num - edge_num)

Fixed submission:
class edge:
    def __init__(self, u, v):
        self.u = u
        self.v = v
    def min(self):
        return min(self.u, self.v)
    def max(self):
        return max(self.u, self.v)

N = int(input())
 
edge_list = []
for i in range(N - 1):
    u, v = map(int, input().split())
    edge_list.append(edge(u - 1, v - 1))
 
ver_num = int(N * (N + 1) * (N + 2) / 6)
 
edge_num = 0
for e in edge_list:
    edge_num += (N + 1 - (e.max() + 1)) * (e.min() + 1)
    
print(ver_num - edge_num)

Buggy python submission (verdict: Time Limit Exceeded):
# Union Find
class edge:
    def __init__(self, u, v):
        self.u = u
        self.v = v
    def min(self):
        return min(self.u, self.v)
    def max(self):
        return max(self.u, self.v)


# xの根を求める
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]


# xとyの属する集合の併合
def unite(x, y):
    x = find(x)
    y = find(y)

    if x == y:
        return False
    else:
        # sizeの大きいほうがx
        if par[x] > par[y]:
            x, y = y, x
        par[x] += par[y]
        par[y] = x
        return True


# xとyが同じ集合に属するかの判定
def same(x, y):
    return find(x) == find(y)


# xが属する集合の個数
def size(x):
    return -par[find(x)]


# 初期化
# 根なら-size,子なら親の頂点
N = int(input())

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

ans_sum = 0
edge_list.append(edge(N, N))
upper_l_edge_list = sorted(edge_list, key=lambda e: -e.max())

for l in range(N):
    par = [-1] * N
    num_cc = 0
    upper_l_edge_list_copy = [e for e in upper_l_edge_list if e.min() >= l]
    ### upper_l_edge_list_copy.append(edge(N, N))
    ### upper_l_edge_list = sorted(upper_l_edge_list_copy, key=lambda e: -e.max()) ###

    for r in range(l, N):
        size = 0
        # print([(e.u, e.v) for e in upper_l_edge_list])
        while upper_l_edge_list_copy[-1].max() <= r:
            e = upper_l_edge_list_copy.pop()
            if not same(e.u, e.v):
                size += 1
            unite(e.u, e.v)
        num_cc = num_cc - size + 1
        # print(l, r, num_cc, "size_r", size)
        ans_sum += num_cc

print(ans_sum)


Fixed submission:
class edge:
    def __init__(self, u, v):
        self.u = u
        self.v = v
    def min(self):
        return min(self.u, self.v)
    def max(self):
        return max(self.u, self.v)

N = int(input())
 
edge_list = []
for i in range(N - 1):
    u, v = map(int, input().split())
    edge_list.append(edge(u - 1, v - 1))
 
ver_num = int(N * (N + 1) * (N + 2) / 6)
 
edge_num = 0
for e in edge_list:
    edge_num += (N + 1 - (e.max() + 1)) * (e.min() + 1)
    
print(ver_num - edge_num)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import deque

# Union Find
class edge:
    def __init__(self, u, v):
        self.u = u
        self.v = v
    def min(self):
        return min(self.u, self.v)
    def max(self):
        return max(self.u, self.v)


# xの根を求める
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]


# xとyの属する集合の併合
def unite(x, y):
    x = find(x)
    y = find(y)

    if x == y:
        return False
    else:
        # sizeの大きいほうがx
        if par[x] > par[y]:
            x, y = y, x
        par[x] += par[y]
        par[y] = x
        return True


# xとyが同じ集合に属するかの判定
def same(x, y):
    return find(x) == find(y)


# xが属する集合の個数
def size(x):
    return -par[find(x)]


# 初期化
# 根なら-size,子なら親の頂点
N = int(input())

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

ans_sum = 0
for l in range(N):
    par = [-1] * N
    num_cc = 0
    upper_l_edge_list_copy = [e for e in edge_list if e.min() >= l]
    upper_l_edge_list_copy.append(edge(N, N))
    upper_l_edge_list = sorted(upper_l_edge_list_copy, key=lambda e: -e.max())
    for r in range(l, N):
        # if not upper_l_edge_list:
        #    continue
        size = 0
        # print([(e.u, e.v) for e in upper_l_edge_list])
        # print("aaaa", upper_l_edge_list[-1].max() == r)
        while upper_l_edge_list[-1].max() <= r:
            # print("bbb", upper_l_edge_list[-1].max() == r)
            e = upper_l_edge_list.pop()
            if not same(e.u, e.v):
                size += 1
            unite(e.u, e.v)
            # if not upper_l_edge_list:
            #    break
        num_cc = num_cc - size + 1
        # print(l, r, num_cc, "size_r", size)
        ans_sum += num_cc

print(ans_sum)


Fixed submission:
class edge:
    def __init__(self, u, v):
        self.u = u
        self.v = v
    def min(self):
        return min(self.u, self.v)
    def max(self):
        return max(self.u, self.v)

N = int(input())
 
edge_list = []
for i in range(N - 1):
    u, v = map(int, input().split())
    edge_list.append(edge(u - 1, v - 1))
 
ver_num = int(N * (N + 1) * (N + 2) / 6)
 
edge_num = 0
for e in edge_list:
    edge_num += (N + 1 - (e.max() + 1)) * (e.min() + 1)
    
print(ver_num - edge_num)