def abc054_c_one_stroke_paths():

    import copy

    N, M = list(map(int, input().split()))



    # create graph G

    G = {}

    for m in range(M):

        a, z = list(map(int, input().split()))

        G[a] = G.get(a, [])

        G[a].append(z)

        G[z] = G.get(z, [])

        G[z].append(a)



    # print(G)



    # find all paths

    if G.get(1, 0) == 0:

        print((0))

        return



    paths = []



    def solve(a, path):

        path.append(a)

        if len(path) == N:

            paths.append(path)

            return

        for z in G.get(a):

            p = copy.copy(path)

            if z in p:

                continue

            solve(z, p)



    solve(1, [])

    # print(paths)

    print((len(paths)))





##########

if __name__ == "__main__":

    abc054_c_one_stroke_paths()

def abc054_c_one_stroke_paths():

    N, M = list(map(int, input().split()))



    # create graph G

    G = {}

    for m in range(M):

        a, z = list(map(int, input().split()))

        G[a] = G.get(a, [])

        G[a].append(z)

        G[z] = G.get(z, [])

        G[z].append(a)



    # print(G)



    # find all paths

    if G.get(1, 0) == 0:

        print((0))

        return



    def dfs(a, path):

        path.append(a)

        if len(path) == N:

            return 1



        paths = 0

        for z in G.get(a):

            if z in path:

                continue

            paths += dfs(z, path[:])



        return paths



    print((dfs(1, [])))





##########

if __name__ == "__main__":

    abc054_c_one_stroke_paths()

def abc054_c_one_stroke_paths():
    import copy

    N, M = list(map(int, input().split()))
    # create graph G
    G = {}
    for m in range(M):
        a, z = list(map(int, input().split()))
        G[a] = G.get(a, [])
        G[a].append(z)
        G[z] = G.get(z, [])
        G[z].append(a)
    # print(G)
    # find all paths
    if G.get(1, 0) == 0:
        print((0))
        return
    paths = []

    def solve(a, path):
        path.append(a)
        if len(path) == N:
            paths.append(path)
            return
        for z in G.get(a):
            p = copy.copy(path)
            if z in p:
                continue
            solve(z, p)

    solve(1, [])
    # print(paths)
    print((len(paths)))


##########
if __name__ == "__main__":
    abc054_c_one_stroke_paths()

def abc054_c_one_stroke_paths():
    N, M = list(map(int, input().split()))
    # create graph G
    G = {}
    for m in range(M):
        a, z = list(map(int, input().split()))
        G[a] = G.get(a, [])
        G[a].append(z)
        G[z] = G.get(z, [])
        G[z].append(a)
    # print(G)
    # find all paths
    if G.get(1, 0) == 0:
        print((0))
        return

    def dfs(a, path):
        path.append(a)
        if len(path) == N:
            return 1
        paths = 0
        for z in G.get(a):
            if z in path:
                continue
            paths += dfs(z, path[:])
        return paths

    print((dfs(1, [])))


##########
if __name__ == "__main__":
    abc054_c_one_stroke_paths()

-    import copy - -    paths = [] -    def solve(a, path): +    def dfs(a, path): -            paths.append(path) -            return +            return 1 +        paths = 0 -            p = copy.copy(path) -            if z in p: +            if z in path: -            solve(z, p) +            paths += dfs(z, path[:]) +        return paths -    solve(1, []) -    # print(paths) -    print((len(paths))) +    print((dfs(1, [])))