qyliang/CodeNanoFix huggingface dataset:
# Buggy code:
def find_index_by_value(a, val):
    for i, items in enumerate(a):
        if val in items:
            return i
    return -1


def num_reachable(n):
    return n * (n - 1) // 2


n, m = map(int, input().split())
edges = []

for _ in range(m):
    a, b = map(int, input().split())
    edges.append((a, b))

size = [1 for _ in range(n + 1)]
group = [i for i in range(n + 1)]


def find_group(x):
    p = x
    while True:
        pp = group[p]
        if pp == p:
            break
    return pp

ans = []
not_reachable = n * (n - 1) // 2
reachable_node = []
ans.append(not_reachable)

count = not_reachable
reachable = 0
for _ in range(m - 1):
    a, b = edges.pop()
    if count > 0:
        ra = find_group(a)
        rb = find_group(b)
        if rb != ra:
            s_ra = size[ra]
            s_rb = size[rb]
            new_size = s_ra + s_rb
            reachable += num_reachable(new_size) - num_reachable(s_ra) - num_reachable(s_rb)
            size[ra] = new_size
            group[rb] = ra
        count = not_reachable - reachable
    ans.append(count)

for _ in range(len(ans)):
    print(ans.pop())

# Fixed code:
def find_index_by_value(a, val):
    for i, items in enumerate(a):
        if val in items:
            return i
    return -1


def num_reachable(n):
    return n * (n - 1) // 2


n, m = map(int, input().split())
edges = []

for _ in range(m):
    a, b = map(int, input().split())
    edges.append((a, b))

size = [1 for _ in range(n + 1)]
group = [i for i in range(n + 1)]


def find_group(x):
    c = []
    p = x
    while True:
        pp = group[p]
        if pp == p:
            break
        else:
            c.append(p)
            p = pp
    for i in c:
        group[i] = pp
    return pp

# find_group = lambda x: x if x == group[x] else find_group(group[x])

ans = []
not_reachable = n * (n - 1) // 2
reachable_node = []
ans.append(not_reachable)

count = not_reachable
reachable = 0
for _ in range(m - 1):
    a, b = edges.pop()
    if count > 0:
        ra = find_group(a)
        rb = find_group(b)
        if rb != ra:
            s_ra = size[ra]
            s_rb = size[rb]
            new_size = s_ra + s_rb
            reachable += num_reachable(new_size) - num_reachable(s_ra) - num_reachable(s_rb)
            size[ra] = new_size
            group[rb] = ra
        count = not_reachable - reachable
    ans.append(count)

for _ in range(len(ans)):
    print(ans.pop())
# Buggy code:
n,m=map(int,input().split())

par=[i for i in range(n)]
size=[1]*n

def find(x):
  if par[x]==x:
    return x
  else:
    par[x]=find(par[x])
    return par[x]
def union(a,b):
  x=find(a)
  y=find(b)
  if x!=y:
    if size[x]<size[y]:
      par[x]=par[y]
      size[y]+=size[x]
    else: 
      par[y]=par[x]
      size[x]+=size[y]
  else:
    return

