CodeEff/ECCO huggingface dataset:
# Original solution
#制約が小さいので全探索する
n,m=list(map(int,input().split()))
#辺があるかどうかが知りたい→隣接行列表現
es=[[0]*n for i in range(n)]
for i in range(m):
  a,b=list(map(int,input().split()))
  es[a-1][b-1]=1
  es[b-1][a-1]=1

#順列を作る
from itertools import permutations
per=[i+1 for i in range(n-1)]
per=list(permutations(per,n-1))

#全探索する
ans=0
for i in per:
  cnt=0
  if es[0][i[0]]==0:
    continue
  else:
    for j in range(1,n-1):
      if es[i[j]][i[j-1]]==0:
        cnt+=1
    if cnt==0:
      ans=ans+1
print(ans)



# Optimized solution
n,m=list(map(int,input().split()))
# 再帰の深さが1000を超えそうなときはこれをやっておく
import sys
sys.setrecursionlimit(10**7)

#隣接行列表現
es=[[0 for i in range(n)] for j in range(n)]
for i in range(m):
  a,b=list(map(int,input().split()))
  es[a-1][b-1]=1
  es[b-1][a-1]=1

  
#深さ優先探索

def dfs(v,visited):
  ans=0
  
  #自分が今いるところは探索済にする
  visited[v-1]=1
 
  #全部探索できたことになる
  if visited==check:
    visited[v-1]=0
    return 1
  
  #vから行けるところを考える
  for i in range(n):
    #道があって未訪問
    if visited[i]==0 and es[v-1][i]==1:
      ans=ans+dfs(i+1,visited)
  #次の探索のため未訪問にしておく
  visited[v-1]=0
   
  return ans





visited=[0 for i in range(n)]
check=[1 for i in range(n)]
print((dfs(1,visited)))
# Original solution
N, M = list(map(int, input().split()))
E = [[] for _ in range(N)]
for m in range(M):
    a, b = list(map(int, input().split()))
    a -= 1
    b -= 1
    E[a].append(b)
    E[b].append(a)

check = [False] * N
check[0] = True
def dfs(v):
    if sum(check) == N:
        return 1
    ans = 0
    for u in E[v]:
        if check[u]:
            continue
        check[u] = True
        ans += dfs(u)
        check[u] = False
    return ans
print((dfs(0)))


# Optimized solution
from itertools import permutations

N, M = list(map(int, input().split()))
E = [set() for _ in range(N)]
for _ in range(M):
    a, b = list(map(int, input().split()))
    E[a-1].add(b-1)
    E[b-1].add(a-1)

ans = 0
for p in permutations([i for i in range(1, N)]):
    i = 0
    for j in p:
        if j not in E[i]:
            break
        i = j
    else:
        ans += 1
print(ans)
# Original solution
from collections import deque

def dfs(G, visited, s, n, ans):
  # すべての頂点を訪れた場合の処理
  if all(visited) :
    ans += 1
    return ans
  #　次の頂点の探索
  for i in G[s] :
    if visited[i] == False :
      visited[i] = True
      ans = dfs(G, visited, i, n, ans)
      visited[i] = False
  return ans

#　グラフGの入力
n,m = list(map(int,input().split()))
G = [[] for j 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)
  

visited = [False for i in range(n)]
visited[0] = True
ans = 0
print((dfs(G, visited, 0, n, ans)))

# Optimized solution
# -*- coding: utf-8 -*-
n,m = list(map(int, input().split()))
graph = [[] for j in range(n)]

for i in range(m):
    a,b = list(map(int, input().split()))
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)

used = [False]*n
used[0] = True

def DFS(v,used):
    if all(used):
        return 1
    ans = 0
    for i in graph[v]:
        if used[i]:
            continue
        used[i] = True
        ans += DFS(i,used)
        used[i] = False
    return ans
  
print((DFS(0,used)))
# Original solution
N,M = list(map(int,input().split()))

P=[]
for m in range(M):
    P.append(list(map(int,input().split())))

from itertools import combinations

ans=0
for c in combinations(list(range(M)),N-1):
    visit = [1]
    P_visit=[]
    v=0
    start=visit[0]
    while v < 100:
        v+=1
        for c_ in c:
            if c_ in P_visit:
                continue
            if P[c_][0] == start:
                visit.append(P[c_][1])
                start = P[c_][1]
                P_visit.append(c_)
                
            elif P[c_][1] == start:
                visit.append(P[c_][0])
                start = P[c_][0]
                P_visit.append(c_)
    
    if len(set(visit))== N:
        ans += 1
print(ans)

# Optimized solution
from itertools import permutations

