import           Control.Monad (replicateM)
import           Data.Foldable (for_)
import           Data.List     (intersect, mapAccumL, partition)
import qualified Data.List     as L (find)
import           Data.Maybe    (fromJust)

main :: IO ()
main = do
  [n, m] <- map read . words <$> getLine
  bridges <- replicateM m $ do
    [a, b] <- map read . words <$> getLine
    pure (a, b)
  for_ (solve n bridges) print

type Island = Int
type Bridge = (Island, Island)
type Inconvenience = Int
type Convenience = Int

solve :: Int -> [Bridge] -> [Inconvenience]
solve n = (++ [maxInconvenience]) . tail . map (maxInconvenience -) . reverse . snd . mapAccumL f (0, map pure [1..n]) . reverse
  where
    f :: (Convenience, [[Island]]) -> Bridge -> ((Convenience, [[Island]]), Convenience)
    f (convenience, islandGroups) (i1, i2) =
      let
        contain1 = find i1 islandGroups
        contain2 = find i2 islandGroups

        bothContained = contain1 == contain2

        convenience' =
          convenience + (if bothContained then 0 else length contain1 * length contain2)
        islandGroups' =
          if bothContained then islandGroups else union i1 i2 islandGroups
      in
        ((convenience', islandGroups'), convenience')

    maxInconvenience :: Inconvenience
    maxInconvenience = n * (n - 1) `div` 2

find :: Eq a => a -> [[a]] -> [a]
find x xss = fromJust $ L.find (x `elem`) xss

union :: Eq a => a -> a -> [[a]] -> [[a]]
union x1 x2 xss =
  let
    (contain1, notContain1) = partition (x1 `elem`) xss
    (contain2, notContain2) = partition (x2 `elem`) xss
    containNeither = notContain1 `intersect` notContain2
  in
    (head contain1 ++ head contain2) : containNeither

-- size :: Eq a => a -> [[a]] -> Int
-- size = (length .) . find