ans=[n*(n-1)//2]
bridge=[]

for i in range(m):
  a,b=map(int,input().split())
  a-=1
  b-=1
  bridge.append([a,b])

bridge.reverse()
bridge.pop()

for i in bridge:
  if find(i[0]) != find(i[1]):
    ans.append(ans[-1]-size[find(i[0])]*size[find(i[1])])
    union(i[0],i[1])


ans.reverse()

for i in ans:
  print(i)

# Fixed code:
n,m=map(int,input().split())

par=[i for i in range(n)]
size=[1]*n

def find(x):
  if par[x]==x:
    return x
  else:
    par[x]=find(par[x])
    return par[x]
def union(a,b):
  x=find(a)
  y=find(b)
  if x!=y:
    if size[x]<size[y]:
      par[x]=par[y]
      size[y]+=size[x]
    else: 
      par[y]=par[x]
      size[x]+=size[y]
  else:
    return

ans=[n*(n-1)//2]
bridge=[]

for i in range(m):
  a,b=map(int,input().split())
  a-=1
  b-=1
  bridge.append([a,b])

bridge.reverse()
bridge.pop()

for i in bridge:
  if find(i[0]) != find(i[1]):
    ans.append(ans[-1]-size[find(i[0])]*size[find(i[1])])
    union(i[0],i[1])
  else:
    ans.append(ans[-1])


ans.reverse()

for i in ans:
  print(i)
# Buggy code:
N, M = [int(x) for x in raw_input().split(' ')]
edges = []
for _ in range(M):
    edges.append([int(x) - 1 for x in raw_input().split(' ')])
res = [str(N * (N-1) / 2)]
init = N * (N-1) / 2
f = range(N)
cnt = [1] * N
def find(x):
    if x != f[x]:
        f[x] = find(f[x])
    return f[x]
for i in range(M-1, 0, -1):
    a, b = edges[i]
    fx, fy = find(a), find(b)
    if fx == fy:
        res.append(str(init))
    else:
        f[fy] = fx
        pre = cnt[fx] * (cnt[fx] - 1) / 2 + cnt[fy] * (cnt[fy] - 1) / 2
        cnt[fx] += cnt[fy]
        # print(a, b, f, cnt)
        init = init - cnt[fx] * (cnt[fx]-1) / 2 + pre
        res.append(str(init))
print('\n'.join(res[::-1]))


# Fixed code:
N, M = [int(x) for x in input().split(' ')]
edges = []
for _ in range(M):
    edges.append([int(x)-1 for x in input().split(' ')])
res = [str(N * (N-1) // 2)]
init = N * (N-1) // 2
f = list(range(N))
cnt = [1] * N
def find(x):
    if x != f[x]:
        f[x] = find(f[x])
    return f[x]
for i in range(M-1, 0, -1):
    a, b = edges[i]
    fx, fy = find(a), find(b)
    if fx == fy:
        res.append(str(init))
    else:
        
        pre = cnt[fx] * (cnt[fx] - 1) // 2 + cnt[fy] * (cnt[fy] - 1) // 2
        if cnt[fx] < cnt[fy]:
            f[fx] = fy
            cnt[fy] += cnt[fx]
            init = init - cnt[fy] * (cnt[fy]-1) // 2 + pre
        else:
            f[fy] = fx
            cnt[fx] += cnt[fy]
            init = init - cnt[fx] * (cnt[fx] - 1) // 2 + pre
        res.append(str(init))
print('\n'.join(res[::-1]))
# Buggy code:
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 code:
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 code:
import sys
sys.setrecursionlimit(100000)
input=sys.stdin.readline
n,m=map(int,input().split())
l=[1]*n
z=n*(n-1)//2
input()
m-=1
b=[input().split() for _ in range(m)]
c=[0]*m+[z]
def r(s):
  t=l[s]
  if t>0:
    return s
  else:
    l[s]=r(t)
    return l[s]
def f(s):
  return r(int(s)-1)
for i in range(m-1,-1,-1):
  x,y=map(f,b[i])
  if x!=y:
    s,t=l[x],l[y]
    z-=s*t
    if s<t:
      l[x]=-y
      l[y]+=s
    else:
      l[y]=-x
      l[x]+=t
  c[i]=z
for x in c:
  print(x)

# Fixed code:
import sys
sys.setrecursionlimit(100000)
input=sys.stdin.readline
n,m=map(int,input().split())
l=[-1]*n
b=[input().split() for _ in range(m)]
c=[0]*m+[n*(n-1)//2]
def r(s):
  t=l[s]
  if t<0:
    return s
  else:
    l[s]=r(t)
    return l[s]
def f(s):
  return r(int(s)-1)
for i in range(m-1,-1,-1):
  x,y=map(f,b[i])
  s,t=0,0
  if x!=y:
    s,t=l[x],l[y]
    if s>t:
      l[x]=y
      l[y]+=s
    else:
      l[y]=x
      l[x]+=t
  c[i]=c[i+1]-s*t
for x in c[1:]:
  print(x)
# Buggy code:
n,m = [int(i) for i in input().split()]
ab = []
for i in range(m):
  ab.append([int(i)-1 for i in input().split()])

def find_index(c,eld):
  if c in eld[c]:
    return(c,len(eld[c]))
  else:
    return(eld[c][0],len(eld[eld[c][0]]))
           
eld = []
for i in range(n):
  eld.append([i])
stat = eld
ans = [int(len(eld)*(len(eld)-1)/2)]

for a,b in ab[1:][::-1]:
  a_index,a_size = find_index(a,eld)
  b_index,b_size = find_index(b,eld)
  if a_index == b_index:
    ans.append(ans[-1])
    continue
  if a_size >= b_size:
    eld[a_index].extend(eld[b_index])
    eld[b_index] = [a_index]
  else:
    eld[b_index].extend(eld[a_index])
    eld[a_index] = [b_index]

  next = a_size * b_size
  ans.append(ans[-1] - next)

for i in ans[::-1]:
  print(i)


  

# Fixed code:
n,m = [int(i) for i in input().split()]
ab = []
for i in range(m):
  ab.append([int(i)-1 for i in input().split()])

def find_index(c,eld):
  if c in eld[c]:
    return(c,len(eld[c]))
  else:
    return(eld[c][0],len(eld[eld[c][0]]))
           
eld = []
for i in range(n):
  eld.append([i])
stat = eld
ans = [int(len(eld)*(len(eld)-1)/2)]

for a,b in ab[1:][::-1]:
#  print(eld)
  a_index,a_size = find_index(a,eld)
  b_index,b_size = find_index(b,eld)
#  print(a_index,b_index)
  if a_index == b_index:
    ans.append(ans[-1])
    continue
  else:
    next = a_size * b_size
    ans.append(ans[-1] - next)

  if a_size >= b_size:
    eld[a_index].extend(eld[b_index])
    for i in eld[b_index]:
      eld[i] = [a_index]
  else:
    eld[b_index].extend(eld[a_index])
    for i in eld[a_index]:
      eld[i] = [b_index]

for i in ans[::-1]:
  print(i)
# Buggy code:
def detectGroup(parents,x):
    if parents[x]!=x:
        return detectGroup(parents,parents[x])
    else:
        return x
    
N,M=map(int,input().split())
AB=[[int(x)-1 for x in input().split()] for i in range(M)][::-1]
parents=[i for i in range(N)]
groupsize=[1 for i in range(N)]
inconv=N*(N-1)/2
result = []
for i in range(M):
    result.append(str(int(inconv))+'\n')
    groupA=detectGroup(parents,AB[i][0])
    groupB=detectGroup(parents,AB[i][1])
    print(groupA,groupB,inconv)
    if groupA!=groupB:
        inconv-=groupsize[groupA]*groupsize[groupB]
        groupsize[groupA]+=groupsize[groupB]
    parents[groupB] = groupA
print("".join(result[::-1]))

# Fixed code:
import sys
sys.setrecursionlimit(100000)

def detectGroup(parents,x):
    if parents[x]!=x:
        parents[x]=detectGroup(parents,parents[x])
        return parents[x]
    else:
        return x
    
N,M=map(int,input().split())
AB=[[int(x)-1 for x in input().split()] for i in range(M)][::-1]
parents=[i for i in range(N)]
groupsize=[1 for i in range(N)]
inconv=N*(N-1)/2
result = []
for i in range(M):
    result.append(str(int(inconv))+'\n')
    groupA=detectGroup(parents,AB[i][0])
    groupB=detectGroup(parents,AB[i][1])
    if groupA!=groupB:
        inconv-=groupsize[groupA]*groupsize[groupB]
        groupsize[groupA]+=groupsize[groupB]
    parents[groupB] = groupA
print("".join(result[::-1]))
# Buggy code:
import sys
sys.setrecursionlimit(20000)
N, M = [int(i) for i in input().split()]
parent = [i for i in range(N+1)]
node_num = [1 for i in range(N+1)]
def find(x):
    if parent[x] == x:
        return x
    else:
        parent[x] = find(parent[x])
        return parent[x]

bridge = []
for i in range(M):
    A, B = [int(i) for i in input().split()]
    bridge.append([A, B])

bridge = bridge[::-1]
ans_rev = [N*(N-1)//2]
combi = 0
for i in range(M-1):
    A, B = bridge[i]
    r_A = find(A)
    r_B = find(B)
    if r_A != r_B:
        parent[r_B] = r_A
        combi += node_num[r_B] * node_num[r_A]
        node_num[r_A] += node_num[r_B]
    ans_rev.append(N*(N-1)//2-combi)

ans = ans_rev[::-1]
print(*ans, sep="\n"

# Fixed code:
import sys
sys.setrecursionlimit(10**6)

N, M = [int(i) for i in input().split()]
parent = [i for i in range(N+1)]
node_num = [1 for i in range(N+1)]
def find(x):
    if parent[x] == x:
        return x
    else:
        parent[x] = find(parent[x])
        return parent[x]

bridge = []
for i in range(M):
    A, B = [int(i) for i in input().split()]
    bridge.append([A, B])

bridge = bridge[::-1]
ans_rev = [N*(N-1)//2]
combi = 0
for i in range(M-1):
    A, B = bridge[i]
    r_A = find(A)
    r_B = find(B)
    if r_A != r_B:
        parent[r_B] = r_A
        combi += node_num[r_B] * node_num[r_A]
        node_num[r_A] += node_num[r_B]
    ans_rev.append(N*(N-1)//2-combi)

ans = ans_rev[::-1]
print(*ans, sep="\n")
# Buggy code:
n,m=map(int,input().split())
pair=[]
uf = [-1]*(n+1)

def root(x):
        if uf[x]<0: 
                return x
        else: 
                uf[x]=root(uf[x])
                return uf[x]

def issame(x,y):
        return root(x)==root(y)

def unite(x,y):
        x=root(x)
        y=root(y)
        if x==y:
                return False
        if uf[x]>uf[y]:
                x,y=y,x
        uf[x]+=uf[y]
        uf[y]=x
        return True

def size(x):
        return -uf[root(x)]


ans=[n*(n-1)//2]

for _ in range(m):
        a,b=map(int,input().split())
        pair.append((a,b))

for i,p in enumerate(reversed(pair)):
        if not issame(p[0],p[1]):               
                ans.append(ans[i]-size(p[0])*size(p[1]))
                unite(p[0],p[1])    
        else:
                ans.append(ans[i])
ans.reverse()
for i in range(n-1):
        print(ans[i+1])

# Fixed code:
n,m=map(int,input().split())
pair=[]
uf = [-1]*(n+1)

def root(x):
        if uf[x]<0: 
                return x
        else: 
                uf[x]=root(uf[x])
                return uf[x]

def issame(x,y):
        return root(x)==root(y)

def unite(x,y):
        x=root(x)
        y=root(y)
        if x==y:
                return False
        if uf[x]>uf[y]:
                x,y=y,x
        uf[x]+=uf[y]
        uf[y]=x
        return True

def size(x):
        return -uf[root(x)]


ans=[n*(n-1)//2]

for _ in range(m):
        a,b=map(int,input().split())
        pair.append((a,b))

for i,p in enumerate(reversed(pair)):
        if not issame(p[0],p[1]):               
                ans.append(ans[i]-size(p[0])*size(p[1]))
                unite(p[0],p[1])    
        else:
                ans.append(ans[i])

ans.reverse()
for i in range(m):
        print(ans[i+1])
# Buggy code:
n,m=map(int,input().split())
a=[list(map(int,input().split()))for i in range(m)][::-1]
w=[i for i in range(n+1)]
s=[1]*(n+1)
def root(x):
    if w[x]==x:
        return x
    else:
        w[x]=root(w[x])
        return root(w[x])
def unite(x,y):
    x=root(x)
    y=root(y)
    if x!=y:
        if s[x]<s[y]:
            w[x]=y
            s[y]+=s[x]
        else:
            w[y]=x
            s[x]+=s[y]
k=[]
ans=n*(n-1)//2
for i in a:
    k.append(ans)
    g=root(i[0])
    h=root(i[1])
    if g!=h:
        c=s[g]
        d=s[h]
    unite(g,h)
    ans-=(c+d)*(c+d-1)//2-c*(c-1)//2-d*(d-1)//2
    unite(g,h)
for i in k[::-1]:
    print(i)

# Fixed code:
n,m=map(int,input().split())
a=[list(map(int,input().split()))for i in range(m)][::-1]
w=[i for i in range(n+1)]
s=[1]*(n+1)
def root(x):
    if w[x]==x:
        return x
    x=w[x]
    return root(w[x])
def unite(x,y):
    x=root(x)
    y=root(y)
    if x!=y:
        if s[x]<s[y]:
            w[x]=y
            s[y]+=s[x]
        else:
            w[y]=x
            s[x]+=s[y]
k=[]
ans=n*(n-1)//2
for i in a:
    k.append(ans)
    g=root(i[0])
    h=root(i[1])
    if g!=h:
        c=s[g]
        d=s[h]
        unite(g,h)
        ans-=(c+d)*(c+d-1)//2-c*(c-1)//2-d*(d-1)//2
        unite(g,h)
for i in k[::-1]:
    print(i)
# Buggy code:
n, m = map(int, input().split())
pair = []
for i in range(m):
	pair.append(list(map(int, input().split())))
pair = pair[::-1]
ans = []
ans.append(int(n*(n-1)/2))

class UnionFind:
    def __init__(self, n):
        self.par = [-1] * (n+1)
        self.rank = [0] * (n+1)

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

    def size(self, x):
        return -self.par[self.find(x)]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        elif self.size(x) < self.size(y):
            x, y = y, x
        self.par[x] += self.par[y]
        self.par[y] = x
        if self.rank[x] == self.rank[y]:
            self.rank[x] += 1
        return True

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

u = UnionFind(n)
for i in range(len(pair) - 1):
    ans.append(int(ans[i] - u.size(pair[i][0]) * u.size(pair[i][1])))
    u.union(pair[i][0], pair[i][1])
ans = ans[::-1]
for i in range(len(ans)):
    print(ans[i])

# Fixed code:
n, m = map(int, input().split())
pair = []
for i in range(m):
	pair.append(list(map(int, input().split())))
pair = pair[::-1]
ans = []
ans.append(int(n*(n-1)/2))

class UnionFind:
    def __init__(self, n):
        self.par = [-1] * (n+1)
        self.rank = [0] * (n+1)

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

    def size(self, x):
        return -self.par[self.find(x)]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        elif self.size(x) < self.size(y):
            x, y = y, x
        self.par[x] += self.par[y]
        self.par[y] = x
        if self.rank[x] == self.rank[y]:
            self.rank[x] += 1
        return

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

u = UnionFind(n)
for i in range(len(pair) - 1):
    if u.find(pair[i][0]) != u.find(pair[i][1]):
        ans.append(max(0, int(ans[i] - u.size(pair[i][0]) * u.size(pair[i][1]))))
    else:
        ans.append(ans[i])
    u.union(pair[i][0], pair[i][1])
ans = ans[::-1]
for i in range(len(ans)):
    print(ans[i])
# Buggy code:
N, M = map(int, input().split())

par = list(range(0, N + 1))
size = [1] * (N + 1)
rank = [1] * (N + 1)

def root(i):
  if par[i] == i:
    return i
  else:
    par[i] = root(par[i])
    return par[i]
  
def same(i, j):
  root(i) == root(j)
  
def findsize(i):
  size[i] = size[root(i)]
  
def unite(i, j):
  i = root(i)
  j = root(j)
  if i != j:
    if rank[i] > rank[j]:
      par[j] = i
      size[i] += size[j]
    else:
      par[i] = j
      size[j] += size[i]
      if rank[i] == rank[j]:
        rank[j] += 1

bridge = [None] * M
for i in range(M):
  x, y = map(int, input().split())
  bridge[i] = [x, y]
  
cnt = N * (N - 1) // 2
inconv = [0] * M
for i in range(M - 1, -1, -1):
  inconv[i] = cnt
  a, b = bridge[i]
  if not same(a, b):
    cnt -= size[root(a)] * size[root(b)]
    unite(a, b)
    
for i in range(M):
  print(inconv[i])

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

par = list(range(0, N + 1))
size = [1] * (N + 1)
rank = [1] * (N + 1)

def root(i):
  if par[i] == i:
    return i
  else:
    par[i] = root(par[i])
    return par[i]
  
def same(i, j):
  return root(i) == root(j)
  
def findsize(i):
  size[i] = size[root(i)]
  
def unite(i, j):
  i = root(i)
  j = root(j)
  if i != j:
    if rank[i] > rank[j]:
      par[j] = i
      size[i] += size[j]
    else:
      par[i] = j
      size[j] += size[i]
      if rank[i] == rank[j]:
        rank[j] += 1

bridge = [None] * M
for i in range(M):
  x, y = map(int, input().split())
  bridge[i] = [x, y]
  
cnt = N * (N - 1) // 2
inconv = [0] * M
for i in range(M - 1, -1, -1):
  inconv[i] = cnt
  a, b = bridge[i]
  if not same(a, b):
    cnt -= size[root(a)] * size[root(b)]
    unite(a, b)
    
for i in range(M):
  print(inconv[i])
# Buggy code:
class UnionFindTree:
    def __init__(self, n):
        self._tree = [i for i in range(n)]
#        self._rank = [1] * n
        self._size = [1] * n
    def root(self, a):
        if self._tree[a] == a:return a
        self._tree[a] = self.root(self._tree[a])
        return self._tree[a]
    def is_same_set(self, a, b):
        return self.root(a)==self.root(b)
    def unite(self, a, b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self._size[ra] < self._size[rb]:
            self._tree[ra] = rb
            self._size[rb] += self._size[ra]
        else:
            self._tree[rb] = ra
            self._size[ra] += self._size[rb]
    def size(self, a):
        return self._size[self.root(a)]

N,M=map(int,input().split())
AB=[list(map(int,input().split())) for _ in range(M)]

uft=UnionFindTree(N)
s=[0]
for a,b in AB[::-1]:
    if not(uft.is_same_set(a-1,b-1)):
        sa = uft.size(a-1)
        sb = uft.size(b-1)
        s += [s[-1] +(sa+sb)*(sa+sb-1)//2 -sa*~-sa//2 -sb*~-sb//2]
        uft.unite(a-1,b-1)
    else:s += [s[-1]]
for r in s[:N-1][::-1]:print(N*~-N//2-r)

# Fixed code:
class UnionFindTree:
    def __init__(self, n):
        self._tree = [i for i in range(n)]
#        self._rank = [1] * n
        self._size = [1] * n
    def root(self, a):
        if self._tree[a] == a:return a
        self._tree[a] = self.root(self._tree[a])
        return self._tree[a]
    def is_same_set(self, a, b):
        return self.root(a)==self.root(b)
    def unite(self, a, b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self._size[ra] < self._size[rb]:
            self._tree[ra] = rb
            self._size[rb] += self._size[ra]
        else:
            self._tree[rb] = ra
            self._size[ra] += self._size[rb]
    def size(self, a):
        return self._size[self.root(a)]

N,M=map(int,input().split())
AB=[list(map(int,input().split())) for _ in range(M)]
 
uft=UnionFindTree(N)
s=[0]
for a,b in AB[::-1]:
    if not(uft.is_same_set(a-1,b-1)):
        sa = uft.size(a-1)
        sb = uft.size(b-1)
        s += [s[-1] +(sa+sb)*(sa+sb-1)//2 -sa*(sa-1)//2 -sb*(sb-1)//2]
        uft.unite(a-1,b-1)
    else:s += [s[-1]]
#print(s)
for r in s[:M][::-1]:print(N*~-N//2-r)