Buggy python submission (verdict: Runtime Error):
import numpy as np
n, m = map(int, input().split())
ab = np.array([list(map(int, input().split())) for x in range(m)]) - 1

to = list(range(n))
ranks = [0] * n
nodes = [1] * n

def find(x):
    if to[x] == x:
        return x
    else:
        root = find(to[x])
        to[x] = root
        return root

entire = (n - 1) * n // 2
def merge(x, y):
    global entire
    xroot = find(x)
    yroot = find(y)
    # if xroot == yroot:
    #     return
    if ranks[xroot] < ranks[yroot]:
        to[xroot] = yroot
        # entire -= nodes[yroot] * nodes[xroot]
        # nodes[yroot] += nodes[xroot]
    else:
        to[yroot] = xroot
        # entire -= nodes[yroot] * nodes[xroot]
        # nodes[xroot] += nodes[yroot]
        if ranks[xroot] == ranks[yroot]:
            ranks[yroot] += 1


results = [entire]
for a, b in reversed(ab[1:]):
    merge(a, b)
#     results.append(entire)
#
# for v in reversed(results):
#     print(v)


Fixed submission:
import numpy as np
n, m = map(int, input().split())
ab = np.array([list(map(int, input().split())) for x in range(m)]) - 1

to = list(range(n))
ranks = [0] * n
nodes = [1] * n

def find(x):
    if to[x] == x:
        return x
    else:
        root = find(to[x])
        to[x] = root
        return root

entire = (n - 1) * n // 2
def merge(x, y):
    global entire
    xroot = find(x)
    yroot = find(y)
    if xroot == yroot:
        return
    if ranks[xroot] < ranks[yroot]:
        to[xroot] = yroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[yroot] += nodes[xroot]
    else:
        to[yroot] = xroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[xroot] += nodes[yroot]
        if ranks[xroot] == ranks[yroot]:
            ranks[xroot] += 1


results = [entire]
for a, b in reversed(ab[1:]):
    merge(a, b)
    results.append(entire)

for v in reversed(results):
    print(v)

Buggy python submission (verdict: Runtime Error):
import numpy as np
n, m = map(int, input().split())
ab = np.array([list(map(int, input().split())) for x in range(m)]) - 1

to = list(range(n))
ranks = [0] * n
nodes = [1] * n

def find(x):
    if to[x] == x:
        return x
    else:
        root = find(to[x])
        to[x] = root
        return root

entire = (n - 1) * n // 2
def merge(x, y):
    global entire
    xroot = find(x)
    yroot = find(y)
    if xroot == yroot:
        return
    if ranks[xroot] < ranks[yroot]:
        to[xroot] = yroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[yroot] += nodes[xroot]
    else:
        to[yroot] = xroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[xroot] += nodes[yroot]
        if ranks[xroot] == ranks[yroot]:
            ranks[yroot] += 1


results = [entire]
for a, b in reversed(ab[1:]):
    merge(a, b)
    results.append(entire)

for v in reversed(results):
    print(v)


Fixed submission:
import numpy as np
n, m = map(int, input().split())
ab = np.array([list(map(int, input().split())) for x in range(m)]) - 1

to = list(range(n))
ranks = [0] * n
nodes = [1] * n

def find(x):
    if to[x] == x:
        return x
    else:
        root = find(to[x])
        to[x] = root
        return root

entire = (n - 1) * n // 2
def merge(x, y):
    global entire
    xroot = find(x)
    yroot = find(y)
    if xroot == yroot:
        return
    if ranks[xroot] < ranks[yroot]:
        to[xroot] = yroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[yroot] += nodes[xroot]
    else:
        to[yroot] = xroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[xroot] += nodes[yroot]
        if ranks[xroot] == ranks[yroot]:
            ranks[xroot] += 1


results = [entire]
for a, b in reversed(ab[1:]):
    merge(a, b)
    results.append(entire)

for v in reversed(results):
    print(v)

Buggy python submission (verdict: Runtime Error):
import numpy as np
n, m = map(int, input().split())
ab = np.array([list(map(int, input().split())) for x in range(m)]) - 1

to = list(range(n))
ranks = [0] * n
nodes = [1] * n

def find(x):
    if to[x] == x:
        return x
    else:
        root = find(to[x])
        to[x] = root
        return root

entire = (n - 1) * n // 2
def merge(x, y):
    global entire
    xroot = find(x)
    yroot = find(y)
    if xroot == yroot:
        return
    if ranks[xroot] < ranks[yroot]:
        to[xroot] = yroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[yroot] += nodes[xroot]
    else:
        to[yroot] = xroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[xroot] += nodes[yroot]
        if ranks[xroot] == ranks[yroot]:
            ranks[yroot] += 1

print(entire)
for a, b in reversed(ab[1:]):
    merge(a, b)
    print(entire)


Fixed submission:
import numpy as np
n, m = map(int, input().split())
ab = np.array([list(map(int, input().split())) for x in range(m)]) - 1

to = list(range(n))
ranks = [0] * n
nodes = [1] * n

def find(x):
    if to[x] == x:
        return x
    else:
        root = find(to[x])
        to[x] = root
        return root

entire = (n - 1) * n // 2
def merge(x, y):
    global entire
    xroot = find(x)
    yroot = find(y)
    if xroot == yroot:
        return
    if ranks[xroot] < ranks[yroot]:
        to[xroot] = yroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[yroot] += nodes[xroot]
    else:
        to[yroot] = xroot
        entire -= nodes[yroot] * nodes[xroot]
        nodes[xroot] += nodes[yroot]
        if ranks[xroot] == ranks[yroot]:
            ranks[xroot] += 1


results = [entire]
for a, b in reversed(ab[1:]):
    merge(a, b)
    results.append(entire)

for v in reversed(results):
    print(v)