N,M = list(map(int,input().split()))
P=[]
for m in range(M):
    P.append(list(map(int,input().split())))

ad={}
for _ in range(1,N+1):
    ad[_]=set()
    
for p in P:
    ad[p[0]].add(p[1])
    ad[p[1]].add(p[0])

ans=0
for p in permutations(list(range(2,N+1)),N-1):
    ans_flag=True
    start=1
    for p_ in p:
        end=p_
#         print(start,end ,end in ad[start])
        if end not in ad[start]:
#             print('break')
            ans_flag=False
            break
        start=p_
        
    if ans_flag==True:
        ans+=1
        
print(ans)
# Original solution
from collections import defaultdict
from itertools import permutations
N, M = list(map(int, input().split()))
dic = defaultdict(list)
for i in range(M):
  a, b = list(map(int, input().split()))
  dic[a-1] += [b-1]
  dic[b-1] += [a-1]

ans = 0
ls = permutations(list(range(1,N)))
for l in ls:
  l = [0]+list(l)
  for i in range(N-1):
    if not l[i+1] in dic[l[i]]:
      break
    if i==N-2:
      ans += 1
print(ans)

# Optimized solution
from itertools import permutations
N, M, *L = list(map(int, open(0).read().split()))
dic = [[] for i in range(N+1)]
for a, b in zip(*[iter(L)]*2):
  dic[a].append(b)
  dic[b].append(a)

ans = 0
for l in permutations(list(range(2,N+1))):
  l = [1]+list(l)
  for i in range(N-1):
    if l[i+1] not in dic[l[i]]:
      break
  else:
    ans += 1
print(ans)
# Original solution
import sys
from itertools import permutations
input = sys.stdin.readline

def main():
    N, M = list(map(int, input().split()))
    link = [[False] * N for i in range(N)]

    for i in range(M):
        a, b = list(map(int, input().split()))
        link[a-1][b-1] = True
        link[b-1][a-1] = True
    
    ans = 0
    path = [i for i in range(1, N)]
    for p in permutations(path):
        if link[0][p[0]]:
            ok = True
            for i in range(N-2):
                if not link[p[i]][p[i+1]]:
                    ok = False
                    break
            if ok:
                ans += 1
    print(ans)

if __name__ == "__main__":
    main()

# Optimized solution
from itertools import permutations
import sys
input = sys.stdin.readline

def main():
    N, M = list(map(int, input().split()))
    link = [[False] * N for i in range(N)]
    for i in range(M):
        a, b = list(map(int, input().split()))
        link[a-1][b-1] = True
        link[b-1][a-1] = True
    
    ans = 0
    for p in permutations(list(range(1, N))):
        # print(0, p)
        pre = 0
        ok = True
        for t in p:
            if not link[pre][t]:
                ok = False
                break
            pre = t
        if ok:
            ans += 1
    print(ans)

if __name__ == "__main__":
    main()
# Original solution
N, M = [int(v) for v in input().split()]
tbl = [[0] * (N + 1) for _ in range(N+1)]
for _ in range(M):
    a, b = [int(v) for v in input().split()]
    tbl[a][b] = 1
    tbl[b][a] = 1

ans = 0
paths = [[1, ]]
while paths:
    p = paths.pop()

    for i in range(1, N + 1):
        if p[-1] == i: continue
        if tbl[p[-1]][i] and i not in p:
            np = p + [i]
            if len(np) == N:
                ans += 1
            paths.append(np)
print(ans)

# Optimized solution
N, M = [int(v) for v in input().split()]
tbl = [[0] * (N + 1) for _ in range(N + 1)]


def dfs(v, visited):
    if len(visited) == N:
        return 1

    ans = 0
    for i in range(1, N + 1):
        if i == v: continue
        if tbl[i][v] == 1 and i not in visited:
            visited.append(i)
            ans += dfs(i, visited)
            visited.pop()
    return ans


for _ in range(M):
    a, b = [int(v) for v in input().split()]
    tbl[a][b] = 1
    tbl[b][a] = 1

paths = [1, ]
print((dfs(1, paths)))
# Original solution
#!/usr/bin/python
# -*- Coding: utf-8 -*-
n,m = list(map(int,input().split()))

H = [[0 for _ in range(n)] for _ in range(n) ]

edge_list = []

for _ in range(m):
    a, b = list(map(int,input().split()))
    edge_list.append([a-1,b-1])
    H[a-1][b-1] = 1
    H[b-1][a-1] = 1
    
l = [0 for _ in range(n)]
ans = 0
l[0] = 1

