import java.util.*

fun main(args: Array<String>) {
    // 一筆書きでかけるかどうかを確認する，深さ優先探索で行えばよいか？
    // ノードがかぶっていないか -> 各探索で訪問したノードを記録しておく
    // パスがかぶっていないか -> 探索過程での分岐で保証

    // どのように訪問したノードを記録しておくか？？ -> スタックでどうか？？

    // 訪問したノードをスタックに入れていく
    
    
    
    val (n, m) = readLine()!!.split(" ").map { it.toInt() }

    // 隣接リストを作成
    val adjList = Array(n) { mutableListOf<Int>()}
    for (i in 0 until m) {
        val (s, t) = readLine()!!.split(" ").map { it.toInt() }
        adjList[s-1].add(t-1)
        adjList[t-1].add(s-1)
    }

    var stack = ArrayDeque<Int>()
    var cnt = 0

    fun dfs(index: Int) {

        if (stack.size + 1 == n){
            cnt += 1
            return
        }

        stack.push(index)
        for (next in adjList[index]) {
            if(!stack.contains(next)){
                dfs(next)
            }
        }

        stack.pop()

        return
    }

    dfs(0)

    print(cnt)
}