Buggy python submission (verdict: Time Limit Exceeded):
class UnionFind:
	def __init__(self, n):
		self.n = n
		self.root = [-1]*(n+1)
		self.rnk = [0]*(n+1)
		self.Maxroot = -1

	def Find_Root(self, x):
		if (self.root[x] < 0):
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return 
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			if self.root[x] < self.Maxroot:
				self.Maxroot = self.root[x]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			if self.root[y] < self.Maxroot:
				self.Maxroot = self.root[y]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return self.root[self.Find_Root(x)] * (-1)

N, M = map(int, input().split())
a, b = [],[]
for _ in range(M):
	at, bt = map(int, input().split())
	a.append(at)
	b.append(bt)

solve = UnionFind(N)
ans = [0]
for i in reversed(range(M)):
	tmp = 0
	solve.Unite(a[i], b[i])
	for i in range(1,N+1):
		if solve.root[i] < -1:
			t = solve.root[i]*(-1)
			tmp += t*(t-1)//2
	ans.append(tmp)
			
tot = N*(N-1)//2

for i in range(1,len(ans)):
	print(tot-ans[-(i+1)])

Fixed submission:
class UnionFind:
	def __init__(self, n):
		self.n = n
		self.root = [-1]*(n+1)
		self.rnk = [0]*(n+1)
		self.Maxroot = -1

	def Find_Root(self, x):
		if (self.root[x] < 0):
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return 
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			if self.root[x] < self.Maxroot:
				self.Maxroot = self.root[x]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			if self.root[y] < self.Maxroot:
				self.Maxroot = self.root[y]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return self.root[self.Find_Root(x)] * (-1)

N, M = map(int, input().split())
a, b = [],[]
for _ in range(M):
	at, bt = map(int, input().split())
	a.append(at)
	b.append(bt)

solve = UnionFind(N)
ans = [0]
for i in reversed(range(M)):
	ca,cb = a[i],b[i]
	if solve.isSameGroup(ca,cb):
		ans.append(ans[-1])
		continue
	num_group_a = solve.Count(ca)
	num_group_b = solve.Count(cb)
	tmp = num_group_a * num_group_b
	solve.Unite(ca, cb)
	ans.append(ans[-1]+tmp)
			
tot = N*(N-1)//2

for i in range(2,M+2):
	print(tot-ans[-i])

Buggy python submission (verdict: Time Limit Exceeded):
class UnionFind:
	def __init__(self, n):
		self.n = n
		self.root = [-1]*(n+1)
		self.rnk = [0]*(n+1)
		self.Maxroot = -1

	def Find_Root(self, x):
		if (self.root[x] < 0):
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return 
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			if self.root[x] < self.Maxroot:
				self.Maxroot = self.root[x]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			if self.root[y] < self.Maxroot:
				self.Maxroot = self.root[y]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return self.root[self.Find_Root(x)] * (-1)

N, M = map(int, input().split())
a, b = [],[]
for _ in range(M):
	at, bt = map(int, input().split())
	a.append(at)
	b.append(bt)

solve = UnionFind(N)
ans = [0]
for i in reversed(range(M)):
	tmp = 0
	solve.Unite(a[i], b[i])
	for i in range(1,N+1):
		if solve.root[i] < -1:
			t = solve.root[i]*(-1)
			tmp += t*(t-1)//2
	ans.append(tmp)
			
tot = N*(N-1)//2

for i in range(1,len(ans)):
	print(tot-ans[-(i+1)])

Fixed submission:
class UnionFind:
	def __init__(self, n):
		self.n = n
		self.root = [-1]*(n+1)
		self.rnk = [0]*(n+1)
		self.Maxroot = -1

	def Find_Root(self, x):
		if (self.root[x] < 0):
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return 
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			if self.root[x] < self.Maxroot:
				self.Maxroot = self.root[x]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			if self.root[y] < self.Maxroot:
				self.Maxroot = self.root[y]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return self.root[self.Find_Root(x)] * (-1)

N, M = map(int, input().split())
a, b = [],[]
for _ in range(M):
	at, bt = map(int, input().split())
	a.append(at)
	b.append(bt)

solve = UnionFind(N)
ans = [0]
for i in reversed(range(M)):
	ca,cb = a[i],b[i]
	if solve.isSameGroup(ca,cb):
		ans.append(ans[-1])
		continue
	num_group_a = solve.Count(ca)
	num_group_b = solve.Count(cb)
	tmp = num_group_a * num_group_b
	solve.Unite(ca, cb)
	ans.append(ans[-1]+tmp)
			
tot = N*(N-1)//2

for i in range(2,M+2):
	print(tot-ans[-i])