def dfs(node,x):
    global ans
    if x.count(0) == 0:
        ans += 1 
        return 0


    else:
        visited = x
        visited[node] = 1
        for node_,edge_ in enumerate(H[node]):
            if edge_ == 1 and visited[node_] != 1:
                visited[node_] = 1
                visited[node] = 1
                dfs(node_,visited)
                visited[node_] = 0
                #頂点iをここで未訪問にすることが一番重要！！！！！



dfs(0,l)
print(ans)


# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

n,m = list(map(int,input().split()))
H = [[0 for _ in range(n)] for _ in range(n) ]

for _ in range(m):
    a, b = list(map(int,input().split()))
    H[a-1][b-1] = 1
    H[b-1][a-1] = 1
    
l = [0 for _ in range(n)]
ans = 0

def dfs(node,visited):
    global ans
    if visited.count(0) == 0:
        ans += 1 
        return 0
    else:
        visited[node] = 1
        for node_,edge_ in enumerate(H[node]):
            if edge_ == 1 and visited[node_] != 1:
                visited[node_] = 1
                visited[node] = 1
                dfs(node_,visited)
                visited[node_] = 0

dfs(0,l)
print(ans)
# Original solution
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()


# Optimized solution
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()
# Original solution
N,M=list(map(int,input().split()))
inp=[list(map(int,input().split())) for _ in range(M)]
g=[[] for _ in range(N)]
[g[a-1].append(b-1) for a,b in inp]
[g[b-1].append(a-1) for a,b in inp]
 
from itertools import permutations
seq=[i for i in range(N)]
test=list(permutations(seq))
cnt=0
for t in test:
    if t[0]==0:
        for i in range(N-1):
            if t[i+1] not in g[t[i]]:
                break
        else:
            cnt+=1
print(cnt)

# Optimized solution
n,m=list(map(int,input().split()))
ab=[list(map(int,input().split())) for _ in [0]*m]
g=[[] for _ in [0]*n]
[g[a-1].append(b-1) for a,b in ab]
[g[b-1].append(a-1) for a,b in ab]

from itertools import permutations

cnt=0
for i in permutations(list(range(1,n))):
    i=(0,)+i
    for j in range(n-1):
        if i[j+1] not in g[i[j]]:
            break
    else:
        cnt+=1
print(cnt)
# Original solution
import itertools
N, M = list(map(int, input().split()))
ab = []
for i in range(M):
    ab.append(list(map(int, input().split())))
ans = 0
if M >= N - 1:
    for i in list(itertools.combinations(ab, N - 1)):
        g = {}
        for j in range(N):
            g[j + 1] = []
        for j, k in i:
            g[j].append(k)
            g[k].append(j)
        if len(g[1]) == 1:
            p = 1
            q = g[p][0]
            for j in range(N - 2):
                l = g[q]
                if len(l) != 2:
                    break
                l.remove(p)
                p = q
                q = l[0]
            else:
                ans += 1
print(ans)

# Optimized solution
import itertools
N, M = list(map(int, input().split()))
e = set([])
for i in range(M):
    a, b = list(map(int, input().split()))
    e.add((a, b))
ans = 0
for i in list(itertools.permutations(list(range(2, N + 1)))):
    a = 1
    for b in i:
        if (a, b) in e or (b, a) in e:
            a = b
            continue
        break
    else:
        ans += 1
print(ans)
# Original solution
def na(): return list(map(int, input().split()))
n, m = na()
edges = [[False for _ in range(n)] for _ in range(n)]
for i in range(m):
    a, b = na()
    a -= 1
    b -= 1
    edges[a][b] = True
    edges[b][a] = True

pathes = {'0'}#permutationで求めたpath
for i in range(n-1):
    buf = set()
    for pre_path in pathes:
        for v in map(str, list(range(1, n))):
            if not(v in pre_path):
                buf.add(pre_path + v)
    pathes = buf.copy()
##print(pathes)
##print(edges)

ans = 0
for path in pathes:
    flg = True
    for i in range(1, n):
        a, b = list(map(int, [path[i-1], path[i]]))
##        print(a, b, edges[a][b])
        if not edges[a][b]:
            flg = False
            break
    if flg:
        ans += 1
print(ans)

# Optimized solution
def ary(r, c, v): return [[v for _ in range(c)] for _ in range(r)]
n, m = list(map(int, input().split()))
e = ary(n, n, False)
for i in range(m):
    a, b = list(map(int, input().split()))
    #頂点を0-indexedに変換
    a -= 1
    b -= 1
    e[a][b] = True
    e[b][a] = True
ps = set()
ps.add('0')

for cnt in range(1, n):
    t = set()
    for p in ps:
        for i in map(str, list(range(1, n))):
            if not(i in p):
                t.add(p + i)
    ps = t.copy()

