'''
DisjointSetForestを作成するクラスを作ります。
参考：AtCoder Beginner Contest 120 解説放送 https://www.youtube.com/watch?v=zV3Ul2pA2Fw
masakiAOTAくんのやつ https://atcoder.jp/contests/abc157/submissions/10450290
'''
class DisjointSetForest:
    # 今回のクラスはインスタンスとしてdisjoint-set forestの構造を一つ保持するものとします。
    # この木構造は、各ノードに格納された数字がそのままindexになります。以降、これを「ノード番号」と呼びます。

    # まずコンストラクタを書きます。コンストラクタとは、インスタンスを作成する時に入力する、そのインスタンスの初期設定を定めるものです。
    def __init__(self,N):# 初期化の入力として、ノードの数を受け付けます。
        self.node = N# ”インスタンス名.node”とするとそのインスタンスに該当するdisjoint-set forestのノード数が帰ってくるようにします。
        self.parents = [-1]*N# "インスタンス名.parents"とすると、そのインスタンスに該当するdisjoint-set forest内の各ノードの親がどのノードかを保管するlistが帰ってくるようにします。自分が根の場合は、「-(自分が属する木のノード数)」を保管します。
        # 初期設定では、各ノードは全てバラバラになっていると考えるため、全てのノードに親は存在せず(つまり自分が根)、ここには-1(最初はそれぞれの木は一つしかノードを持たない)が保管されます。

    # 次にノード番号を受け取ったらそのノードが属する木の根ノードの番号を返す関数を作ります。
    def root(self,A):# ノード番号をAとして受け取ります。またコンストラクタで設定された初期設定も使いたいのでこれもselfとして受け取ります。
        if self.parents[A]<0:# もしノード番号Aのノードが根ノードなら、
            return A# 自分自身が根ノードです。
        else:# そうでないなら、
            # return self.root(self.parents[A]) 親ノードの根ノードを出力！ と行きたいところ。
            #しかし親にも親がいる場合、自分の親を、その親の親に変更したいよね
            self.parents[A] = self.root(self.parents[A])# 自分の親ノードの根ノードを自分の親ノードに更新します(これがこのアルゴリズムの肝らしい)
            return self.parents[A]# 更新してから自分の親を返せば、これは根を出力したことになります。
    
    # 次に木の大きさを返す関数です。
    def size(self,A):
    # あるノード番号を受け取ったら、そのノードが含まれる木のサイズを返します。
        # サイズはその根ノードの.parentsに負号として格納されているので、
        return -self.parents[self.root(A)]# 根の親の符号を反転させたものを出力します。

    # 次に木と木を結合させるメソッドを作ります。
    def unite(self,A,B):
    # あるノードAとノードBが結合するときを考えます。
    # この時AとBを直接つなげるのではなく、Aの根とBの根をつなげることにします。
    # 木を「つなげる」とは、具体的には 1.小さい方の木のノードにとっての根ノードを全て大きい木の根に書き換え、2.大きい木のサイズを二つの木のノード数の合計に更新するという処理になります。
    # このメソッド自体は、つなげられたらTrue,既に繋がっていてつなげられなかったらFalseを返す関数になります。

        # まず二つのノードA,Bをそれぞれの根ノードに変更しちゃいます。
        A = self.root(A)
        B = self.root(B)

        #もし既に同じ木に属するのなら、Falseを返します。
        if A==B:
            return False

        # そうでないなら、
        else:

            # つなげる処理の前に、二つの木のうち、大きい木の方の根をrootA,小さい木の方の根をrootBとします。
            if -self.parents[A] < -self.parents[B]:
                A, B = B, A
            
            # つなげます。
            # 2.大きい木(根がAの方)のサイズを更新します。
            self.parents[A] += self.parents[B]
            # 1.小さい木(根がBの方)に含まれるノードの根を全て大きい木の根(A)に変更します。
            self.parents[B] = A# ノードBの親がAである、としてしまえばいいのです。


            return True

    # 最後に二つのノードが同じ木に属するかどうかを判定する関数を作ります。
    def is_in_same(self,A,B):
    # 二つのノードA,Bが同じ木かどうか... → 根ノードが同じかどうかを見れば良い。
        return self.root(A) == self.root(B)


    

'''
https://atcoder.jp/contests/abc120/tasks/abc120_d
を解いてみます。
'''
# 読み込み
N,M = map(int,input().split())
A=[]
B=[]
for i in range(M):
    a,b = map(int,input().split())
    A.append(a-1)
    B.append(b-1)

# ノードの番号は0始まりindexなので島番号も1引いた物を入れます。

# 橋が全て壊れているところから不便さを計算していきます。
ans=[]
# まず全ての橋が壊れている時、不便さはN_C_2通りです。
ans.append(N*(N-1)//2)

# まずこの島のdisjoint-set forestのインスタンスを作成します。
island = DisjointSetForest(N)
for i in range(M):
    # とりあえず繋ぐ前の状態における島A[-i-1]と島B[-i-1]がそれぞれ属する木のノード数を獲得しておきます。
    sizeA=island.size(A[-i-1])
    sizeB=island.size(B[-i-1])

    # もしその二つの島が元々繋がっていなかったら、
    if island.unite(A[-i-1],B[-i-1]):
        ans.append(ans[i]-sizeA*sizeB)

    # 既に繋がっている橋だったら、
    else:
        ans.append(ans[i])

    

print(*ans[-2::-1],sep='\n')
# ans=ans[::-1]
# print(*ans[1:])

Measured memory_bytes: 18508