using System;
using System.Numerics;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace debug
{
    class main
    {
        static void Main(string[] args)
        {
            //問題クラスを展開
            ProgramD a = new ProgramD();
            a.main();//実行する

        }

    }

    class ProgramA
    {
        public void main()
        {
            //入力
            string[] s = Console.ReadLine().Split(' ');
            int sound = int.Parse(s[1]) / int.Parse(s[0]);

            if (sound < int.Parse(s[2]))
                Console.WriteLine(sound);
            else
                Console.WriteLine(int.Parse(s[2]));

        }
    }

    class ProgramB
    {
        public void main()
        {
            //入力
            string[] s = Console.ReadLine().Split(' ');
            int a = int.Parse(s[0]);
            int b = int.Parse(s[1]);
            int k = int.Parse(s[2]);

            int count = 0;

            for (int i = 100; i > 0; i--)
            {
                if (a % i == 0 && b % i == 0)
                    count++;

                if (count == k)
                {
                    Console.WriteLine(i);
                    return;
                }


            }
        }

        
    }

    class ProgramC
    {
        public void main()
        {

            //入力（decimal型だと桁精度が27桁ぐらいまである
            string s = Console.ReadLine();
            int count0 = 0;
            int count1 = 0;
           
            for(int i = 0;i < s.Length;i++)
            {
                if (s[i] == '0')
                    count0++;
                else
                    count1++;
            }

            Console.WriteLine(2 *Math.Min(count1, count0));

        }
    }

    class ProgramD
    {
        public void main()
        {

            //入力
            string[] s = Console.ReadLine().Split(' ');
            long n = long.Parse(s[0]);
            long m = long.Parse(s[1]);
            List<Path> path = new List<Path>();
            long[] ans = new long[m];

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

            //入力
            for (int i = 0; i < m; i++)
            {
                string[] t = Console.ReadLine().Split(' ');
                path.Add(new Path(long.Parse(t[0]) - 1, long.Parse(t[1]) - 1));
            }

            UnionFind tree = new UnionFind();//UnionFindクラスを設定
            tree.par = new long[n];
            tree.temp = new long[n];
            tree.reset(n);

            for (int i = 0; i < m - 1; i++)
            {
                if (tree.same(path[(int)m - 1 - i].a, path[(int)m - 1 - i].b) == false)
                    ans[m - 2 - i] = ans[m - 1 - i] - tree.size(path[(int)m - 1 - i].a) * tree.size(path[(int)m - 1 - i].b);
                else
                    ans[m - 2 - i] = ans[m - 1 - i];
                tree.unite(path[(int)m - 1 -i].a, path[(int)m - 1 - i].b); // xの木とyの木を併合する
                if (ans[m - 2 - i] == 0)
                    break;
            }
            //答え出力
            for (int i = 0;i < m;i++)
                Console.WriteLine(ans[i]);
        }
    }

    /*UnionFind法のクラス*/
    class UnionFind
    {

        public long[] par;
        public long[] temp;


        //マイナスは根を示す。
        public void reset(long n)
        {
            for (int i = 0; i < n; i++)
                par[i] = -1;
        }

        //マイナスならそれはまだ属していないので根である。そうでないならさかのぼる
        public long root(long x)
        {
            if (par[x] < 0)
                return x;
            else
                return root(par[x]);
        }

        //根の併合を行い、根には要素数を足す（マイナスの値）
        public void unite(long x, long y)
        { // xとyの木を併合
            long rx = root(x); //xの根をrx
            long ry = root(y); //yの根をry
            if (rx == ry)
                return; //xとyの根が同じ(=同じ木にある)時はそのまま
            if (par[ry] > par[rx])
            {
                long temp = ry;
                ry = rx;
                rx = temp;
            }
            par[ry] += par[rx];
            par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
        }

        // 2つのデータx, yが属する木が同じならtrueを返す
        public bool same(long x, long y)
        {
            long rx = root(x);
            long ry = root(y);
            return rx == ry;
        }


        //根の元に入っている
        public long size(long x)
        {
            return -par[root(x)];
        }
    }

    class Path
    {
        public long a;
        public long b;
        public Path(long a, long b)
        {
            this.a = a;
            this.b = b;
        }
    }
}






Measured memory_bytes: 27584