import sys
input = sys.stdin.readline

n, m = [int(x) for x in input().split()]
ab = [[int(x) for x in input().split()] for _ in range(m)][::-1]

#Union Find

#xの根を求める
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
#xとyの属する集合の併合
def unite(x,y):
    x = find(x)
    y = find(y)

    if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

#xとyが同じ集合に属するかの判定
def same(x,y):
    return find(x) == find(y)

#xが属する集合の個数
def size(x):
    return -par[find(x)]

#初期化
#根なら-size,子なら親の頂点
par = [-1]*n

def cmb(n, k):
    return n * (n - 1) // 2
convinience = [0]

for i in ab:
    a, b = i
    res = convinience[-1]
    a -= 1
    b -= 1
    if find(a) == find(b):
        convinience.append(res)
        continue
    if size(a) > 1:
        res -= cmb(size(a), 2)
    if size(b) > 1:
        res -= cmb(size(b), 2)
    unite(a, b)
    res += cmb(size(a), 2)
    convinience.append(res)

convinience = convinience[1::][::-1] + [0]

ans = [0]
for i in range(m):
    ans.append(convinience[i] - convinience[i + 1] + ans[-1])
for i in ans[1:]:
    print(i) import sys sys input = sys.stdin.readline input sys.stdin.readline sys.stdin sys stdin readline int(x) for x in input().split() for x in input().split() x input().split() ().split () input split for x in input().split() int(x) int x n, m = [int(x) for x in input().split()] n [int(x) for x in input().split()] m [int(x) for x in input().split()] for _ in range(m) for _ in range(m) _ range(m) range m for _ in range(m) [int(x) for x in input().split()] ab = [[int(x) for x in input().split()] for _ in range(m)][::-1] ab [[int(x) for x in input().split()] for _ in range(m)][::-1] [[int(x) for x in input().split()] for _ in range(m)] ::-1 -1 def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
#xとyの属する集合の併合 find if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
#xとyの属する集合の併合 par[x] < 0 par[x] par x 0 return x x par[x] = find(par[x]) par[x] par x find(par[x]) find par[x] par x return par[x] par[x] par x x x def unite(x,y):
    x = find(x)
    y = find(y)

    if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

#xとyが同じ集合に属するかの判定 unite x = find(x) x find(x) find x y = find(y) y find(y) find y if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

#xとyが同じ集合に属するかの判定 x == y x y return False False if par[x] > par[y]:
            x,y = y,x
         par[x] > par[y] par[x] par x par[y] par y x,y = y,x x y y x par[x] += par[y] par[x] par x par[y] par y par[y] = x par[y] par y x return True True x x y y def same(x,y):
    return find(x) == find(y)

#xが属する集合の個数 same return find(x) == find(y) find(x) == find(y) find(x) find x find(y) find y x x y y def size(x):
    return -par[find(x)]

