unittest
{
	assert( [ "4 5", "1 2", "3 4", "1 3", "2 3", "1 4" ].solve == "0\n0\n4\n5\n6" );
	assert( [ "6 5", "2 3", "1 2", "5 6", "3 4", "4 5" ].solve == "8\n9\n12\n14\n15" );
	assert( [ "2 1", "1 2" ].solve == "1" );
}



import std.conv;
import std.format;
import std.range;
import std.stdio;

void main()
{
	stdin.byLineCopy.solve.writeln;
}

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto n = 0L;
	auto m = 0L;
	input.front.formattedRead!"%s %s"( n, m );
	auto abs = new long[ 2 ][ m ];
	foreach( ref ab; abs )
	{
		input.popFront;
		ab = input.front.split.to!( long[] );
		ab[] -= 1;
	}
	
	// 逆順で不便さを計算
	auto anss = new long[ 1 + m ];
	anss[ $ - 1 ] = n * ( n - 1 ) / 2;
	auto uft = UnionFindTree( n );
	foreach_reverse( i, ab; abs )
	{
		if( uft.same( ab[ 0 ], ab[ 1 ] ) ) continue;
		anss[ i ] = anss[ i + 1 ] - uft.weight( ab[ 0 ] ) * uft.weight( ab[ 1 ] );
		uft.unite( ab[ 0 ], ab[ 1 ] );
	}
	anss.popFront;
	return anss.to!( string[] ).join( "\n" );
}

// UnionFind木
struct UnionFindTree
{
	long[] ps;
	long[] rs;
	long   rn;
	
	this( long n )
	{
		ps.length = n;
		ps[] = -1;
		rs.length = n;
		rn = n;
	}
	
	long root( long i )
	{
		if( ps[ i ] < 0 ) return i;
		else              return ps[ i ] = root( ps[ i ] );
	}
	
	auto same( long i, long j )
	{
		return root( i ) == root( j );
	}
	
	auto unite( long i, long j )
	{
		i = root( i );
		j = root( j );
		if( i == j ) return;
		if( rs[ i ] < rs[ j ] )
		{
			ps[ j ] += ps[ i ];
			ps[ i ] = j;
		}
		else
		{
			ps[ i ] += ps[ j ];
			ps[ j ] = i;
			if( rs[ i ] == rs[ j ] ) rs[ i ]++;
		}
		rn--;
	}
	
	auto weight( long i )
	{
		return -ps[ root( i ) ];
	}
	
	auto toString()
	{
		return ps.to!( string );
	}
}
