import qualified Data.ByteString.Char8 as B
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Data.Char
import Control.Monad

type Parent = VUM.IOVector Int

makeUF :: Int -> IO Parent
makeUF n = do
    par <- VU.unsafeThaw $ VU.generate n id
    return par

root :: Int -> Parent -> IO Int
root x par = do
    r <- VUM.read par x
    if x == r
        then return x
        else do
            newr <- root r par
            VUM.write par x newr
            return newr

same :: Int -> Int -> Parent -> IO Bool
same x y par = do
    rx <- root x par
    ry <- root y par
    return $ rx == ry

unite :: Int -> Int -> Parent -> IO ()
unite x y par = do
    x' <- root x par
    y' <- root y par
    when (x' /= y') $ VUM.write par x' y'

toTuple :: B.ByteString -> (Int, Int)
toTuple bs =
    let
        Just (a, bs') = B.readInt bs
        Just (b, _) = B.readInt $ B.dropWhile isSpace bs'
    in
        (a, b)

main = do
    (n,m) <- toTuple <$> B.getLine 
    es <- VU.replicateM m (toTuple <$> B.getLine)
    let es' = VU.map (\(a,b) -> (a-1,b-1)) es
    xs <- forM [0..m-1] $ \i -> do
            par <- makeUF n
            forM_ [0..m-1] $ \j -> do 
                let (a,b) = es' VU.! j
                when (i/=j) $ unite a b par
            par' <- VU.unsafeFreeze par
            let res = VU.length $ VU.filter id $ VU.zipWith (==) par' (VU.fromList [0..n-1])
            return $ res > 1 
    print $ length [() | x<-xs, x]