{-# LANGUAGE ScopedTypeVariables #-}

import qualified Data.ByteString.Char8 as B
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import qualified Data.Map as MP
import Data.List
import Data.Tuple
import Data.Char
import Data.IORef
import Control.Monad

type Graph = MP.Map Int [Int]

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)

make es = VU.foldl' step MP.empty (VU.map swap es VU.++ es)
    where
        step m (f,t) =
            case MP.lookup f m of
                Just _ -> MP.adjust (t:) f m
                Nothing -> MP.insert f [t] m

del graph (f,t) =
    let
        graph' = MP.adjust (delete f) t graph
        graph'' = MP.adjust (delete t) f graph' 
    in
        graph''

dfs :: Graph -> VUM.IOVector Bool -> Int -> IO Int
dfs graph table v = do
    r <- VUM.read table (v-1)
    if r 
        then return 0
        else do
            VUM.write table (v-1) True
            (table' :: VU.Vector Bool) <- VU.unsafeFreeze table
            let Just ns = MP.lookup v graph
            let ns' = delete v ns
            if (VU.and table')
                then return 1
                else if (Data.List.null ns')
                    then return 0
                    else do
                        res <- mapM (dfs graph table) ns'
                        return $ Data.List.sum res
                    
main = do
    (n,m) <- toTuple <$> B.getLine
    es <- VU.replicateM m (toTuple <$> B.getLine) 
    let graph = make es
    res <- newIORef (0 :: Int)
    forM_ [0..m-1] $ \i -> do
        tbl <- VUM.replicate n False
        let d = del graph (es VU.! i)
        solve <- dfs d tbl 1
        when (solve == 0) $ modifyIORef' res (+1)
    
    readIORef res >>= print