def multival(): return list(map(int,input().split()))

def data(N=1): return [list(map(int,input().split())) for _ in range(N)]

mod = 10**9 + 7

inf = float("inf")



N,M = multival()

nemat = [[0]*N for _ in range(N)]

ans = 0

for _ in range(M):

    a,b = multival()

    a -= 1; b-= 1

    nemat[a][b] = 1

    nemat[b][a] = 1



def dfs(now=0,visited=[False]*N):

    visited[now] = True

    if all(visited) is True:

        global ans

        ans += 1

    for ne in range(N):

        if nemat[now][ne] == 1 and visited[ne] is False:

            dfs(ne,visited[:])

            # visited[:]

            # n方向に分かれて探索する際にそれぞれ別のvisitedを持たせる

            # そうしなければ例えばsample1では 1->2->3 と進んで全てに訪問済みの印が付く

            # 次に1->2と進もうとしても2は既にTrueに更新済みなので探索が終了してしまう



dfs()

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

ad = [[0]*N for _ in range(N)]

for _ in range(M):

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

    a -= 1; b -= 1

    ad[a][b] = 1

    ad[b][a] = 1



ans = 0



def dfs(v=0,d=0,visited=[1]+[0]*(N-1)):

    if d == N-1:

        global ans

        ans += 1

        return

    for nv, bit in enumerate(ad[v]):

        if bit == 0: continue

        if visited[nv] == 1: continue

        visited[nv] = 1

        dfs(nv,d+1)

        visited[nv] = 0



dfs()

print(ans)
def multival():
    return list(map(int, input().split()))


def data(N=1):
    return [list(map(int, input().split())) for _ in range(N)]


mod = 10**9 + 7
inf = float("inf")
N, M = multival()
nemat = [[0] * N for _ in range(N)]
ans = 0
for _ in range(M):
    a, b = multival()
    a -= 1
    b -= 1
    nemat[a][b] = 1
    nemat[b][a] = 1


def dfs(now=0, visited=[False] * N):
    visited[now] = True
    if all(visited) is True:
        global ans
        ans += 1
    for ne in range(N):
        if nemat[now][ne] == 1 and visited[ne] is False:
            dfs(ne, visited[:])
            # visited[:]
            # n方向に分かれて探索する際にそれぞれ別のvisitedを持たせる
            # そうしなければ例えばsample1では 1->2->3 と進んで全てに訪問済みの印が付く
            # 次に1->2と進もうとしても2は既にTrueに更新済みなので探索が終了してしまう


dfs()
print(ans)

N, M = list(map(int, input().split()))
ad = [[0] * N for _ in range(N)]
for _ in range(M):
    a, b = list(map(int, input().split()))
    a -= 1
    b -= 1
    ad[a][b] = 1
    ad[b][a] = 1
ans = 0


def dfs(v=0, d=0, visited=[1] + [0] * (N - 1)):
    if d == N - 1:
        global ans
        ans += 1
        return
    for nv, bit in enumerate(ad[v]):
        if bit == 0:
            continue
        if visited[nv] == 1:
            continue
        visited[nv] = 1
        dfs(nv, d + 1)
        visited[nv] = 0


dfs()
print(ans)

-def multival(): -    return list(map(int, input().split())) +N, M = list(map(int, input().split())) +ad = [[0] * N for _ in range(N)] +for _ in range(M): +    a, b = list(map(int, input().split())) +    a -= 1 +    b -= 1 +    ad[a][b] = 1 +    ad[b][a] = 1 +ans = 0 -def data(N=1): -    return [list(map(int, input().split())) for _ in range(N)] - - -mod = 10**9 + 7 -inf = float("inf") -N, M = multival() -nemat = [[0] * N for _ in range(N)] -ans = 0 -for _ in range(M): -    a, b = multival() -    a -= 1 -    b -= 1 -    nemat[a][b] = 1 -    nemat[b][a] = 1 - - -def dfs(now=0, visited=[False] * N): -    visited[now] = True -    if all(visited) is True: +def dfs(v=0, d=0, visited=[1] + [0] * (N - 1)): +    if d == N - 1: -    for ne in range(N): -        if nemat[now][ne] == 1 and visited[ne] is False: -            dfs(ne, visited[:]) -            # visited[:] -            # n方向に分かれて探索する際にそれぞれ別のvisitedを持たせる -            # そうしなければ例えばsample1では 1->2->3 と進んで全てに訪問済みの印が付く -            # 次に1->2と進もうとしても2は既にTrueに更新済みなので探索が終了してしまう +        return +    for nv, bit in enumerate(ad[v]): +        if bit == 0: +            continue +        if visited[nv] == 1: +            continue +        visited[nv] = 1 +        dfs(nv, d + 1) +        visited[nv] = 0