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

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



for i in range(M):

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

    adj_matrix[a-1][b-1] = 1

    adj_matrix[b-1][a-1] = 1



def dfs(v, used):

    if not False in used:

        return 1



    ans = 0

    for i in range(N):

        if not adj_matrix[v][i]:

            continue

        if used[i]:

            continue

        used[i] = True

        ans += dfs(i, used)

        used[i] = False        

    return ans



used = [False] * N

used[0] = True

print((dfs(0, used)))
N, M = list(map(int, input().split()))

g = [[] for i in range(N)]



for i in range(M):

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

  g[a-1].append(b-1)

  g[b-1].append(a-1)



memo = {}

All_used = (1 << N) - 1



def dfs(v, used):

  if used == All_used:

    return 1

  key = (v, used)

  if key in memo:

    return memo[key]

  ans = 0

  for u in g[v]:

    if (used >> u) & 1 ==1:

      continue

    used ^= (1 << u)

    ans += dfs(u, used)

    used ^= (1 << u)

  memo[key] = ans

  return ans



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


def dfs(v, used):
    if not False in used:
        return 1
    ans = 0
    for i in range(N):
        if not adj_matrix[v][i]:
            continue
        if used[i]:
            continue
        used[i] = True
        ans += dfs(i, used)
        used[i] = False
    return ans


used = [False] * N
used[0] = True
print((dfs(0, used)))

N, M = list(map(int, input().split()))
g = [[] for i in range(N)]
for i in range(M):
    a, b = list(map(int, input().split()))
    g[a - 1].append(b - 1)
    g[b - 1].append(a - 1)
memo = {}
All_used = (1 << N) - 1


def dfs(v, used):
    if used == All_used:
        return 1
    key = (v, used)
    if key in memo:
        return memo[key]
    ans = 0
    for u in g[v]:
        if (used >> u) & 1 == 1:
            continue
        used ^= 1 << u
        ans += dfs(u, used)
        used ^= 1 << u
    memo[key] = ans
    return ans


print((dfs(0, 1)))

-adj_matrix = [[0] * N for _ in range(N)] +g = [[] for i in range(N)] -    adj_matrix[a - 1][b - 1] = 1 -    adj_matrix[b - 1][a - 1] = 1 +    g[a - 1].append(b - 1) +    g[b - 1].append(a - 1) +memo = {} +All_used = (1 << N) - 1 -    if not False in used: +    if used == All_used: +    key = (v, used) +    if key in memo: +        return memo[key] -    for i in range(N): -        if not adj_matrix[v][i]: +    for u in g[v]: +        if (used >> u) & 1 == 1: -        if used[i]: -            continue -        used[i] = True -        ans += dfs(i, used) -        used[i] = False +        used ^= 1 << u +        ans += dfs(u, used) +        used ^= 1 << u +    memo[key] = ans -used = [False] * N -used[0] = True -print((dfs(0, used))) +print((dfs(0, 1)))