import qualified Data.ByteString.Char8 as B
import qualified Data.IntSet as S
import Data.Array.IArray
import Data.Maybe

type Vertex = Int
type Vertexes = S.IntSet
type Edge = (Vertex, Vertex)
type Graph = Array Vertex Vertexes

buildG :: Int -> [Edge] -> Graph
buildG n = accumArray (flip S.insert) S.empty (1, n)

from :: Graph -> Vertex -> Vertexes
from g = (g !)

readUndirectedEdge :: B.ByteString -> [Edge]
readUndirectedEdge = concatMap ((\[v,w] -> [(v,w),(w,v)]) . map readVertex . B.words) . B.lines

readVertex :: B.ByteString -> Vertex
readVertex = fst . fromJust . B.readInt

main :: IO ()
main = do
 [n,_] <- map read . words <$> getLine
 es <- readUndirectedEdge <$> B.getContents
 let g = buildG n es
 print (one_stroke n g 1 S.empty)

one_stroke :: Int -> Graph -> Vertex -> Vertexes -> Int
one_stroke n g v visited
  | S.size visited == n - 1 = 1
  | S.null next = 0
  | otherwise = S.foldr (\w acc -> acc + one_stroke n g w (S.insert v visited)) 0 next
  where next = S.difference (from g v) visited