#include <bits/stdc++.h>

#define REP(i, n) for(decltype(n) i = 0; i < n; i++)

#define ALL(c)   c.begin(), c.end()
#define SORT(c)  std::sort(ALL(c))
#define RSORT(c) std::sort(ALL(c), std::greater<decltype(c)::value_type>())

using namespace std;
using ll = long long;

const int MOD  = (int)1e9 + 7;
const int INF  = (int)1e9 + 1;
const ll  LINF = (ll)1e18 + 1;

class UnionFind {
    using ll = long long;
public:
    struct Node {
        ll parent, weight, size, rank;
        Node(const ll& _parent = 0,
             const ll& _weight = 0,
             const ll& _size   = 1,
             const ll& _rank   = 0) :
            parent(_parent),
            weight(_weight),
            size(_size),
            rank(_rank) { }
    };

    explicit UnionFind(const ll& num_node) {
        node_.reserve(num_node);
        for(ll i = 0; i < num_node; i++) {
            node_.emplace_back(i);
        }
    }

    const std::vector<Node>& getNode() const {
        return node_;
    }

    ll searchAndZipRoot(const ll& x) {
        if(node_[x].parent == x) {
            return x;
        }
        else {
            node_[x].weight += node_[node_[x].parent].weight;
            return node_[x].parent = searchAndZipRoot(node_[x].parent);
        }
    }

    void unite(const ll& x,
               const ll& y,
               const ll& weight = 0) {
        auto rx = searchAndZipRoot(x);
        auto ry = searchAndZipRoot(y);
        if(rx != ry) {
            auto yw = weight + calcWeight(x) - calcWeight(y);
            if(node_[rx].rank < node_[ry].rank) {
                std::swap(rx, ry);
                yw *= -1;
            }
            node_[ry].parent  = rx;
            node_[ry].weight  = yw;
            node_[rx].size   += node_[ry].size;
            if(node_[rx].rank == node_[ry].rank) {
                node_[rx].rank++;
            }
        }
    }

    ll calcWeight(const ll& x) {
        searchAndZipRoot(x);
        return node_[x].weight;
    }

    ll calcDiff(const ll& x,
                const ll& y) {
        return std::abs(calcWeight(x) - calcWeight(y));
    }

    ll calcSize(const ll& x) {
        return node_[searchAndZipRoot(x)].size;
    }

    template<class... A>
    bool checkWhetherRootIsSame(const A&... nodes) {
        auto node_list = std::initializer_list<ll>{nodes...};
        if(node_list.size() < 2) return false;
        auto v = searchAndZipRoot(*node_list.begin());
        for(size_t i = 1; i < node_list.size(); i++) {
            if(v != searchAndZipRoot(*(node_list.begin() + i))) return false;
        }
        return true;
    }

private:
    std::vector<Node> node_;
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    ll N, M;
    std::cin >> N >> M;

    vector<pair<ll, ll>> bridge;
    bridge.reserve(M);
    REP(i, M) {
        ll a, b;
        std::cin >> a >> b;
        bridge.emplace_back(a - 1, b - 1);
    }

    UnionFind tree(N);

    vector<ll> ans;
    ans.reserve(M);
    ans.push_back((N * (N - 1)) / 2);
    for(ll i = bridge.size() - 1; 0 < i; i--) {
        auto comb = ans.back();
        if(!tree.checkWhetherRootIsSame(bridge[i].first, bridge[i].second)) {
            comb -= tree.calcSize(bridge[i].first) * tree.calcSize(bridge[i].second);
            tree.unite(bridge[i].first, bridge[i].second);
        }
        ans.push_back(comb);
    }

    for(ll i = ans.size() - 1; 0 <= i; i--) {
        std::cout << ans[i] << std::endl;
    }

    return 0;
}


Measured memory_bytes: 6784