# Original solution
# Union-Find木（サイズ付き）
class UnionFind():
    def __init__(self, n):  # n要素で初期化　初めは全ての頂点が別々の木の根
        self.parent = [None] * n # 親
        self.rank = [None] * n   # 木の深さ
        self._size = [1] * n # 要素が属する集合の大きさ（根の要素のみ参照すること）
        for i in range(n):
            self.parent[i] = i
            self.rank[i] = 0

    # 木の根を求める
    def root_of(self, x):
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.root_of(self.parent[x])  # 経路圧縮して親が変わる
            return self.parent[x]

    # xとyの属する集合を併合
    def unite(self, x, y):
        rx = self.root_of(x)
        ry = self.root_of(y)
        if rx == ry:
            return
        if self.rank[rx] < self.rank[ry]: # ランクの小さい木から大きい木の根に辺を張る
            self.parent[rx] = ry  # rxをryの子とする
            self._size[ry] += self._size[rx]
        elif self.rank[rx] == self.rank[ry]:
            self.parent[ry] = rx
            self.rank[rx] += 1
            self._size[rx] += self._size[ry]
        else:
            self.parent[ry] = rx
            self._size[rx] += self._size[ry]

    # 同じ集合に属するかどうか
    def is_same(self, x, y):
        return self.root_of(x) == self.root_of(y)

    # 頂点xが属する集合のサイズ
    def size(self, x):
        return self._size[self.root_of(x)]

# 入力
N, M = [int(x) for x in input().split()]
A = [None] * M
B = [None] * M
for i in range(M):
    A[i], B[i] = [int(x) - 1 for x in input().split()]


# 島同士が全く繋がっていない状態からスタート
# M-1番目, M-2番目, ..., , 2番目, 1番目の橋の順に橋をかけていく
inconv = [-1] * (M - 1) + [N * (N - 1) // 2]    # 不便さ

uf = UnionFind(N)

for i in range(M - 1, 0, -1):
    # i番目の橋をかける
    if not uf.is_same(A[i], B[i]):
        size_a = uf.size(A[i]) # A[i]が属する集合の大きさ
        size_b = uf.size(B[i]) # B[i]が属する集合の大きさ
        inconv[i - 1] = inconv[i] - size_a * size_b
        uf.unite(A[i], B[i])
    else:
        inconv[i - 1] = inconv[i]

for i in range(M):
    print((inconv[i]))


# Optimized solution
# Union-Find木（サイズ付き）
class UnionFind():
    def __init__(self, n):  # n要素で初期化　初めは全ての頂点が別々の木の根
        self.parent = [None] * n # 親
        self.rank = [None] * n   # 木の深さ
        self._size = [1] * n # 要素が属する集合の大きさ（根の要素のみ参照すること）
        for i in range(n):
            self.parent[i] = i
            self.rank[i] = 0

    # 木の根を求める
    def root_of(self, x):
        children = [x]
        while self.parent[x] != x:
            x = self.parent[x]
            children.append(x)

        for ch in children: # 根の子供として張りなおす
            self.parent[ch] = x

        return x

    # xとyの属する集合を併合
    def unite(self, x, y):
        rx = self.root_of(x)
        ry = self.root_of(y)
        if rx == ry:
            return
        if self.rank[rx] < self.rank[ry]: # ランクの小さい木から大きい木の根に辺を張る
            self.parent[rx] = ry  # rxをryの子とする
            self._size[ry] += self._size[rx]
        elif self.rank[rx] == self.rank[ry]:
            self.parent[ry] = rx
            self.rank[rx] += 1
            self._size[rx] += self._size[ry]
        else:
            self.parent[ry] = rx
            self._size[rx] += self._size[ry]

    # 同じ集合に属するかどうか
    def is_same(self, x, y):
        return self.root_of(x) == self.root_of(y)

    # 頂点xが属する集合のサイズ
    def size(self, x):
        return self._size[self.root_of(x)]

# 入力
N, M = [int(x) for x in input().split()]
A = [None] * M
B = [None] * M
for i in range(M):
    A[i], B[i] = [int(x) - 1 for x in input().split()]


# 島同士が全く繋がっていない状態からスタート
# M-1番目, M-2番目, ..., , 2番目, 1番目の橋の順に橋をかけていく
inconv = [-1] * (M - 1) + [N * (N - 1) // 2]    # 不便さ

uf = UnionFind(N)

for i in range(M - 1, 0, -1):
    # i番目の橋をかける
    if not uf.is_same(A[i], B[i]):
        size_a = uf.size(A[i]) # A[i]が属する集合の大きさ
        size_b = uf.size(B[i]) # B[i]が属する集合の大きさ
        inconv[i - 1] = inconv[i] - size_a * size_b
        uf.unite(A[i], B[i])
    else:
        inconv[i - 1] = inconv[i]

for i in range(M):
    print((inconv[i]))