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

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
uf = UnionFind(N)
for _ in range(M):
  a, b = map(long, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

ans = nC2(N)
for a, b in reversed(zip(A, B)):
  rev_res.append(ans)
  if not uf.same(a, b):
    ans -= uf.size(a) * uf.size(b)
  uf.unite(a, b)

for r in reversed(rev_res):
  print r

Fixed submission:
import math
from collections import deque

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
uf = UnionFind(N)
for _ in range(M):
  a, b = map(long, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

ans = N * (N - 1) / 2
for a, b in reversed(zip(A, B)):
  rev_res.append(ans)
  if not uf.same(a, b):
    ans -= uf.size(a) * uf.size(b)
  uf.unite(a, b)

for r in reversed(rev_res):
  print r

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

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
rev_res.append(nC2(N))
uf = UnionFind(N)
for _ in range(M):
  a, b = map(long, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

for a, b in reversed(zip(A, B)):
  if not uf.same(a, b):
    res = rev_res[-1] - uf.size(a) * uf.size(b)
  else:
    res = rev_res[-1]
  rev_res.append(res)
  uf.unite(a, b)

for r in reversed(rev_res[:-1]):
  print r

Fixed submission:
import math
from collections import deque

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
uf = UnionFind(N)
for _ in range(M):
  a, b = map(long, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

ans = N * (N - 1) / 2
for a, b in reversed(zip(A, B)):
  rev_res.append(ans)
  if not uf.same(a, b):
    ans -= uf.size(a) * uf.size(b)
  uf.unite(a, b)

for r in reversed(rev_res):
  print r

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

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
rev_res.append(nC2(N))
uf = UnionFind(N)
for _ in range(M):
  a, b = map(int, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

for a, b in reversed(zip(A, B)):
  if not uf.same(a, b):
    res = rev_res[-1] - uf.size(a) * uf.size(b)
  else:
    res = rev_res[-1]
  rev_res.append(res)
  uf.unite(a, b)

for r in reversed(rev_res[:-1]):
  print r

Fixed submission:
import math
from collections import deque

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
uf = UnionFind(N)
for _ in range(M):
  a, b = map(long, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

ans = N * (N - 1) / 2
for a, b in reversed(zip(A, B)):
  rev_res.append(ans)
  if not uf.same(a, b):
    ans -= uf.size(a) * uf.size(b)
  uf.unite(a, b)

for r in reversed(rev_res):
  print r

Buggy python submission (verdict: Time Limit Exceeded):
import math
from collections import deque
def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)
N, M = map(int, raw_input().split())

seg_tree = [i for i in range(N)]
seg_height = [1 for _ in range(N)]
seg_size = [1 for _ in range(N)]
def get_root(i):
  if i == seg_tree[i]:
    return i
  else:
    return get_root(seg_tree[i])

def unite(i, j):
  if get_root(i) == get_root(j):
    return
  if seg_height[get_root(i)] > seg_height[get_root(j)]:
    seg_size[get_root(i)] += seg_size[get_root(j)]
    seg_tree[get_root(j)] = get_root(i)
  elif seg_height[get_root(i)] < seg_height[get_root(j)]:
    seg_size[get_root(j)] += seg_size[get_root(i)]
    seg_tree[get_root(i)] = get_root(j)
  else:
    seg_height[get_root(i)] += 1
    seg_size[get_root(i)] += seg_size[get_root(j)]
    seg_tree[get_root(j)] = get_root(i)

def same(i, j):
  return get_root(i) == get_root(j)

A = deque()
B = deque()
rev_res = deque()
rev_res.append(nC2(N))
for _ in range(M):
  a, b = map(int, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

for _ in range(M):
  a = A.pop()
  b = B.pop()
  res = rev_res[-1] - seg_size[get_root(a)] * seg_size[get_root(b)] if not same(a, b) else rev_res[-1]
  rev_res.append(res)
  unite(a, b)
rev_res.pop()
while len(rev_res) > 0:
  print rev_res.pop()

Fixed submission:
import math
from collections import deque

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
uf = UnionFind(N)
for _ in range(M):
  a, b = map(long, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

ans = N * (N - 1) / 2
for a, b in reversed(zip(A, B)):
  rev_res.append(ans)
  if not uf.same(a, b):
    ans -= uf.size(a) * uf.size(b)
  uf.unite(a, b)

for r in reversed(rev_res):
  print r

Buggy python submission (verdict: Time Limit Exceeded):
import math
def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)
N, M = map(int, raw_input().split())
A = []
B = []
for _ in range(M):
  a, b = map(int, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)
max_inconvenience = nC2(N)

seg_tree = [i for i in range(N)]
seg_height = [1 for _ in range(N)]
seg_size = [1 for _ in range(N)]
def get_root(i):
  if i == seg_tree[i]:
    return i
  else:
    return get_root(seg_tree[i])

def unite(i, j):
  if get_root(i) == get_root(j):
    return
  if seg_height[get_root(i)] > seg_height[get_root(j)]:
    seg_size[get_root(i)] += seg_size[get_root(j)]
    seg_tree[get_root(j)] = get_root(i)
  elif seg_height[get_root(i)] < seg_height[get_root(j)]:
    seg_size[get_root(j)] += seg_size[get_root(i)]
    seg_tree[get_root(i)] = get_root(j)
  else:
    seg_height[get_root(i)] += 1
    seg_size[get_root(i)] += seg_size[get_root(j)]
    seg_tree[get_root(j)] = get_root(i)

def same(i, j):
  return get_root(i) == get_root(j)

rev_res = [max_inconvenience]
for a, b in reversed(zip(A, B)):
  res = rev_res[-1] - seg_size[get_root(a)] * seg_size[get_root(b)] if not same(a, b) else rev_res[-1]
  rev_res.append(res)
  unite(a, b)
for res in reversed(rev_res[:-1]):
  print res

Fixed submission:
import math
from collections import deque

class UnionFind():
  def __init__(self, n):
    self.seg_tree = [-1 for i in range(n)]
  
  def root(self, i):
    if self.seg_tree[i] < 0:
      return i
    else:
      self.seg_tree[i] = self.root(self.seg_tree[i])
      return self.seg_tree[i]

  def size(self, i):
    return -self.seg_tree[self.root(i)]

  def unite(self, i, j):
    if self.same(i, j):
      return

    if self.size(i) == self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    elif self.size(i) > self.size(j):
      self.seg_tree[self.root(i)] -= self.size(j)
      self.seg_tree[self.root(j)] = self.root(i)
    else:
      self.seg_tree[self.root(j)] -= self.size(i)
      self.seg_tree[self.root(i)] = self.root(j)

  def same(self, i, j):
    return self.root(i) == self.root(j)

def nC2(n):
  return math.factorial(n) / math.factorial(2) / math.factorial(n - 2)

N, M = map(int, raw_input().split())
A = []
B = []
rev_res = []
uf = UnionFind(N)
for _ in range(M):
  a, b = map(long, raw_input().split())
  A.append(a - 1)
  B.append(b - 1)

ans = N * (N - 1) / 2
for a, b in reversed(zip(A, B)):
  rev_res.append(ans)
  if not uf.same(a, b):
    ans -= uf.size(a) * uf.size(b)
  uf.unite(a, b)

for r in reversed(rev_res):
  print r