ans = 0
for p in ps:
    flg = True
    for i in range(n - 1):
        a = int(p[i])
        b = int(p[i + 1])
        if not e[a][b]:
            flg = False
            break
    if flg:
        ans += 1

print(ans)
# Original solution
def ary(r, c, v): return [[v for _ in range(c)] for _ in range(r)]
n, m = list(map(int, input().split()))
e = ary(n, n, False)
for i in range(m):
    a, b = list(map(int, input().split()))
    #頂点を0-indexedに変換
    a -= 1
    b -= 1
    e[a][b] = True
    e[b][a] = True
ps = set()
ps.add('0')

for cnt in range(1, n):
    t = set()
    for p in ps:
        for i in map(str, list(range(1, n))):
            if not(i in p):
                t.add(p + i)
    ps = t.copy()

ans = 0
for p in ps:
    flg = True
    for i in range(n - 1):
        a = int(p[i])
        b = int(p[i + 1])
        if not e[a][b]:
            flg = False
            break
    if flg:
        ans += 1

print(ans)

# Optimized solution
def main():
    import sys

    sys.setrecursionlimit(10 ** 7)

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

    g = tuple(set() for _ in range(N))
    for _ in range(M):
        a, b = (int(x) - 1 for x in input().split())
        g[a].add(b)
        g[b].add(a)

    def dfs(v=0, visited=1 << 0):
        if visited == (1 << N) - 1:
            return 1

        ret = 0
        for u in g[v]:
            if (visited >> u) & 1:
                continue
            ret += dfs(u, visited | (1 << u))
        return ret

    ans = dfs()
    print(ans)


if __name__ == '__main__':
    main()

# import sys
#
# sys.setrecursionlimit(10 ** 7)
#
# input = sys.stdin.readline
# rstrip()
# int(input())
# map(int, input().split())
# Original solution
n,m=list(map(int,input().split()))
a=[]

for i in range(m):
    ai,bi=list(map(int,input().split()))
    a.append([ai,bi])
              
ni=[0]*n
nii=[]
    
def pathm(n,a,bi,pcnt,ni):
    if n==1:
        pcnt=pcnt+1
#        print("2:","n:",n,"bi:",bi,"pcnt:",pcnt)
        return pcnt
    else:
        n=n-1
        nii.append(bi)
        for mm in range(m):
            if a[mm][0]==bi and not a[mm][1] in nii:
#            if a[mm][0]==bi :
                ni[a[mm][1]-1]=1
#                print("1:","n:",n,"mm:",mm,"a[mm][1]:",a[mm][1],"pcnt:",pcnt)
                pcnt=pathm(n,a,a[mm][1],pcnt,ni)
            if a[mm][1]==bi and not a[mm][0] in nii:
#            if a[mm][1]==bi  and ni[a[mm][0]-1]==0 :
                ni[a[mm][0]-1]=1
#                ni[mm]=1
#                print("1:","n:",n,"mm:",mm,"a[mm][0]:",a[mm][0],"pcnt:",pcnt)
                pcnt=pathm(n,a,a[mm][0],pcnt,ni)
        nii.pop()
        return pcnt       
                
pcnt=0
pcnt1=pathm(n,a,1,pcnt,ni)
print(pcnt1)


# Optimized solution
q=[]
qq=[]
def dfs(j,q,icnt,count,n,qq):
    if len(qq)==n:
        count+=1
#        print("1",n,j,icnt,count,q[j],qq)
        return count
    icnt+=1
    
    for j2 in q[j]:
        if not j2 in qq:
            qq.append(j2)
#            print("2",n,j,icnt,count,q[j],qq)
            count=dfs(j2,q,icnt,count,n,qq)
            qq.pop()
#        print("3",n,j,icnt,count,q[j],qq)
    return count

n,m=list(map(int,input().split()))
ab=[[0]*2 for i in range(m)]
for i in range(m):
    ab[i]=list(map(int,input().split()))

#n=3
#m=3
#ab=[[1,2],[1,3],[2,3]]

#n=7
#m=7
#ab=[[1,3],[2,7],[3,4],[4,5],[4,6],[5,6],[6,7]]

q=[[]*2 for i in range(n)]
for i in range(m):
    if not q[ab[i][1]-1] in q[ab[i][0]-1]:
        q[ab[i][0]-1].append(ab[i][1]-1)    
    if not q[ab[i][0]-1] in q[ab[i][1]-1]:
        q[ab[i][1]-1].append(ab[i][0]-1)    
#print(q)    

