class UnionFind:
    def __init__(self, n):
        self.nodes = n
        self.parents = [i for i in range(n)]
        self.sizes = [1] * n
        self.rank = [0] * n

    def find(self, i): # どの集合に属しているか（根ノードの番号）
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) # 経路圧縮
            return self.parents[i]

    def unite(self, i, j): # 二つの集合を併合
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
    def same(self, i, j): # 同じ集合に属するかを判定
        return self.find(i)==self.find(j)

    def get_parents(self): # 根ノードの一覧を取得
        for n in range(self.nodes): # findで経路圧縮する
            self.find(n)
        return self.parents

    def size(self, i):
        p = self.find(i)
        return self.sizes[p]


N, M = map(int, input().split())
AB = []
B = []
for m in range(M):
    a, b = map(int, input().split())
    AB.append((a-1,b-1))

ans = []
score = N * (N-1) // 2
uf = UnionFind(N)
for a, b in AB[::-1]:
    ans.append(score)
    if not uf.same(a,b):
        score -= uf.size(a) * uf.size(b)
        uf.unite(a,b)    

for score in ans[::-1]:
    print(score) class UnionFind:
    def __init__(self, n):
        self.nodes = n
        self.parents = [i for i in range(n)]
        self.sizes = [1] * n
        self.rank = [0] * n

    def find(self, i): # どの集合に属しているか（根ノードの番号）
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) # 経路圧縮
            return self.parents[i]

    def unite(self, i, j): # 二つの集合を併合
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
    def same(self, i, j): # 同じ集合に属するかを判定
        return self.find(i)==self.find(j)

    def get_parents(self): # 根ノードの一覧を取得
        for n in range(self.nodes): # findで経路圧縮する
            self.find(n)
        return self.parents

    def size(self, i):
        p = self.find(i)
        return self.sizes[p] UnionFind def __init__(self, n):
        self.nodes = n
        self.parents = [i for i in range(n)]
        self.sizes = [1] * n
        self.rank = [0] * n

     __init__ self.nodes = n self.nodes self nodes n i for i in range(n) for i in range(n) i range(n) range n for i in range(n) i self.parents = [i for i in range(n)] self.parents self parents [i for i in range(n)] self.sizes = [1] * n self.sizes self sizes [1] * n [1] 1 n self.rank = [0] * n self.rank self rank [0] * n [0] 0 n self self n n def find(self, i): # どの集合に属しているか（根ノードの番号）
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) # 経路圧縮
            return self.parents[i]

     find if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) # 経路圧縮
            return self.parents[i]

     self.parents[i] == i self.parents[i] self.parents self parents i i return i i self.parents[i] = self.find(self.parents[i]) self.parents[i] self.parents self parents i self.find(self.parents[i]) self.find self find self.parents[i] self.parents self parents i return self.parents[i] self.parents[i] self.parents self parents i self self i i def unite(self, i, j): # 二つの集合を併合
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
     unite pi = self.find(i) pi self.find(i) self.find self find i pj = self.find(j) pj self.find(j) self.find self find j if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
     pi != pj pi pj if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
     self.rank[pi] < self.rank[pj] self.rank[pi] self.rank self rank pi self.rank[pj] self.rank self rank pj self.sizes[pj] += self.sizes[pi] self.sizes[pj] self.sizes self sizes pj self.sizes[pi] self.sizes self sizes pi self.parents[pi] = pj self.parents[pi] self.parents self parents pi pj self.sizes[pi] += self.sizes[pj] self.sizes[pi] self.sizes self sizes pi self.sizes[pj] self.sizes self sizes pj self.parents[pj] = pi self.parents[pj] self.parents self parents pj pi if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
     self.rank[pi] == self.rank[pj] self.rank[pi] self.rank self rank pi self.rank[pj] self.rank self rank pj self.rank[pi] += 1 self.rank[pi] self.rank self rank pi 1 self self i i j j def same(self, i, j): # 同じ集合に属するかを判定
        return self.find(i)==self.find(j)

     same return self.find(i)==self.find(j) self.find(i)==self.find(j) self.find(i) self.find self find i self.find(j) self.find self find j self self i i j j def get_parents(self): # 根ノードの一覧を取得
        for n in range(self.nodes): # findで経路圧縮する
            self.find(n)
        return self.parents

     get_parents for n in range(self.nodes): # findで経路圧縮する
            self.find(n)
         n range(self.nodes) range self.nodes self nodes self.find(n) self.find self find n return self.parents self.parents self parents self self def size(self, i):
        p = self.find(i)
        return self.sizes[p] size p = self.find(i) p self.find(i) self.find self find i return self.sizes[p] self.sizes[p] self.sizes self sizes p self self i i N, M = map(int, input().split()) N map(int, input().split()) map int input().split() ().split () input split M AB = [] AB [] B = [] B [] for m in range(M):
    a, b = map(int, input().split())
    AB.append((a-1,b-1)) m range(M) range M a, b = map(int, input().split()) a map(int, input().split()) map int input().split() ().split () input split b AB.append((a-1,b-1)) AB.append AB append (a-1,b-1) a-1 a 1 b-1 b 1 ans = [] ans [] score = N * (N-1) // 2 score N * (N-1) // 2 N * (N-1) N N-1 N 1 2 uf = UnionFind(N) uf UnionFind(N) UnionFind N for a, b in AB[::-1]:
    ans.append(score)
    if not uf.same(a,b):
        score -= uf.size(a) * uf.size(b)
        uf.unite(a,b)     a b AB[::-1] AB ::-1 -1 ans.append(score) ans.append ans append score if not uf.same(a,b):
        score -= uf.size(a) * uf.size(b)
        uf.unite(a,b)     not uf.same(a,b) uf.same(a,b) uf.same uf same a b score -= uf.size(a) * uf.size(b) score uf.size(a) * uf.size(b) uf.size(a) uf.size uf size a uf.size(b) uf.size uf size b uf.unite(a,b) uf.unite uf unite a b for score in ans[::-1]:
    print(score) score ans[::-1] ans ::-1 -1 print(score) print score score = N * (N-1) // 2 N * (N-1) // 2 score N, M = map(int, input().split()) map(int, input().split()) N b = map(int, input().split()) map(int, input().split()) b AB = [] [] AB a, b = map(int, input().split()) map(int, input().split()) a uf = UnionFind(N) UnionFind(N) uf M = map(int, input().split()) map(int, input().split()) M class UnionFind:
    def __init__(self, n):
        self.nodes = n
        self.parents = [i for i in range(n)]
        self.sizes = [1] * n
        self.rank = [0] * n

    def find(self, i): # どの集合に属しているか（根ノードの番号）
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) # 経路圧縮
            return self.parents[i]

    def unite(self, i, j): # 二つの集合を併合
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
    def same(self, i, j): # 同じ集合に属するかを判定
        return self.find(i)==self.find(j)

    def get_parents(self): # 根ノードの一覧を取得
        for n in range(self.nodes): # findで経路圧縮する
            self.find(n)
        return self.parents

    def size(self, i):
        p = self.find(i)
        return self.sizes[p] class UnionFind:
    def __init__(self, n):
        self.nodes = n
        self.parents = [i for i in range(n)]
        self.sizes = [1] * n
        self.rank = [0] * n

    def find(self, i): # どの集合に属しているか（根ノードの番号）
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) # 経路圧縮
            return self.parents[i]

    def unite(self, i, j): # 二つの集合を併合
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
    def same(self, i, j): # 同じ集合に属するかを判定
        return self.find(i)==self.find(j)

    def get_parents(self): # 根ノードの一覧を取得
        for n in range(self.nodes): # findで経路圧縮する
            self.find(n)
        return self.parents

    def size(self, i):
        p = self.find(i)
        return self.sizes[p] UnionFind B = [] [] B score -= uf.size(a) * uf.size(b) uf.size(a) * uf.size(b) score ans = [] [] ans
class UnionFind:
    def __init__(self, n):
        self.nodes = n
        self.parents = [i for i in range(n)]
        self.sizes = [1] * n
        self.rank = [0] * n

    def find(self, i): # どの集合に属しているか（根ノードの番号）
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) # 経路圧縮
            return self.parents[i]

    def unite(self, i, j): # 二つの集合を併合
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
    def same(self, i, j): # 同じ集合に属するかを判定
        return self.find(i)==self.find(j)

    def get_parents(self): # 根ノードの一覧を取得
        for n in range(self.nodes): # findで経路圧縮する
            self.find(n)
        return self.parents

    def size(self, i):
        p = self.find(i)
        return self.sizes[p]


N, M = map(int, input().split())
AB = []
B = []
for m in range(M):
    a, b = map(int, input().split())
    AB.append((a-1,b-1))

ans = []
score = N * (N-1) // 2
uf = UnionFind(N)
for a, b in AB[::-1]:
    ans.append(score)
    if not uf.same(a,b):
        score -= uf.size(a) * uf.size(b)
        uf.unite(a,b)    

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