import Control.Monad
import Data.List

main :: IO ()
main = do
  [n, m] <- map (read :: String -> Int) . words <$> getLine
  strs <- replicateM m getLine
  let es = sort $ concatMap strToEdge strs
  --mapM_ (putStrLn. show) $ [[node1, 1] | (node1, _) <- filter ((==1). snd) es]
  putStrLn . show  . length $ filter (\ls -> length ls == n) $ solve es
  --mapM_ (putStrLn . show) $ filter (\ls -> length ls == n) $ solve es

type Edge = (Int, Int)
type Path = [Int]

strToEdge :: String -> [Edge]
strToEdge str = [(from, to), (to, from)]
  where
    [from, to] = map read $ words str

solve :: [Edge] -> [Path]
solve es = go [[node1, 1] | (node1, _) <- filter ((==1). snd) es] []
  where
    go :: [Path] -> [Path] -> [Path]
    go [] result = result
    go (p:ps) result = 
      case candidates of
        [] -> go ps (p:result)
        _ -> do
          c <- candidates
          go ((snd c : p):ps) result
      where
        candidates = filter (\x -> (head p == fst x) &&(snd x `notElem` p) ) es

          
        