count=0
j=0
qq=[j]
icnt=1
count=dfs(j,q,icnt,count,n,qq)
print(count)
# Original solution
import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
h = logging.FileHandler("logtest.log")
logger.addHandler(h)


N, M = list(map(int, input().split()))
open_list = [[] for _ in range(N)]
for _ in range(M):
    a, b = list(map(int, input().split()))
    a -= 1
    b -= 1
    open_list[a].append(b)
    open_list[b].append(a)

logger.info("open_list: {}\n".format(open_list))

# 探索済みリスト
closed_list = [False] * N
closed_list[0] = True
cnt = 0
level = 1

# 深さ優先探索
def dfs(target):
    global cnt, level
    logger.info("***********open_list[target]: {}".format(open_list[target]))
    if all(closed_list):
        cnt += 1
        logger.info("[level: {}] closed_list: {}".format(level, closed_list))
        logger.info("cnt: {}".format(cnt))
        logger.info("*****************************************")
        return
    # open_listリストのnode
    for node in open_list[target]:
        logger.info("node: {}".format(node))
        logger.info("[level: {}] closed_list: {}".format(level, closed_list))
        # 探索済みでない場合
        if closed_list[node] is False:
            # 探索開始
            closed_list[node] = True
            # 再帰
            level += 1
            dfs(node)
            level = 1
            # levalを戻す
            closed_list[node] = False
            logger.info("[level: {}] closed_list: {}".format(level, closed_list))
    return


dfs(0)
print(cnt)


# Optimized solution
N, M = list(map(int, input().split()))
open_list = [[] for _ in range(N)]
for _ in range(M):
    a, b = list(map(int, input().split()))
    a -= 1
    b -= 1
    open_list[a].append(b)
    open_list[b].append(a)

# 探索済みリスト
closed_list = [False] * N
closed_list[0] = True
cnt = 0
level = 1

# 深さ優先探索
def dfs(target):
    global cnt, level
    if all(closed_list):
        cnt += 1
        return
    # open_listリストのnode
    for node in open_list[target]:
        # 探索済みでない場合
        if closed_list[node] is False:
            # 探索開始
            closed_list[node] = True
            # 再帰
            level += 1
            dfs(node)
            level = 1
            # levalを戻す
            closed_list[node] = False
    return


dfs(0)
print(cnt)
# Original solution
# -*- coding: utf-8 -*-

# DFSでやる版

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

# 入力値の頂点ペア(辺)を格納する配列
a = [0] * M
b = [0] * M

# 頂点ペアが隣接しているかどうかを格納する配列
graph = [[False for i in range(N)] for j in range(N)]

# 入力値の頂点ペア(辺)を格納していくループ
for i in range(M):
    a[i], b[i] = list(map(int, input().split()))
    # 添字に合わせて入力値から1減らしておく
    a[i] -= 1
    b[i] -= 1
    # 入力値の内容に合わせて、隣接していることを記録
    graph[a[i]][b[i]] = True
    graph[b[i]][a[i]] = True

cnt = 0
p = [0] * N
def dfs(pos, mask):
    # 関数内で更新して外部で参照する変数のglobal宣言
    global cnt
    # 最後まで到達できた時はここを通る
    if pos == N:
        # 前提としてスタート地点(添字0)が0かどうか確認
        if p[0] == 0:
            for i in range(N-1):
                # 各辺が存在(各頂点ペアが隣接)しているか確認していく
                if graph[p[i]][p[i+1]] == False:
                    break
                # 全て存在すれば条件を満たすのでカウント+1
                if i == N-2:
                    cnt += 1
        return
    for i in range(N):
        # 残っている数の中にiがまだ残っている場合
        # (maskの中に(1<<i)のビットがまだ残っていればTrueを返す)
        if mask & (1<<i):
            p[pos] = i
            # 残っている数からiを取り除く
            # (排他的論理和XORで重複部分が0になる)
            dfs(pos+1, mask^(1<<i))
# 0からN-1までの数の集合
dfs(0, (1<<N)-1)
print(cnt)

# 参考：2進数の1を左へ3ビット移動(1→8)
# (1 << 3)

# Optimized solution
# -*- coding: utf-8 -*-

import sys
from itertools import permutations

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 18
MOD = 10 ** 9 + 7

N, M = MAP()
edges = set()
for i in range(M):
    a, b = MAP()
    a -= 1; b -= 1
    edges.add((a, b))
    edges.add((b, a))

cnt = 0
for perm in permutations(list(range(N))):
    if perm[0] != 0:
        continue
    for i in range(N-1):
        a = perm[i]
        b = perm[i+1]
        if (a, b) not in edges:
            break
    else:
        cnt += 1
print(cnt)