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
        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 (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

root' :: Int -> State SizedUF Int
root' x = maybe x id <$> root x

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