#初期化
#根なら-size,子なら親の頂点 size return -par[find(x)] -par[find(x)] par[find(x)] par find(x) find x x x par = [-1]*n par [-1]*n [-1] -1 n def cmb(n, k):
    return n * (n - 1) // 2 cmb return n * (n - 1) // 2 n * (n - 1) // 2 n * (n - 1) n n - 1 n 1 2 n n k k convinience = [0] convinience [0] 0 for i in ab:
    a, b = i
    res = convinience[-1]
    a -= 1
    b -= 1
    if find(a) == find(b):
        convinience.append(res)
        continue
    if size(a) > 1:
        res -= cmb(size(a), 2)
    if size(b) > 1:
        res -= cmb(size(b), 2)
    unite(a, b)
    res += cmb(size(a), 2)
    convinience.append(res) i ab a, b = i a i b res = convinience[-1] res convinience[-1] convinience -1 a -= 1 a 1 b -= 1 b 1 if find(a) == find(b):
        convinience.append(res)
        continue
     find(a) == find(b) find(a) find a find(b) find b convinience.append(res) convinience.append convinience append res continue if size(a) > 1:
        res -= cmb(size(a), 2)
     size(a) > 1 size(a) size a 1 res -= cmb(size(a), 2) res cmb(size(a), 2) cmb size(a) size a 2 if size(b) > 1:
        res -= cmb(size(b), 2)
     size(b) > 1 size(b) size b 1 res -= cmb(size(b), 2) res cmb(size(b), 2) cmb size(b) size b 2 unite(a, b) unite a b res += cmb(size(a), 2) res cmb(size(a), 2) cmb size(a) size a 2 convinience.append(res) convinience.append convinience append res convinience = convinience[1::][::-1] + [0] convinience convinience[1::][::-1] + [0] convinience[1::][::-1] [1::] convinience 1:: 1 ::-1 -1 [0] 0 ans = [0] ans [0] 0 for i in range(m):
    ans.append(convinience[i] - convinience[i + 1] + ans[-1]) i range(m) range m ans.append(convinience[i] - convinience[i + 1] + ans[-1]) ans.append ans append convinience[i] - convinience[i + 1] + ans[-1] convinience[i] - convinience[i + 1] convinience[i] convinience i convinience[i + 1] convinience i + 1 i 1 ans[-1] ans -1 for i in ans[1:]:
    print(i) i ans[1:] ans 1: 1 print(i) print i def unite(x,y):
    x = find(x)
    y = find(y)

    if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

#xとyが同じ集合に属するかの判定 def unite(x,y):
    x = find(x)
    y = find(y)

    if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

#xとyが同じ集合に属するかの判定 unite par = [-1]*n [-1]*n par a -= 1 1 a ans = [0] [0] ans input = sys.stdin.readline sys.stdin.readline input def same(x,y):
    return find(x) == find(y)

#xが属する集合の個数 def same(x,y):
    return find(x) == find(y)

#xが属する集合の個数 same def cmb(n, k):
    return n * (n - 1) // 2 def cmb(n, k):
    return n * (n - 1) // 2 cmb convinience = convinience[1::][::-1] + [0] convinience[1::][::-1] + [0] convinience a, b = i i a res -= cmb(size(b), 2) cmb(size(b), 2) res b -= 1 1 b n, m = [int(x) for x in input().split()] [int(x) for x in input().split()] n res -= cmb(size(a), 2) cmb(size(a), 2) res m = [int(x) for x in input().split()] [int(x) for x in input().split()] m res += cmb(size(a), 2) cmb(size(a), 2) res def size(x):
    return -par[find(x)]

#初期化
#根なら-size,子なら親の頂点 def size(x):
    return -par[find(x)]

#初期化
#根なら-size,子なら親の頂点 size ab = [[int(x) for x in input().split()] for _ in range(m)][::-1] [[int(x) for x in input().split()] for _ in range(m)][::-1] ab convinience = [0] [0] convinience res = convinience[-1] convinience[-1] res def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
#xとyの属する集合の併合 def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
#xとyの属する集合の併合 find b = i i b
import sys
input = sys.stdin.readline

n, m = [int(x) for x in input().split()]
ab = [[int(x) for x in input().split()] for _ in range(m)][::-1]

#Union Find

#xの根を求める
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]
#xとyの属する集合の併合
def unite(x,y):
    x = find(x)
    y = find(y)

    if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

#xとyが同じ集合に属するかの判定
def same(x,y):
    return find(x) == find(y)

#xが属する集合の個数
def size(x):
    return -par[find(x)]

#初期化
#根なら-size,子なら親の頂点
par = [-1]*n

def cmb(n, k):
    return n * (n - 1) // 2
convinience = [0]

for i in ab:
    a, b = i
    res = convinience[-1]
    a -= 1
    b -= 1
    if find(a) == find(b):
        convinience.append(res)
        continue
    if size(a) > 1:
        res -= cmb(size(a), 2)
    if size(b) > 1:
        res -= cmb(size(b), 2)
    unite(a, b)
    res += cmb(size(a), 2)
    convinience.append(res)

convinience = convinience[1::][::-1] + [0]

ans = [0]
for i in range(m):
    ans.append(convinience[i] - convinience[i + 1] + ans[-1])
for i in ans[1:]:
    print(i)
