package main

import (
	"fmt"
	"os"
	"sort"
)

// {{{
// source: https://github.com/raahii/algo
func MaxInts(nums ...int) int {
	var maxVal int
	for i, e := range nums {
		if i == 0 || e > maxVal {
			maxVal = e
		}
	}
	return maxVal
}

func MaxIntsWithIdx(nums ...int) (int, int) {
	var maxIdx, maxVal int
	for i, e := range nums {
		if i == 0 || e > maxVal {
			maxIdx = i
			maxVal = e
		}
	}
	return maxVal, maxIdx
}

func MinInts(nums ...int) int {
	var minVal int
	for i, e := range nums {
		if i == 0 || e < minVal {
			minVal = e
		}
	}
	return minVal
}

func MinIntsWithIdx(nums ...int) (int, int) {
	var minIdx, minVal int
	for i, e := range nums {
		if i == 0 || e < minVal {
			minIdx = i
			minVal = e
		}
	}
	return minVal, minIdx
}

func SumInts(nums []int) int {
	s := 0
	for _, v := range nums {
		s += v
	}
	return s
}

func SumInts2d(mat [][]int) int {
	s := 0
	for _, nums := range mat {
		for _, v := range nums {
			s += v
		}
	}
	return s
}

func ReverseInts(nums []int) []int {
	rnums := make([]int, len(nums))
	for i := 0; i < len(nums); i++ {
		rnums[len(nums)-1-i] = nums[i]
	}
	return rnums
}

func ExtendInts(nums1 []int, nums2 []int) []int {
	for _, v := range nums2 {
		nums1 = append(nums1, v)
	}
	return nums1
}

func Ints2d(n_rows, n_cols int) [][]int {
	ints := make([][]int, n_rows)
	for i := 0; i < n_rows; i++ {
		ints[i] = make([]int, n_cols)
	}
	return ints
}

func StrInts2d(mat [][]int) string {
	str := ""
	for i := 0; i < len(mat); i++ {
		str += fmt.Sprintf("[%d", mat[i][0])
		for j := 1; j < len(mat[0]); j++ {
			str += fmt.Sprintf(" %d", mat[i][j])
		}
		str += "]"
		if i != len(mat)-1 {
			str += "\n"
		}
	}
	return str
}

func MemsetInts1d(nums []int, val int) {
	for i := range nums {
		nums[i] = val
	}
}

func MemsetInts2d(nums [][]int, val int) {
	for i := range nums {
		for j := range nums[i] {
			nums[i][j] = val
		}
	}
}

func ContainsInt(nums []int, num int) bool {
	sort.Ints(nums)

	s, e := 0, len(nums)
	for {
		if s >= e {
			break
		}

		m := (e + s) / 2
		if nums[m] == num {
			return true
		} else if num > nums[m] {
			s = m + 1
		} else {
			e = m
		}
	}

	return false
}

func ReadInt(f *os.File) int {
	var n int
	fmt.Fscanf(f, "%d", &n)
	return n
}

func ReadInts(f *os.File, n int) []int {
	nums := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(f, "%d", &nums[i])
	}
	return nums
}

func ScanInts(f *os.File, vars ...*int) {
	for i := 0; i < len(vars); i++ {
		fmt.Fscanf(f, "%d", vars[i])
	}
}

func ReadLine(f *os.File) string {
	var str string
	fmt.Fscanf(f, "%s", &str)

	return str
}

func ReadLines(f *os.File, n int) []string {
	lines := make([]string, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(f, "%s", &lines[i])
	}

	return lines
}

func ReadWords(f *os.File, n int) []string {
	strs := make([]string, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(f, "%s", &strs[i])
	}
	return strs
}

func Pow(a, n int) int {
	c := 1
	for i := 0; i < n; i++ {
		c *= a
	}
	return c
}

func Abs(n int) int {
	if n < 0 {
		return -n
	}

	return n
}

// }}}

type UnionFind struct {
	Size  int
	Nodes []int
	Ranks []int
}

func NewUnionFind(n int) *UnionFind {
	nodes := make([]int, n)
	counts := make([]int, n)
	for i := 0; i < n; i++ {
		nodes[i] = i
		counts[i] = 1
	}
	return &UnionFind{n, nodes, counts}
}

func (p *UnionFind) Root(a int) int {
	nodes := []int{}

	par := p.Nodes[a]
	var root int
	for {
		if par == p.Nodes[par] {
			root = par
			break
		}
		nodes = append(nodes, par)
		par = p.Nodes[par]
	}

	for _, n := range nodes {
		p.Nodes[n] = root
	}

	return root
}

func (p *UnionFind) Merge(a, b int) {
	if a == b {
		return
	}

	if p.Rank(a) > p.Rank(b) {
		a, b = b, a
	}
	ra, rb := p.Root(a), p.Root(b)
	p.Nodes[rb] = ra
	p.Ranks[ra] += p.Ranks[rb]
	p.Ranks[rb] = 0
}

func (p *UnionFind) Same(a, b int) bool {
	return p.Root(a) == p.Root(b)
}

func (p *UnionFind) Rank(a int) int {
	return p.Ranks[p.Root(a)]
}

func solve(A, B []int, n int) {
	m := len(A)
	ans := make([]int, m)
	now := n * (n - 1) / 2
	ans[m-1] = now

	uf := NewUnionFind(n)

	for i := m - 1; i > 0; i-- {
		if uf.Same(A[i], B[i]) {
			ans[i-1] = now
			continue
		}

		now -= uf.Rank(A[i]) * uf.Rank(B[i])
		ans[i-1] = now
		uf.Merge(A[i], B[i])
	}

	for _, v := range ans {
		fmt.Println(v)
	}
}

var item [][]int
var root []int

func prepare(n int) {
	item = make([][]int, n)
	root = make([]int, n)
	for i := 0; i < n; i++ {
		item[i] = []int{i}
		root[i] = i
	}
}

func main() {
	var n, m int
	fmt.Scan(&n, &m)
	prepare(n)

	A, B := make([]int, m), make([]int, m)
	var a, b int
	for i := 0; i < m; i++ {
		fmt.Scan(&a, &b)
		A[i], B[i] = a-1, b-1
	}

	solve(A, B, n)
}

Measured memory_bytes: 16000