import qualified Data.IntMap.Strict as M
import Control.Monad.State.Strict

main :: IO ()
main = do
  [n, m] <- map read . words <$> getLine
  bs <- sequence . replicate m $ unsafeListToTuple . map read . words <$> getLine
  sequence_ . map print . scanl1 (+) . evalState (foldr (flip (>>=) . f) (return []) bs) $ newUF
    where
      f (x, y) ls = do
        x' <- root x
        y' <- root y
        if x' == y'
          then
            return $ 0 : ls
          else
            do
              nx <- size' x'
              ny <- size' y'
              unite' x' y'
              return $ (nx * ny) : ls

unsafeListToTuple :: [a] -> (a, a)
unsafeListToTuple (x : y : _) = (x, y)
unsafeListToTuple _ = undefined

type SizedUF = (M.IntMap Int, M.IntMap Integer)

newUF :: SizedUF
newUF = (M.empty, M.empty)

unite :: Int -> Int -> State SizedUF ()
unite x y = do
  x' <- root x
  y' <- root y
  if x' == y'
    then
      return ()
    else
      nx <- size x'
      ny <- size y'
      (ps, cs) <- get
      put (M.insert y' x' ps, M.insert x' (nx + ny) cs)

unite' :: Int -> Int -> State SizedUF ()
unite' x' y' = do
  nx <- size' x'
  ny <- size' y'
  (ps, cs) <- get
  put (M.insert y' x' ps, M.insert x' (nx + ny) cs)

find :: Int -> Int -> State SizedUF Bool
find x y = (==) <$> root x <*> root y

root :: Int -> State SizedUF Int
root = \x -> maybe x id <$> root' x
  where
    root' :: Int -> State SizedUF (Maybe Int)
    root' x = do
      px <- M.lookup x . fst <$> get
      case px of
        Nothing -> return Nothing
        Just y -> do
          ry <- root' y
          case ry of
            Nothing -> return px
            Just z -> do
              (ps, cs) <- get
              put (M.insert x z ps, cs)
              return ry

size :: Int -> State SizedUF Integer
size x = do
  x' <- root x
  (M.findWithDefault 1 x') . snd <$> get

size' :: Int -> State SizedUF Integer
size' x' = do
  (M.findWithDefault 1 x') . snd <$> get
