Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self):
        rank = np.array(self.rank)
        return int(np.sum(rank*(len(self.rank)-rank))/2)

uf = UnionFind(N)
inconvenience = []
for m in range(M):
    inconvenience.append(uf.get_inconvenience())
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

print(*inconvenience[::-1], sep='\n')


Fixed submission:
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if x==y:
            return 0
        else:
            return self.rank[x] * self.rank[y]

uf = UnionFind(N)
inconvenience = [int(N*(N-1)/2)]
for m in range(M-1):
    inconvenience.append(inconvenience[-1] - uf.get_inconvenience(pairs[m][0]-1, pairs[m][1]-1))
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

print(*inconvenience[::-1], sep='\n')

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
            self.par[x] = self.root(self.par[x])
            return self.root(self.par[x])

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self):
        rank = np.array(self.rank)
        return int(np.sum(rank*(len(self.rank)-rank))/2)

uf = UnionFind(N)
inconvenience = []
for m in range(M):
    inconvenience.append(uf.get_inconvenience())
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

inconvenience = inconvenience[::-1]
for m in range(M):
    print(inconvenience[m])


Fixed submission:
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if x==y:
            return 0
        else:
            return self.rank[x] * self.rank[y]

uf = UnionFind(N)
inconvenience = [int(N*(N-1)/2)]
for m in range(M-1):
    inconvenience.append(inconvenience[-1] - uf.get_inconvenience(pairs[m][0]-1, pairs[m][1]-1))
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

print(*inconvenience[::-1], sep='\n')

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
            self.par[x] = self.root(self.par[x])
            return self.root(self.par[x])

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self):
        rankMat = np.zeros((len(self.rank), len(self.rank)))        
        for i in range(len(self.rank)):
            rankMat[i] = self.rank
            rankMat[i][i] = 0
        rank = np.array(self.rank)
        return int(np.sum(np.dot(rank, rankMat))/2)
    
    def get_inconvenience2(self):
        inconvenience = 0
        for i in range(len(self.rank)-1):
            inconvenience += self.rank[i] * sum(self.rank[i+1:])
        return inconvenience

uf = UnionFind(N)
inconvenience = []
for m in range(M):
    inconvenience.append(uf.get_inconvenience2())
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

inconvenience = inconvenience[::-1]
for m in range(M):
    print(inconvenience[m])


Fixed submission:
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if x==y:
            return 0
        else:
            return self.rank[x] * self.rank[y]

uf = UnionFind(N)
inconvenience = [int(N*(N-1)/2)]
for m in range(M-1):
    inconvenience.append(inconvenience[-1] - uf.get_inconvenience(pairs[m][0]-1, pairs[m][1]-1))
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

print(*inconvenience[::-1], sep='\n')

Buggy python submission (verdict: Runtime Error):
import numpy as np
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにpath compressionやめてunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
#            self.par[x] = self.root(self.par[x])
            return self.root(self.par[x])

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self):
        rankMat = np.zeros((len(self.rank), len(self.rank)))
        for i in range(len(self.rank)):
            rankMat[i] = self.rank
            rankMat[i][i] = 0
        rank = np.array(self.rank)
        return int(np.sum(np.dot(rank, rankMat))/2)

uf = UnionFind(N)
inconvenience = []
for m in range(M):
    inconvenience.append(uf.get_inconvenience())
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

inconvenience = inconvenience[::-1]
for m in range(M):
    print(inconvenience[m])


Fixed submission:
N, M = map(int, input().split())

pairs = []
for _ in range(M):
    pairs.append(list(map(int, input().split())))
pairs = pairs[::-1]

# rank保持のためにunionでrankを足し合わせる
# 島を数えるためにデフォルトのrank=1とする
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [1 for i in range(n)]

    def root(self, x):
        if (self.par[x]==x):
            return x
        else:
            # path compression
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if (x==y):
            return

        if (self.rank[x] < self.rank[y]):
            self.par[x] = y
            self.rank[y] += self.rank[x]
            self.rank[x] = 0
        else:
            self.par[y] = x
            self.rank[x] += self.rank[y]
            self.rank[y] = 0

    def find(self, x, y):
        return self.root(x)==self.root(y)
    
    def get_inconvenience(self, x, y):
        x = self.root(x)
        y = self.root(y)

        if x==y:
            return 0
        else:
            return self.rank[x] * self.rank[y]

uf = UnionFind(N)
inconvenience = [int(N*(N-1)/2)]
for m in range(M-1):
    inconvenience.append(inconvenience[-1] - uf.get_inconvenience(pairs[m][0]-1, pairs[m][1]-1))
    uf.union(pairs[m][0]-1, pairs[m][1]-1)

print(*inconvenience[::-1], sep='\n')