n,m=map(int,input().split())
d=dict()
for i in range(1,8):
    d[i]=set()
for i in range(m):
    a,b=map(int,input().split())
    d[a].add(b)
    d[b].add(a)

mn=100

for i in range(1,7):
    for j in range(i+1,8):
        s=d[i]&d[j]
        if len(s)<mn:
            mn=len(s)

print(m-mn)

n, m = map(int, input().split())

g = [[]]*(n+1)

for i in range(m):
	a, b = map(int, input().split())
	g[a] = g[a][:] + [b]
	g[b] = g[b][:] + [a]

if n==7:
	M = 0
	for i in range(1, n+1):
		for j in range(1, n+1):
			if i == j:
				continue
			N = []
			for k in g[i]+g[j]:
				N.append(k)
			N = set(N)
			num_edges = m - len(g[i]) - len(g[j]) + len(N)
			M = max(M, num_edges)
	print(min(M, 21))
else:
	print(m)

n, m = map(int, input().split())
if n <= 6:
    print(m)
else:
    A = []
    for i in range(m):
        x, y = map(int, input().split())
        A.append((min(x, y), max(x, y)))
    Max = 0
    for i in range(1, 7):
        for j in range(i + 1, 8):
            # Consider i ~ j
            S = set()
            for pair in A:
                x, y = pair
                if x == j:
                    S.add((i, y))
                elif y == j:
                    S.add((min(x, i), max(x, i)))
                else:
                    S.add(pair)
            if len(S) == 21:
                print(i, j, S)
            Max = max(Max, len(S))
    print(Max)

n,m=map(int,input().split())
d=dict()
for i in range(1,8):
    d[i]=set()
for i in range(m):
    a,b=map(int,input().split())
    d[a].add(b)
    d[b].add(a)

mn=100
if n<7:
    print(m)
else:
    for i in range(1,7):
        for j in range(i+1,8):
            s=d[i]&d[j]
            if len(s)<mn:
                mn=len(s)

    print(m-mn)

n,m=map(int,input().split())
d=[]
if n<7:
    print(m)
    exit(0)
for i in range(8):
    d.append(set())
for i in range(m):
    a,b=map(int,input().split())
    d[a-1].add(b-1)
    d[b-1].add(a-1)

minn=100
for i in range(0,7):
    for j in range(0,7):
        ss=d[i]&d[j]
        if len(ss)<minn:
            minn=len(ss)
print(m-minn)

import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline

N, M = map(int, input().split())
Edges = [list(map(lambda x:int(x)-1, input().split())) for _ in range(M)]
adj = [set() for _ in range(7)]
for a, b in Edges:
    adj[a].add(b)
    adj[b].add(a)
if N <= 6:
    ans = M
else:
    cnt = 100
    for i in range(7):
        for j in range(i+1, 7):
            cnt = min(cnt, len(adj[i] & adj[j]))
    ans = M-cnt
print(ans)

n, m = map(int, input().split())
d = [[] for _ in range(n+1)]
for _ in range(m):
    x, y = map(int, input().split())
    d[x].append(y)
    d[y].append(x)
if n < 7:
    print(m)
else:
    max1 = -1
    for q in range(1, n):
        for q1 in range(q+1, n+1):
            minus = 0
            for q2 in range(1, n+1):
                if q2 in d[q] and q2 in d[q1]:
                    minus += 1
            max1 = max(max1, m-minus)
    print(max1)

n, m = map(int, input().split())
u = []
for i in range(n):
    u.append([])
for i in range(m):
    a, b = map(int, input().split())
    u[a - 1].append(b - 1)
    u[b - 1].append(a - 1)
if n < 7 or m == 0:
    print(m)
    exit()
ans = 10
for i in range(n):
    for j in range(n):
        ansi = 0
        for k in range(n):
            if i in u[k] and j in u[k]:
                ansi += 1
        ans = min(ans, ansi)
        #print(ansi)
print(m - max(ans, 0))

n,k=[int(x) for x in input().split()]
dic={}
for i in range(1,7):
    dic[i]=[]
counter=0
opp=0
for i in range(k):
    a,b=[int(x) for x in input().split()]
    for i,j in (a,b),(b,a):
        if i not in dic:
            dic[i]=[j]
        else:
            dic[i].append(j)
arr=7
if n==7:
    for item in dic:
        for elem in dic:
            counter=len(dic[item])
            for i in dic[item]:
                if i not in dic[elem]:
                    counter-=1
            arr=min(arr,counter)
    print(max(k-arr,0))
else:
    print(k)

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

def ps(st, c, ans):
    if len(st) == 0:
        ans.append(tuple(c))
    nxt = set(st)
    for ci in st:
        c.append(ci)
        nxt.remove(ci)
        ps(nxt, c, ans)
        c.pop()
        nxt.add(ci)

st = set(range(6))
c = []
mine = []
ps(st, c, mine)
# x=(1,2,0,3,4,5)
# print(x in mine)
# mine=[[1,2,0,3,4,5]]

n, k = gns()
st = set()
for i in range(k):
    a, b = gns()
    a -= 1
    b -= 1
    a, b = min(a, b), max(a, b)
    st.add((a, b))
ans = 0
for mi in mine:
    for i in range(7):
        # if m==(1,2,0,3,4,5)and i==2:
        #     xxxxxx=0
        m = mi[:i] + (0,) + mi[i:]

        nd = set()
        for i in range(7):
            for j in range(i, 7):
                ij = (i, j)
                if ij in st:
                    di, dj = m[i], m[j]
                    di, dj = min(di, dj), max(di, dj)
                    nd.add((di, dj))
        # x = nd.intersection(st)
        l = len(nd)
        # if x!=16:
        #     xxxxx=0
        ans = max(l, ans)

print(ans)

a = list(map(int, input().split()))
n = a[0]
m = a[1]
graph = {}
for i in range(n):
    graph[i + 1] = []
for i in range(m):
    a = list(map(int, input().split()))
    graph[a[0]].append(a[1])

if n < 7:
    print(m)
else:
    res = 0

    DOMINOES = set()
    for i in range(1, 7):
        for j in range(i, 7):
            DOMINOES.add((i, j))

    max_dominoes = 0
    for i in range(7):
        for j in range(i + 1, 8):
            nums = [1, 1, 1, 1, 1, 1, 1]
            c = 2
            for k in range(len(nums)):
                if k != j and k != i:
                    nums[k] = c
                    c += 1
            not_used_dominoes = set(DOMINOES)
            count = 0
            ignored = 0
            for v in graph:
                for child in graph[v]:
                    domino = (min(nums[v - 1], nums[child - 1]), max(nums[v - 1], nums[child - 1]))
                    if domino in not_used_dominoes:
                        count += 1
                        not_used_dominoes.remove(domino)

            max_dominoes = max(max_dominoes, count)
            if max_dominoes >= m:
                break

    print(max_dominoes)

n, m = map(int, input().split())

if n < 7:
    print(m)
else:
    g = []
    for i in range(7):
        g.append(set())

    for _ in range(m):
        x, y = map(int, input().split())
        g[x-1].add(y)
        g[y-1].add(x)

    mn = 1000
    for i in range(7):
        for j in range(i+1,7):

            s = g[i] & g[j]

            if len(s) < mn:
                mn = len(s)

    print(m - mn)

a = list(map(int, input().split()))
n = a[0]
m = a[1]
graph = {}
for i in range(n):
    graph[i + 1] = []
for i in range(m):
    a = list(map(int, input().split()))
    graph[a[0]].append(a[1])

if n < 7:
    print(m)
else:
    vertices = []
    for k in graph.keys():
        vertices.append((k, len(graph[k])))
    sorted_vertices = sorted(vertices, key=lambda x: x[1])
    minimum_dominoes = 0
    for i in range(1, len(sorted_vertices)):
        if sorted_vertices[0][0] in graph[sorted_vertices[i][0]]:
            minimum_dominoes += sorted_vertices[i][1] - 1
        else:
            minimum_dominoes += sorted_vertices[i][1] - 1

    res = 0
    nums = [1, 1, 1, 1, 1, 1, 1]

    DOMINOES = set()
    for i in range(1, 7):
        for j in range(i, 7):
            DOMINOES.add((i, j))

    max_dominoes = 0
    while True:
        not_used_dominoes = set(DOMINOES)
        count = 0
        ignored = 0
        for v in graph:
            for child in graph[v]:
                domino = (min(nums[v - 1], nums[child - 1]), max(nums[v - 1], nums[child - 1]))
                if domino in not_used_dominoes:
                    count += 1
                    not_used_dominoes.remove(domino)
                else:
                    ignored += 1
                    if ignored > m - minimum_dominoes:
                        break
        max_dominoes = max(max_dominoes, count)
        if max_dominoes >= m:
            break
        j = len(nums) - 1
        while nums[j] == 6:
            nums[j] = 1
            j -= 1
        if j < 1:
            break
        nums[j] = nums[j] + 1

    print(max_dominoes)

import sys

lines = []
for Line in sys.stdin:
  lines.append(Line.rstrip('\n'))

# lines=["7 11",
# "4 7",
# "6 4",
# "5 1",
# "1 4",
# "5 4",
# "1 2",
# "3 4",
# "4 2",
# "6 1",
# "3 1",
# "7 1"]

n,m = list(map(int,lines[0].split()))
del(lines[0])

#G=[[] for _ in range(n)]
G=[[0 for i in range(n)] for j in range(n)]
for i in range(m):
   a,b=list(map(int,lines[i].split()))
   a = a-1
   b = b-1
   G[a][b]=1
   G[b][a]=1

if (n<=6):
	print(m)
	exit(0)
else:
    ctr = 2e9;
    for i in range(n):
        for k in range(n):
            temp = 0
            for j in range(n):
                if(G[i][j]==1 and G[k][j]==1):
                	temp+=1
            ctr = min(ctr, temp)
    print(m-ctr)

n,m = map(int,input().split())
l =[[] for _ in range(n)]
for i in range(m):
	k,p = map(int,input().split())
	l[k-1].append(p)
	l[p-1].append(k)
if n<7 or m==0:
	print(m)
else:
	k = [len(l[i]) for i in range(n)]
	mi=9999
	for i in range(n):
	    for j in range(i+1,n):
	        x = len(set(l[i]).union(set(l[j])))# if (i+1) in l[j] else len(set(l[i]).union(set(l[j])))
	        x = k[i]+k[j]-x
	        if mi>x:
	            mi = x
	print(m - mi)

from itertools import *
n,m=map(int,input().split())
e = [tuple(int(s)-1 for s in input().split()) for _ in range(m)]
print(max(len(set(tuple(sorted([p[a],p[b]])) for a,b in e)) for p in permutations(i%6 for i in range(n))))

n,m = [int(x) for x in input().split()]

p = []
for x in range(m):
    t = sorted([int(x) for x in input().split()])
    p.append((t[0],t[1]))

if (n < 7):
    print(m)
    exit(0)

res = 0

for i in range(1,8):
    for j in range(1,8):
        if i == j: continue
        p1 = []
        for u,v in p:
            t = [u,v]
            if u == i:
                t = sorted([j,v])
            elif v == i:
                t = sorted([j,u])
            p1.append((t[0],t[1]))
        res = max(res , len(set(p1)))

print(res)

def dominoes(n,m,edges):
    if n<=6:
        return m
    if m==0:
        return 0
    mscore=7
    for a in range(1,7):
        for b in range(a):
            score=codeg(a,b,edges)
            if score<mscore:
                mscore=score
    return m-mscore

def codeg(a,b,edges):
    c=0
    for x in range(7):
        if x==a:
            continue
        if x==b:
            continue
        if ([a,x] in edges) or ([x,a] in edges):
            if ([b,x] in edges) or ([x,b] in edges):
                c+=1
    return c

n,m=map(int,input().split())
ed=[]
for x in range(m):
    a,b=map(int,input().split())
    a-=1
    b-=1
    ed.append([a,b])

print(dominoes(n,m,ed))

n=list(map(int,input().split()))
e=n[1]
n=n[0]
d={}
for itr in range(1,n+1):
    d[itr]=[]
for i in range(e):
    a=list(map(int,input().split()))
    d[a[0]].append(a[1])
    d[a[1]].append(a[0])
if n<=6:
    print(e)
else:
    asdf=[]
    for ii in range(1,8):
        ans=e-len(d[ii])
        if ii!=7:
            d[ii],d[7]=d[7],d[ii]
            for i in d:
                for j in range(len(d[i])):
                    if d[i][j]==ii: d[i][j]=7
                    elif d[i][j]==7: d[i][j]=ii
        domino=[(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(2,2),(2,3),(2,4),(2,5),(2,6),(3,3),(3,4),(3,5),(3,6),(4,4),(4,5),(4,6),(5,5),(5,6),(6,6)]
        for i in range(1,7):
            for j in d[i]:
                if j==7 or j<i: continue
                else: domino.remove((i,j))
        #print(domino)
        for i in domino:
            if (i[0] in d[7]) or (i[1] in d[7]): continue
            else: domino.remove(i)
        dd={}
        possible=0
        for i in range(1,7):
            count=0
            for itr in domino:
                if itr[0]==i:
                    if itr[1] in d[7]: count+=1
                elif itr[1]==i:
                    if itr[0] in d[7]: count+=1
            possible=max(count,possible)
        asdf.append(ans+possible)
    print(max(asdf))

n, m = input().split()
n, m = int(n), int(m)
edges = [[] for x in range(n)]
for i in range(m):
    a, b = input().split()
    a, b = int(a), int(b)
    ma = max(a, b)
    mi = min(a, b)
    edges[mi-1].append((ma-1))
    edges[ma-1].append((mi-1))
# print(edges)
# find lowest degree:

xxx=[]
if n<=6:
    print(m)
else:
    for i in range(n):
        for j in range(i):
            xxx.append(set(edges[i]).intersection(set(edges[j])))
# print(xxx)
    p = [len(z) for z in xxx]
    print(m-min(p))

n , m = map(int,input().split())
lis=[]
for i in range(7):
    lis.append(set())
for i in range(m):
    a , b = map(int,input().split())
    lis[a-1].add(b)
    lis[b-1].add(a)
if n<=6:
    print(m)
else:
    ma=1000000
    for i in range(7):
        for j in range(i+1,7):
            s=lis[i] & lis[j]
            if len(s)<ma:
                ma =len(s)
    print(m-ma)

n,m=map(int,input().split())
d=[[] for i in range(n+1)]
for x in range(m):
    a,b=map(int,input().split())
    d[a].append(b)
    d[b].append(a)
if n<7:
    print(m)
else:
    ans=-1
    for i in range(1,n):
        for j in range(i+1,n+1):
            sub=0
            for k in range(1,n+1):
                if k in d[i] and k in d[j]:
                    sub+=1
            ans=max(ans,m-sub)
    print(ans)

from collections import defaultdict
number, mumber = map(int, input().split())
graphical = defaultdict(set)
for _ in range(mumber):
    a, b = map(int, input().split())
    graphical[a].add(b)
    graphical[b].add(a)

answer = 100
for i in range(1, 7):
    for j in range(i + 1, 8):
        g = graphical[i] & graphical[j]
        answer = min(answer, len(g))
print(mumber - answer)

#encoding:utf-8
import math
class Rookie(object):

    def _input(self):
        l1 = raw_input()
        l1 = l1.split()
        n, m = int(l1[0]), int(l1[1])
        edge = []
        for _ in range(m):
            l2 = raw_input()
            l2 = l2.split()
            a,b = int(l2[0]), int(l2[1])
            edge.append([a,b])
        return n, m, edge

    def gen(self, status, numb, n, k):
        '''
        n ge shu
        '''
        if k == n + 1:
            self.status.append(status[:])
            return
        # None
        for idx, b in enumerate(numb):
            if b == 0:
                continue
            status[k] = idx + 1
            numb[idx] -= 1
            self.gen(status, numb, n, k+1)
            numb[idx] += 1
        self.gen(status, numb, n, k + 1)

    def _output(self):
        pass

    def solve(self):
        n,m,edge = self._input()
        self.status = []
        self.gen([-1]*(n+1), [1]*min(n,6), n, 1)
        dom = [[0]*7 for _ in range(7)]
        for a in range(1,7):
            for b in range(a,7):
                dom[a][b] = 1
        ret = 0
        #print (len(self.status))
        for status in self.status:
            tmp_ret = 0
            flag = 1
            use_d = []
            #print (status)
            #status = [-1, 1,2,3,4,5,6,-1]
            for idx, E in enumerate(edge):
                v1, v2 = E[0], E[1]
                s1 = status[v1]
                s2 = status[v2]
                if s1 == -1 or s2 == -1:
                    continue
                #print (v1, v2, s1, s2, dom[s1][s2])
                if s1 > s2:
                    s1,s2 = s2,s1
                if dom[s1][s2] == 0:
                    #flag = 0
                    #break
                    continue
                dom[s1][s2] = 0
                use_d.append((s1,s2))
                tmp_ret += 1
                if m - idx - 1 + tmp_ret < ret:
                    break
            #print (flag)
            #break
            #print (flag)
            if flag:
                ret = max(ret, tmp_ret)
            for a,b in use_d:
                dom[a][b] = 1
            if ret == m:
                break
            #break
        print ret

if __name__ == '__main__':
    #print Rookie().pow(3,1)
    #print Rookie().cal(3,1)
    Rookie().solve()

#!/usr/bin/env python3

secondApproach = True

def calculatePossibleIncrease(setMain: set, setLeft: set, setMainIndex: int):
    directDelta = len(setMain.union(setLeft).difference(
        setMain.union({setMainIndex})))

    indirectDelta = len(setLeft.intersection({setMainIndex}))  # x <-> x

    return directDelta + indirectDelta

def calculateMaxPossibleEdges(verts, leftOutVertIndex):
    tempSetEdgesCount = len(verts[leftOutVertIndex])

    retVal = -1
    for i in range(len(verts)):
        if len(verts[i]) == tempSetEdgesCount or secondApproach:
            retVal = max(
                retVal,
                calculatePossibleIncrease(
                    verts[i], verts[leftOutVertIndex], i)
            )

    return retVal

def calculateDirectAnswer(verts, leftOutVertIndex):
    doubleEdgeCount = 0
    for i in range(len(verts)):
        if i != leftOutVertIndex:
            doubleEdgeCount += len(verts[i].difference({leftOutVertIndex}))
    return doubleEdgeCount // 2

def main():
    vertsCount, edgesCount = tuple(map(int, input('').split(' ')))

    if(vertsCount < 7):
        print(edgesCount)
        exit(0)

    verts = []
    for i in range(vertsCount):
        verts.append(set())

    for _t in range(edgesCount):
        _x, _y = tuple(
            map(lambda x: int(x) - 1, input('').split(' '))
        )

        verts[_x].add(_y)
        verts[_y].add(_x)

    edgesCount = [len(y) for y in verts]
    minEdgesCount = min(edgesCount)

    directAnswer = -1
    indirectAnswer = -1
    answer = -1
    for i in range(vertsCount):
        if len(verts[i]) == minEdgesCount or secondApproach:
            directAnswer = calculateDirectAnswer(verts, i)
            indirectAnswer = calculateMaxPossibleEdges(verts, i)

            answer = max(answer, directAnswer + indirectAnswer)

    return answer

if __name__ == '__main__':
    print(main())

'''
dominos = []
for i in range(1,7):
	for j in range(i, 7):
			dominos.append((i,j))

dominos_start_from = {}

for val in dominos:
		a, b = val
		try:
			dominos_start_from[a].append((a,b))
		except KeyError:
			dominos_start_from[a] = [(a,b)]

		try:
			dominos_start_from[b].append((b,a))
		except KeyError:
			dominos_start_from[b] = [(b,a)]
'''
nm = raw_input();
edges = []
n, m = nm.strip().split();
m = int(m)
n = int(n)
graph = {}

for i in range(m):
		uv = raw_input()
		u, v = uv.strip().split()
		u = int(u)
		v = int(v)
		edges.append((u,v))

		try:
			graph[u].append(v)
			graph[v].append(u)
		except KeyError:
			graph[u] = [v]
			graph[v] = [u]

ans = [0]
vertex = {}
nodes = graph.keys()
n_nodes = len(nodes)

degree = {}

for node in nodes:
	degree[node] = len(graph[node])

def compute():
	val = 0;
	pairs = {}
	for val in edges:
		a,b = val
		a = vertex[a]
		b = vertex[b]
		if a and b:
				a,b = min(a,b), max(a,b)
				pairs[(a,b)] = True
	ans[0] = max(ans[0], len(pairs.keys()))

freq = {}
def dfs1(idx):
	if idx >= n_nodes:
		compute()
		return
	node = nodes[idx]
	for val in range(1,7):
		fv = freq.get(val,0)
		if fv < 6:
			vertex[node] = val
			freq[val] = fv + degree.get(node, 0)
			dfs1(idx+1)
			vertex[node] = 0
			freq[val] = fv

dfs1(0);
print ans[0];

n, m = [int(x) for x in input().split()]

if n <= 6:
    for i in range(m):
        input()
    print(m)
    exit()

graph = [set() for _ in range(7)]

for i in range(m):
    edge = [int(x) - 1 for x in input().split()]
    u = edge[0]
    v = edge[1]
    graph[u].add(v)
    graph[v].add(u)

answer = 0

for i, u in enumerate(graph):
    for j, v in enumerate(graph):
        if i == j:
            continue
        intersectionLength = len(u.intersection(v))
        answer = max(answer, m - intersectionLength)

print(answer)

n,m=map(int,input().split())
if n<7:
    print(m)
    exit()
else:
    graph=[[0]*7 for i in range(n)]
    for i in range(m):
        s1,s2=map(int,input().split())
        graph[s1-1][s2-1]=1
        graph[s2-1][s1-1]=1
    ans=0
    for i in range(n):
        used=[0]*n
        for j in range(n):
            if graph[i][j]==1:
                for i1 in range(n):
                    if i1!=i and graph[j][i1]!=1:
                        used[i1]+=1
        ans=max(max(used)+m-sum(graph[i]),ans)
print(ans)

n, m = list(map(int, input().split()))

a=[]
b=[]

for _ in range(m):
  aa, bb = list(map(int, input().split()))
  if (bb < aa):
    aa,bb = bb,aa
  a.append(aa)
  b.append(bb)

if (n <= 6):
  print(m)
else:

  maxv = 0
  for i in range(1, n + 1):
    for j in range(i + 1, n + 1):
      alle = m
      minuse = 0
      tk = []
      for k in range(len(a)):
        if (i == a[k] and j != b[k]):
          alle -= 1
          tk.append(b[k])
        elif (i != a[k] and j == b[k]):
          alle -= 1
          tk.append(a[k])
        elif (i == b[k] and j != a[k]):
          alle -= 1
          tk.append(a[k])
        elif (i != b[k] and j == a[k]):
          alle -= 1
          tk.append(b[k])
      #print(alle)
      #print('set' + str(len(set(tk))))
      #exit(0)
      alle += len(set(tk))
      maxv = max(alle, maxv)
  print(maxv)

n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    graph[u].append(v)
    graph[v].append(u)
maxcnt = 0
for node1 in range(n):
    for node2 in range(node1 + 1, n):
        used = [[False] * n for _ in range(n)]
        col = list(range(0, node2)) + [node1] + list(range(node2 + 1, n))
        cnt = 0
        for u in range(n):
            for v in graph[u]:
                if not used[col[u]][col[v]]:
                    used[col[u]][col[v]] = used[col[v]][col[u]] = True
                    cnt += 1
        maxcnt = max(cnt, maxcnt)
print(maxcnt if n > 6 else m)

n, m = map(int, input().split())
s = [[0 for i in range(n)] for i2 in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    s[a - 1][b - 1] = 1
    s[b - 1][a - 1] = 1
if n == 7:
    mass = []
    for i in range(n):
        for i2 in range(n):
            k = 0
            for i3 in range(n):
                if s[i][i3] == 1 and s[i2][i3] == 1:
                    k += 1
            mass += [k]
    m -= min(mass)
print(m)

import itertools
n,m = list(map(int,input().split()))
arr = []
for i in range(n):
    arr.append([])
for i in range(m):
    a,b = list(map(int,input().split()))
    a-=1
    b-=1
    arr[a].append(b)
    arr[b].append(a)
permuts = list(itertools.permutations(list(range(7))))
ans = 0
for i in range(len(permuts)):
    permut = permuts[i]
    was = []
    for i in range(6):
        was.append([False]*6)
    c = 0
    for i in range(n):
        if permut[i] != 6:
            for g in range(len(arr[i])):
                if not permut[arr[i][g]] == 6:
                    if not was[permut[i]][permut[arr[i][g]]]:
                        c+=1
                        was[permut[i]][permut[arr[i][g]]] = True
                        was[permut[arr[i][g]]][permut[i]] = True
    for w in range(n):
        if permut[w] == 6:
            ams = [0]*6
            for g in range(len(arr[w])):
                for j in range(6):
                    if not was[permut[arr[w][g]]][j]:
                        ams[j]+=1
            c+=max(ams)
            break

    ans = max(ans,c)
print(ans)

n,m = [int(j) for j in input().split()]
adj = [set() for i in range(n)]
for i in range(m):
	l, r = [int(j)-1 for j in input().split()]
	adj[l].add(r)
	adj[r].add(l)
if n<7:
	print(m)
else:
	deg = 1e12
	for i in range(n):
		for j in range(i+1, n):
			l = adj[i].intersection(adj[j])
			# print(l)
			tmp = len(l)
			if tmp<deg:
				deg = tmp
		# deg = min(len(adj[i]), deg)
	# deg = ma
	# print(deg)
	print(m-deg)

n,m = [int(j) for j in input().split()]
adj = [set() for i in range(n)]
for i in range(m):
	l, r = [int(j)-1 for j in input().split()]
	adj[l].add(r)
	adj[r].add(l)
if n<7:
	print(m)
else:
	deg = 10**12
	for i in range(n):
		for j in range(i+1, n):
			l = adj[i].intersection(adj[j])
			tmp = len(l)
			if tmp<deg:
				deg = tmp
	print(m-deg)

n,m = [int(j) for j in input().split()]
adj = [set() for i in range(n)]
for i in range(m):
	l, r = [int(j)-1 for j in input().split()]
	adj[l].add(r)
	adj[r].add(l)
if n<7:
	print(m)
else:
	maxi = 10**12
	for i in range(n):
		for j in range(i+1, n):
			l = adj[i].intersection(adj[j])
			tmp = len(l)
			if tmp<maxi:
				maxi = tmp
	print(m-maxi)

n,m = map(int,raw_input().split(" "))
edges = []
colors = [0]*n
for i in range(m):
	a,b = map(int,raw_input().split(" "))
	edges.append((a-1,b-1))

if n <= 6:
	print m
else:
	ret = []
	for i in range(n):
		for j in range(i):
			colors = [0]*n
			visited = [0]*100
			cnt = 2
			ans = 0
			colors[i] = 1
			colors[j] = 1
			for k in range(n):
				if colors[k] == 0:
					colors[k]= cnt
					cnt += 1
			for a,b in edges:
				x = colors[a]
				y = colors[b]
				x,y=min(x,y),max(x,y)
				if not visited[x*10+y]:
					visited[x*10+y] = 1
					ans += 1
			ret.append(ans)
	print max(ret)

from collections import Counter,defaultdict
from sys import stdin
raw_input = stdin.readline
n,m=map(int,raw_input().split())
if n<=6:
    for i in xrange(m):
        raw_input()
    print m
else:
    edge=[]
    ans=0
    for i in xrange(m):
        edge.append(((map(int,raw_input().split()))))
    for a in xrange(1,7):
        for b in xrange(1,7):
            for c in xrange(1,7):
                for d in xrange(1,7):
                    for e in xrange(1,7):
                        for f in xrange(1,7):
                            for g in xrange(1,7):
                                x=defaultdict(Counter)
                                l=[0,a,b,c,d,e,f,g]
                                c1=0
                                for u,v in edge:
                                    if not x[max(l[u],l[v])][min(l[v],l[u])]:
                                        x[max(l[u],l[v])][min(l[v],l[u])]=1
                                        c1+=1
                                ans=max(ans,c1)
    print ans

# ---------------------------iye ha aam zindegi---------------------------------------------
import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction
import sys
mod = 10 ** 9 + 7
mod1 = 998244353

# ------------------------------warmup----------------------------
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# -------------------game starts now----------------------------------------------------import math
class TreeNode:
    def __init__(self, k, v):
        self.key = k
        self.value = v
        self.left = None
        self.right = None
        self.parent = None
        self.height = 1
        self.num_left = 1
        self.num_total = 1

class AvlTree:

    def __init__(self):
        self._tree = None

    def add(self, k, v):
        if not self._tree:
            self._tree = TreeNode(k, v)
            return
        node = self._add(k, v)
        if node:
            self._rebalance(node)

    def _add(self, k, v):
        node = self._tree
        while node:
            if k < node.key:
                if node.left:
                    node = node.left
                else:
                    node.left = TreeNode(k, v)
                    node.left.parent = node
                    return node.left
            elif node.key < k:
                if node.right:
                    node = node.right
                else:
                    node.right = TreeNode(k, v)
                    node.right.parent = node
                    return node.right
            else:
                node.value = v
                return

    @staticmethod
    def get_height(x):
        return x.height if x else 0

    @staticmethod
    def get_num_total(x):
        return x.num_total if x else 0

    def _rebalance(self, node):

        n = node
        while n:
            lh = self.get_height(n.left)
            rh = self.get_height(n.right)
            n.height = max(lh, rh) + 1
            balance_factor = lh - rh
            n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
            n.num_left = 1 + self.get_num_total(n.left)

            if balance_factor > 1:
                if self.get_height(n.left.left) < self.get_height(n.left.right):
                    self._rotate_left(n.left)
                self._rotate_right(n)
            elif balance_factor < -1:
                if self.get_height(n.right.right) < self.get_height(n.right.left):
                    self._rotate_right(n.right)
                self._rotate_left(n)
            else:
                n = n.parent

    def _remove_one(self, node):
        """
        Side effect!!! Changes node. Node should have exactly one child
        """
        replacement = node.left or node.right
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = replacement
            else:
                node.parent.right = replacement
            replacement.parent = node.parent
            node.parent = None
        else:
            self._tree = replacement
            replacement.parent = None
        node.left = None
        node.right = None
        node.parent = None
        self._rebalance(replacement)

    def _remove_leaf(self, node):
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = None
            else:
                node.parent.right = None
            self._rebalance(node.parent)
        else:
            self._tree = None
        node.parent = None
        node.left = None
        node.right = None

    def remove(self, k):
        node = self._get_node(k)
        if not node:
            return
        if AvlTree._is_leaf(node):
            self._remove_leaf(node)
            return
        if node.left and node.right:
            nxt = AvlTree._get_next(node)
            node.key = nxt.key
            node.value = nxt.value
            if self._is_leaf(nxt):
                self._remove_leaf(nxt)
            else:
                self._remove_one(nxt)
            self._rebalance(node)
        else:
            self._remove_one(node)

    def get(self, k):
        node = self._get_node(k)
        return node.value if node else -1

    def _get_node(self, k):
        if not self._tree:
            return None
        node = self._tree
        while node:
            if k < node.key:
                node = node.left
            elif node.key < k:
                node = node.right
            else:
                return node
        return None

    def get_at(self, pos):
        x = pos + 1
        node = self._tree
        while node:
            if x < node.num_left:
                node = node.left
            elif node.num_left < x:
                x -= node.num_left
                node = node.right
            else:
                return (node.key, node.value)
        raise IndexError("Out of ranges")

    @staticmethod
    def _is_left(node):
        return node.parent.left and node.parent.left == node

    @staticmethod
    def _is_leaf(node):
        return node.left is None and node.right is None

    def _rotate_right(self, node):
        if not node.parent:
            self._tree = node.left
            node.left.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.left
            node.left.parent = node.parent
        else:
            node.parent.right = node.left
            node.left.parent = node.parent
        bk = node.left.right
        node.left.right = node
        node.parent = node.left
        node.left = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    def _rotate_left(self, node):
        if not node.parent:
            self._tree = node.right
            node.right.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.right
            node.right.parent = node.parent
        else:
            node.parent.right = node.right
            node.right.parent = node.parent
        bk = node.right.left
        node.right.left = node
        node.parent = node.right
        node.right = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    @staticmethod
    def _get_next(node):
        if not node.right:
            return node.parent
        n = node.right
        while n.left:
            n = n.left
        return n

# -----------------------------------------------binary seacrh tree---------------------------------------
class SegmentTree1:
    def __init__(self, data, default='z', func=lambda a, b: min(a, b)):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------game starts now----------------------------------------------------import math
class SegmentTree:
    def __init__(self, data, default=0, func=lambda a, b: a + b):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------------------iye ha chutiya zindegi-------------------------------------
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]

    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]

    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]

    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]

class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)

    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

# --------------------------------------iye ha combinations ka zindegi---------------------------------
def powm(a, n, m):
    if a == 1 or n == 0:
        return 1
    if n % 2 == 0:
        s = powm(a, n // 2, m)
        return s * s % m
    else:
        return a * powm(a, n - 1, m) % m

# --------------------------------------iye ha power ka zindegi---------------------------------
def sort_list(list1, list2):
    zipped_pairs = zip(list2, list1)

    z = [x for _, x in sorted(zipped_pairs)]

    return z

# --------------------------------------------------product----------------------------------------
def product(l):
    por = 1
    for i in range(len(l)):
        por *= l[i]
    return por

# --------------------------------------------------binary----------------------------------------
def binarySearchCount(arr, n, key):
    left = 0
    right = n - 1

    count = 0

    while (left <= right):
        mid = int((right + left) / 2)

        # Check if middle element is
        # less than or equal to key
        if (arr[mid] < key):
            count = mid + 1
            left = mid + 1

        # If key is smaller, ignore right half
        else:
            right = mid - 1

    return count

# --------------------------------------------------binary----------------------------------------
def countdig(n):
    c = 0
    while (n > 0):
        n //= 10
        c += 1
    return c
def binary(x, length):
    y = bin(x)[2:]
    return y if len(y) >= length else "0" * (length - len(y)) + y

def countGreater(arr, n, k):
    l = 0
    r = n - 1

    # Stores the index of the left most element
    # from the array which is greater than k
    leftGreater = n

    # Finds number of elements greater than k
    while (l <= r):
        m = int(l + (r - l) / 2)
        if (arr[m] >= k):
            leftGreater = m
            r = m - 1

        # If mid element is less than
        # or equal to k update l
        else:
            l = m + 1

    # Return the count of elements
    # greater than k
    return (n - leftGreater)

# --------------------------------------------------binary------------------------------------
n,k=map(int,input().split())
graph=defaultdict(list)
tot=[6,6,6,6,6,6,6]
e=[]
for i in range(k):
    a,b=map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)
    e.append((a,b))
if n<=6:
    print(k)
    sys.exit(0)
else:
    ans=k
    for i in range(7):
        tot=set()
        for ie in range(1,8):
            for j in range(ie,8):
                tot.add((ie,j))
        #print(tot)
        cur = len(graph[i + 1])
        for j in range(k):
            if e[j][0] == i + 1 or e[j][1] == i + 1:
                continue
            tot.remove((min(e[j][1],e[j][0]),max(e[j][0],e[j][1])))
        #print(tot)
        check=set()
        for j in range(k):
            if e[j][0] == i + 1:
                check.add(e[j][1])
            elif e[j][1] == i + 1:
                check.add(e[j][0])
        we=0
        for i1 in range(1,8):
            d=0
            if i1==i+1:
                continue
            for j1 in check:
                if (min(j1,i1),max(j1,i1)) in tot:
                    d+=1
            we=max(we,d)
        ans=min(ans,cur-we)
    print(min(k,k-ans))

from sys import stdin
from itertools import product
from copy import copy

rints = lambda: [int(x) for x in stdin.readline().split()]
rints_2d = lambda n: [tuple(sorted(rints())) for _ in range(n)]

n, m = rints()
edges, all, ans = rints_2d(m), set(), 0

for i in range(1, 7):
    for j in range(i, 7):
        all.add((i, j))

for mem in product([1, 2, 3, 4, 5, 6], repeat=7):
    dis, tem = copy(all), 0
    for u, v in edges:
        if (mem[u - 1], mem[v - 1]) in dis:
            dis.discard((mem[u - 1], mem[v - 1]))
            tem += 1

    ans = max(ans, tem)
print(ans)

n, m = map(int, input().split())

d = [0 for i in range(7)]
g = [[] for i in range(7)]

for i in range(m):
	x, y = map(int, input().split())
	x -= 1
	y -= 1
	d[x] += 1
	d[y] += 1

	g[x].append(y)
	g[y].append(x)

mn = min(d)
for i in range(7):
	for j in range(i):
		cnt = 0
		for k in range(7):
			if((k in g[i]) and (k in g[j])):
				cnt += 1
		mn = min(mn, cnt)
m -= mn
print(m)

import sys
import collections
import itertools

if sys.version_info[0] == 2:
	input = raw_input

def solve2(graph, edges, mapping):
	rmapping = {v: k for k, v in mapping.items()}
	doms = set()
	for i in range(1, 7):
		for j in range(i, 7):
			doms.add((i, j))

	answer = 0
	for (a, b) in edges:
		if mapping[a] <= 6 and mapping[b] <= 6:
			answer += 1
			dom = (mapping[a], mapping[b])
			if dom[0] > dom[1]:
				dom = (dom[1], dom[0])
			doms.remove(dom)

	D = [[0 for i in range(7)] for j in range(7)]
	for (a, b) in doms:
		D[a][b] = 1

	if 7 in rmapping:
		candidates = [mapping[v] for v in graph[rmapping[7]]]
		answer += max([sum([D[z][j] for z in candidates]) for j in range(1, 7)])

	return answer

def solve():
	n, m = map(int, input().split())
	graph = collections.defaultdict(set)
	counts = collections.defaultdict(int)
	edges = set()
	mapping = {}
	rmapping = {}

	for i in range(m):
		a, b = map(int, input().split())
		edges.add((a, b))
		graph[a].add(b)
		graph[b].add(a)

	if n <= 6:
		return m

	answer = 0
	for p in itertools.permutations(range(1, n + 1)):
		mapping = dict(zip(range(1, n + 1), p))
		answer = max(answer, solve2(graph, edges, mapping))
	return answer

print(solve())

from __future__ import print_function,division
n,m=map(int,raw_input().split())
if n<7:
    print(m)
else:
    l=[[] for k in range(n)]
    for i in range(m):
        a,b=map(int,raw_input().split())
        a-=1
        b-=1
        l[a].append(b)
        l[b].append(a)
    print(m-min([sum((i in l[a]) and (i in l[b]) for i in range(n)) for a in range(n-1) for b in range(a+1,n)]))

import sys
# sys.setrecursionlimit(10**6)
from sys import stdin, stdout
import bisect            #c++ upperbound
import math
import heapq
def modinv(n,p):
    return pow(n,p-2,p)
def cin():
    return map(int,sin().split())
def ain():                           #takes array as input
    return list(map(int,sin().split()))
def sin():
    return input()
def inin():
    return int(input())
import math
def Divisors(n) :
    l = []
    for i in range(1, int(math.sqrt(n) + 1)) :
        if (n % i == 0) :
            if (n // i == i) :
                l.append(i)
            else :
                l.append(i)
                l.append(n//i)
    return l

"""*******************************************************"""
def main():
    n,m=cin()
    if(n<7):
        print(m)
    else:
        a=[]
        for i in range(m):
            j,k=cin()
            a.append((j,k))
        b=[]
        ans=0
        for i in range(6):
            for j in range(6-i):
                b=[0]*7
                b[i]=1
                b[i+j+1]=1
                x=2
                for j in range(7):
                    if(b[j]==0):
                        b[j]=x
                        x+=1
                d={}
                # print(b)
                for j in range(m):
                    x=min(b[a[j][0]-1],b[a[j][1]-1])
                    y=max(b[a[j][0]-1],b[a[j][1]-1])
                    d[(x,y)]=1
                    # print(x,y,d)
                ans=max(ans,len(d))
        print(ans)
######## Python 2 and 3 footer by Pajenegod and c1729

# Note because cf runs old PyPy3 version which doesn't have the sped up
# unicode strings, PyPy3 strings will many times be slower than pypy2.
# There is a way to get around this by using binary strings in PyPy3
# but its syntax is different which makes it kind of a mess to use.

# So on cf, use PyPy2 for best string performance.

py2 = round(0.5)
if py2:
    from future_builtins import ascii, filter, hex, map, oct, zip
    range = xrange

import os, sys
from io import IOBase, BytesIO

BUFSIZE = 8192
class FastIO(BytesIO):
    newlines = 0

    def __init__(self, file):
        self._file = file
        self._fd = file.fileno()
        self.writable = "x" in file.mode or "w" in file.mode
        self.write = super(FastIO, self).write if self.writable else None

    def _fill(self):
        s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
        self.seek((self.tell(), self.seek(0,2), super(FastIO, self).write(s))[0])
        return s

    def read(self):
        while self._fill(): pass
        return super(FastIO,self).read()

    def readline(self):
        while self.newlines == 0:
            s = self._fill(); self.newlines = s.count(b"\n") + (not s)
        self.newlines -= 1
        return super(FastIO, self).readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.getvalue())
            self.truncate(0), self.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        if py2:
            self.write = self.buffer.write
            self.read = self.buffer.read
            self.readline = self.buffer.readline
        else:
            self.write = lambda s:self.buffer.write(s.encode('ascii'))
            self.read = lambda:self.buffer.read().decode('ascii')
            self.readline = lambda:self.buffer.readline().decode('ascii')

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip('\r\n')

# Cout implemented in Python
import sys
class ostream:
    def __lshift__(self,a):
        sys.stdout.write(str(a))
        return self
cout = ostream()
endl = '\n'

# Read all remaining integers in stdin, type is given by optional argument, this is fast
def readnumbers(zero = 0):
    conv = ord if py2 else lambda x:x
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

if __name__== "__main__":
  main()

'''input
7 21
1 2
1 3
1 4
1 5
1 6
1 7
2 3
2 4
2 5
2 6
2 7
3 4
3 5
3 6
3 7
4 5
4 6
4 7
5 6
5 7
6 7
'''

import sys
readln = sys.stdin.readline

def write(s):
    sys.stdout.write(str(s))

def writeln(s):
    sys.stdout.write(str(s))
    sys.stdout.write('\n')

def readint():
    return int(readln())

def readints():
    return map(int, readln().split())

def readstr():
    return readln()

def readstrs():
    return readln().split()

def solve(i, n, edges, flags):
    ans = 0
    if i == n + 1:
        dset = set()
        for (a,b) in edges:
            curd = (flags[a], flags[b])
            if curd in dset: continue
            dset.add(curd)
            dset.add((flags[b], flags[a]))
            ans += 1
        return ans

    else:
        for cflag in xrange(1, 7):
            flags[i] = cflag
            ans = max(ans, solve(i+1, n, edges, flags))
        return ans

n, m = readints()
edges = []
for e in xrange(m):
    edges.append(readints())
flags = [1] * (n+1)

writeln(solve(2, n, edges, flags))

n, m = map(int, raw_input().split())

edge = []
for x in xrange(m):
    edge.append(map(int, raw_input().split()))

val = [0] * (n + 1)

def dfs(x):
    res = 0
    if x == n:
        s = set()
        for a, b in edge:
            c, d = val[a], val[b]
            if c > d:
                c, d = d, c
            if (c, d) not in s:
                s.add((c, d))
                res += 1
    else:
        for i in xrange(6):
            val[x + 1] = i
            res = max(res, dfs(x + 1))
    return res

print(dfs(0))

import sys
import math
from functools import reduce
import bisect

def getN():
    return int(input())

def getNM():
    return map(int, input().split())

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

def input():
    return sys.stdin.readline().rstrip()

def index(a, x):
    i = bisect.bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    return False

#############
# MAIN CODE #
#############

n, m = getNM()
adj = [set() for _ in range(n)]

for _ in range(m):
    a, b = getNM()
    a -= 1
    b -= 1
    adj[a].add(b)
    adj[b].add(a)
if n < 7 or m == 0:
    print(m)
    exit()

ans = 0

for i in range(7):
    for j in range(i, 7):
        ans = max(ans, m - len(adj[i] & adj[j]))
print(ans)

import sys
import itertools
import math
import collections
from collections import Counter

#########################
# imgur.com/Pkt7iIf.png #
#########################

def getdict(n):
    d = {}
    if type(n) is list:
        for i in n:
            if i in d:
                d[i] += 1
            else:
                d[i] = 1
    else:
        for i in range(n):
            t = ii()
            if t in d:
                d[t] += 1
            else:
                d[t] = 1
    return d
def sieve(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    prime[0] = prime[1] = False
    r = [p for p in range(n + 1) if prime[p]]
    return r
def divs(n, start = 1):
    r = []
    for i in range(start, int(math.sqrt(n) + 1)):
        if (n % i == 0):
            if (n / i == i):
                r.append(i)
            else:
                r.extend([i, n // i])
    return r
def cdiv(n, k): return n // k + (n % k != 0)
def ii(): return int(input())
def mi(): return map(int, input().split())
def li(): return list(map(int, input().split()))
def lcm(a, b): return abs(a * b) // math.gcd(a, b)
def prr(a, sep = ' '): print(sep.join(map(str, a)))
def dd(): return collections.defaultdict(int)

n, m = mi()

if n < 7:
    exit(print(m))

edges = []
for i in range(m):
    edges.append(li())
perm = list(itertools.permutations([0, 1, 2, 3, 4, 5, 6]))
gmax = 0
for p in perm:
    g = [[] for i in range(n)]
    deg = [0]*n
    for i in edges:
        u, v = i[0], i[1]
        g[p[u - 1]].append(p[v - 1])
        g[p[v - 1]].append(p[u - 1])
        deg[p[v - 1]] += 1
        deg[p[u - 1]] += 1

    rm = 0
    for i in range(6):
        k = 0
        for j in g[6]:
            if i not in g[j]:
                k += 1
        rm = max(rm, k)

    #print((sum(deg[:6]) - deg[6])//2,  rm)
    gmax = max(gmax, (sum(deg[:6]) - deg[6])//2 + rm)
print(gmax)

def main():
    n, m = map(int, input().split())
    edges = []
    for _ in range(m):
        edge = [int(x) for x in input().split()]
        if edge[0] > edge[1]:
            edge.reverse()
        edges.append(edge)
    if n < 7:
        print(m)
        return
    # 7 verticies so two must have the same number
    ecount = [0] * 8
    for e1,e2 in edges:
        ecount[e1] +=1
        ecount[e2] +=1
    best = 0
    for i in range(1,8):
        for j in range(1,8):
            dom = m - ecount[i]
            if [min(i,j), max(i,j)] in edges:
                 dom += 1
            for k in range(1,8):
                if k !=i and k != j and [min(i,k), max(i,k)] in edges and [min(j,k), max(j,k)] not in edges:
                    dom += 1
            if dom > best:
                best = dom
    print(best)

if __name__ == "__main__":
    main()

n, m = [int(i) for i in input().split()]
data = []
for i in range(m):

    data.append([int(j) - 1 for j in input().split()])

ans = 0
for i in range(6 ** n):
    k = i
    num = [0] * n
    for j in range(n):
        dig = k % 6
        k //= 6
        num[j] =  dig

    st = set()
    for e in data:
        t = [num[e[0]],num[e[1]]]
        if t[0] > t[1]:
            t.reverse()
        st.add(tuple(t))
    ans = max(len(st), ans)

print(ans)

IN = input().split()
n = int(IN[0])
m = int(IN[1])
num = [0] * (n + 3)
ile = [0] * 10
E = [0] * (m + 3)
ans = 0

def spr () :
    res = 0
    for b in range (1, 7) :
        for a in range (1, 1 + b) :
            ile[a][b] = 1
    for i in range (0, m) :
        u = E[i][0]
        v = E[i][1]
        a = min(num[u], num[v])
        b = max(num[u], num[v])
        if ile[a][b] > 0 :
            ile[a][b] = 0
            res += 1
    return res

def rek (N) :
    if N > n :
        return spr()
    else :
        ret = 0
        for i in range (1, 7) :
            num[N] = i
            ret = max(ret, rek(N + 1))
    return ret

for i in range (0, 10) :
    ile[i] = [0] * 10
for i in range (0, m) :
    IN = input().split()
    E[i] = [int(IN[0]), int(IN[1])]
print(rek(1))

from collections import defaultdict
a,b=map(int,input().split())
if b<7:
    print(b)
else:
    d=defaultdict()
    for i in range(1,8):
        d[i]=set()
    for i in range(b):
        x,y=map(int,input().split())
        d[x].add(y)
        d[y].add(x)
    w=1000
    for i in range(1,8):
        for j in range(i+1,8):
            s=d[i]&d[j]
            if len(s)<w:
                w=len(s)
    print(b-w)

from collections import defaultdict
a,b=map(int,input().split())
d=defaultdict()
for i in range(1,8):
    d[i]=set()
for i in range(b):
    x,y=map(int,input().split())
    d[x].add(y)
    d[y].add(x)
w=1000
for i in range(1,8):
    for j in range(i+1,8):
        s=d[i]&d[j]
        if len(s)<w:
            w=len(s)
print(b-w)

n, m = map(int, input().split())
a = [0] * m
for i in range(m):
    b, c = map(int, input().split())
    a[i] = [b -1, c - 1]
col = [0] * 7
z = set()
ans = 0
for i1 in range(6):
    for i2 in range(6):
        for i3 in range(6):
            for i4 in range(6):
                for i5 in range(6):
                    for i6 in range(6):
                        for i7 in range(6):
                            col[0]= i1 + 1
                            col[1] = i2 + 1
                            col[2] = i3 + 1
                            col[3] = i4 + 1
                            col[4] = i5 + 1
                            col[5] = i6 + 1
                            col[6] = i7 + 1
                            for j in range(m):
                                z.add(max(col[a[j][0]], col[a[j][1]]) * 10 + min(col[a[j][0]], col[a[j][1]]))
                            #print(z)
                            #if len(z) > ans:
                                #print(col, z)
                            ans = max(ans, len(z))
                            z = set()
print(ans)

def getminpair(n):
	global graph
	s = [set(graph[i]) for i in range(8)]
	inter = 100000
	ans = (-1, -1)
	for i in range(1, n+1):
		for j in range(1, n+1):
			if(len(s[i].intersection(s[j])) < inter):
				inter = len(s[i].intersection(s[j]))
				ans = (i, j)
	return ans

n, m = map(int, input().split())
graph = [[], [], [], [], [], [], [], []]
for i in range(m):
	x, y = map(int, input().split())
	graph[x] += [y]
	graph[y] += [x]

if(n <= 6):
	print(m)
	exit()

pair = getminpair(n)
s0 = set(graph[pair[0]])
s1 = set(graph[pair[1]])
print(m - len(s1.intersection(s0)))

def getminpair(n):
	global graph
	s = [set(graph[i]) for i in range(8)]
	inter = 100000
	for i in range(1, n+1):
		for j in range(1, n+1):
			inter = min(inter, len(s[i].intersection(s[j])))
	return inter

n, m = map(int, input().split())
graph = [[], [], [], [], [], [], [], []]
for i in range(m):
	x, y = map(int, input().split())
	graph[x] += [y]
	graph[y] += [x]

if(n <= 6):
	print(m)
	exit()

print(m - getminpair(n))

n, m = map(int, input().split())
graph = [[], [], [], [], [], [], [], []]
for i in range(m):
	x, y = map(int, input().split())
	graph[x] += [y]
	graph[y] += [x]
s = [set(g) for g in graph]
if(n <= 6):
	print(m)
	exit()
ans = 100000
for i in range(1, n+1):
	for j in range(1, n+1):
		ans = min(ans, len(s[i].intersection(s[j])))
print(m - ans)

import itertools
n, m = map(int, input().split())
edge = [[0 for _ in range(n)] for _ in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    edge[a][b] = 1
    edge[b][a] = 1

ans = 0
d = [0] * n
for d in list(itertools.product(range(6), repeat=n)):
    count = set()
    for i, v1 in enumerate(d):
        for j, v2 in enumerate(d):
            if edge[i][j] == 1:
                count.add(str(v1) + str(v2))
    ans = max(len(count), ans)
print((ans+1)//2)

from collections import defaultdict
n, m = map(int, input().split())
graph = defaultdict(set)
for _ in range(m):
    a, b = map(int, input().split())
    graph[a].add(b)
    graph[b].add(a)

ans = 100
for i in range(1, 7):
    for j in range(i + 1, 8):
        g = graph[i] & graph[j]
        ans = min(ans, len(g))
print(m - ans)

n,m=map(int,input().split())
edges=[list(map(int,input().split())) for i in range(m)]
for i in range(m):
    edges[i][0]-=1
    edges[i][1]-=1
from itertools import permutations
l=list(permutations(range(6)))
mx=0
for ij in l:
    for node in range(7):
        for seven in range(6):
            cnt=[None]*10
            for xi in range(6):
                cnt[xi]=[0]*10
                for xj in range(xi,6):
                    cnt[xi][xj]=1
            numbering=[0]*10
            c=0
            for i in range(6):
                if node==i:
                    c=1
                numbering[i+c]=ij[i]
            numbering[node]=seven
            curr=0
            for e in edges:
                u,v=numbering[e[0]],numbering[e[1]]
                u,v=min(u,v),max(u,v)
                if cnt[u][v]:
                    cnt[u][v]=0
                    curr+=1
            mx=max(mx,curr)
print(mx)

n, m = map(int, input().split())
d = dict()
for i in range(1, 8):
    d[i] = set()
for i in range(m):
    a, b = map(int, input().split())
    d[a].add(b)
    d[b].add(a)
ans = 100
for i in range(1, 7):
    for j in range(i + 1, 8):
        g = d[i] & d[j]
        if len(g) < ans:
            ans = len(g)
print(m - ans)

n,m=map(int,input().split())
d=[[] for i in range(n+1)]
for x in range(m):
    a,b=map(int,input().split())
    d[a].append(b)
    d[b].append(a)
if n<7:
    print(m)
else:
    ans=-1
    for i in range(1,n):
        for j in range(i+1,n+1):
            sub=0
            for k in range(1,n+1):
                if k in d[i] and k in d[j]:
                    sub+=1
            ans=max(ans,m-sub)
    print(ans)

import sys
input = sys.stdin.readline

N, M = map(int, input().split())
Edges = [list(map(lambda x:int(x)-1, input().split())) for _ in range(M)]

def dfs(maxd, L, ans):
    if len(L) == N:
        dominos = [set() for _ in range(7)]
        score = 0
        for a, b in Edges:
            ca, cb = L[a], L[b]
            if ca in dominos[cb]:
                continue
            dominos[ca].add(cb)
            dominos[cb].add(ca)
            score += 1
        #print(L, score)
        return max(score, ans)
    for l in range(maxd+2):
        if l == 6: continue
        ans = dfs(max(maxd,l), L+[l], ans)
    return ans

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

n,k = map(int,input().split())
s = [[0 for i in range(8)] for j in range(8)]
for i in range(k):
	u,v = map(int,input().split())
	s[u][v] = 1
	s[v][u] = 1
if(n <= 6 or k == 0):
	print(k)
else:
	a = []
	for i in range(1,8):
		for j in range(1,8):
			if(i == j):
				continue
			ct = 0
			for k in range(1,8):
				if s[i][k] == 1 and s[j][k] == 1:
					ct += 1
			#print(j,i,ct)
			a.append([ct,i,j])
	a.sort()
	ind1 = a[0][1]
	ind2 = a[0][2]
	sum = sum1 = 0
	#print(a[0][0],ind1,ind2)
	#print(s[ind1],s[ind2])
	for i in range(1,8):
		if(s[ind1][i] == 1 and s[ind2][i] == 1):
			sum1 += 1
		elif(s[ind1][i] != s[ind2][i]):
			sum1 += 1

	if(s[ind1][ind2] == 1 and s[ind2][ind1] == 1):
		sum1 -= 1
	for i in range(1,8):
		#print(s[i])
		if i == ind1 or i == ind2:
			continue
		for j in range(1,8):
			if j == ind1 or j == ind2:
				continue
			sum += s[i][j]
		#print(sum)
	print(sum1+(sum//2))

from itertools import product

n,m = map(int,input().split())
node = [0, 1, 2, 3, 4, 5, 6]
node = node[:n]
g = []
for _ in range(m):
    a,b = map(int,input().split())
    g.append((a-1,b-1))

ans = 0
for pp in product(node, repeat=n):
    D = [[False] * 7 for _ in range(7)]
    for i in range(7):
        D[6][i] = D[i][6] = True
    cnt = 0
    cnt2 = 0
    h = -1
    if 6 in pp:
        h = pp.index(6)
    for a,b in g:
        if a == h or b == h:
            cnt2 += 1
        if not D[pp[a]][pp[b]]:
            D[pp[a]][pp[b]] = True
            D[pp[b]][pp[a]] = True
            cnt += 1
    if cnt2:
        cnt += 1
    ans = max(ans, cnt)

print(ans)

edges = []
n,m = map(lambda x:int(x), input().split())
for i in range(m):
    curr = [0,0]
    curr[0],curr[1] = map(lambda x:int(x)-1, input().split())
    edges.append(curr)

num_in = [1,1,1,1,1,1,1]
abs_max = 0
c=0
for num_in[1] in range(1, 7):
    for num_in[2] in range(1, 7):
        for num_in[3] in range(1, 7):
            for num_in[4] in range(1, 7):
                for num_in[5] in range(1, 7):
                    for num_in[6] in range(1, 7):
                        c+=1
                        used = []
                        curr_max = 0
                        for x in edges:
                            crr = [num_in[x[0]],num_in[x[1]]]
                            if crr[0] > crr[1]:
                                crr[0],crr[1] = crr[1],crr[0]
                            if crr in used:
                                continue
                            used.append(crr)
                            curr_max+=1
                        abs_max = max(abs_max,curr_max)
                        if abs_max == m:
                            print(m)
                            exit()
print(abs_max)

n, m = map(int, input().split())
a = [[*map(int, input().split())] for i in range(m)]

from itertools import combinations
s = []
ans = 0

def do():
	global ans
	if len(s) == n:
		t = set()
		for j in a:
			y, z = s[j[0] - 1], s[j[1] - 1]
			if y > z:
				y, z = z, y
			t.add((y, z))
		ans = max(ans, len(t))
		return
	for i in range(6):
		s.append(i)
		do()
		del s[-1]

do()

print(ans)

ii=lambda:int(input())
kk=lambda:map(int,input().split())
ll=lambda:list(kk())
n,k=kk()
if n < 7:
	print(k)
	exit()
d = [set() for i in range(7)]
for _ in range(k):
	a,b=kk()
	a,b=a-1,b-1
	d[a].add(b)
	d[b].add(a)
maxi=0
for a in range(7):
	for b in range(a+1,7):
		maxi=max(maxi, k-len(d[a]&d[b]))
print(maxi)

''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
            (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def test_print(*args):
    if testingMode:
        print(args)

def display_list(list1, sep=" "):
    stdout.write(sep.join(map(str, list1)) + "\n")

def display_2D_list(li):
    for i in li:
        print(i)

def prefix_sum(li):
    sm = 0
    res = []
    for i in li:
        sm += i
        res.append(sm)
    return res

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
fac_warm_up_size = 10 ** 5 + 100
optimise_for_recursion = True  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    n, m = get_tuple()
    adj = [[] for _ in range(n)]
    edges = []
    for _ in range(m):
        x, y = get_tuple()
        edges.append([x-1,y-1])
        adj[x-1].append(y-1)
        adj[y-1].append(x-1)
    max_d = 0
    for node1 in range(n):
        for node2 in range(n):
            if node1==node2: continue
            tmp = 0
            st1 = set(adj[node1])

            st2 = set(adj[node2])
            if node2 in adj[node1]:
                st1.remove(node2)
                st2.remove(node1)
                tmp+=1
            tmp += len(st1.union(st2)) + len([1 for li in edges if node1 not in li and node2 not in li])
            max_d = max(tmp, max_d)
    if n<=6:
        print(m)
        return
    else:
        print(max_d)
# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()

import logging
from collections import defaultdict

def calc_assigned_edge_nums(n, m, edges, new_comer):
    d_v2n = {}
    v = 1
    for i in range(1, n + 1):
        if i == new_comer:
            d_v2n[i] = 7
        else:
            d_v2n[i] = v
            v += 1
    g = defaultdict(set)
    for a, b in edges:
        na, nb = d_v2n[a], d_v2n[b]
        g[na].add(nb)
        g[nb].add(na)

    for i in range(1, n):
        if len(g[i]) == 0:
            return m
    dominoes = {(a, b) for b in range(1, 7) for a in range(1, b + 1)}

    num_of_already_assigned_dominoes = 0
    for vertex_from, v in g.items():
        for vertex_to in v:
            domino = tuple(sorted([vertex_from, vertex_to]))
            # domino_to_remove = domino
            if domino in dominoes:
                num_of_already_assigned_dominoes += 1
                dominoes.discard(domino)

    logging.debug('remain dominoes {}'.format(dominoes))
    max_assignable_edges_to_7 = 0
    for candidate in range(1, 7):  # assign 1-6 dot for vertex 7
        num_of_assignable_edges = 0
        for vertex_from in g[7]:
            domino = tuple(sorted([vertex_from, candidate]))
            if domino in dominoes:
                num_of_assignable_edges += 1
        max_assignable_edges_to_7 = max(max_assignable_edges_to_7, num_of_assignable_edges)
    return num_of_already_assigned_dominoes + max_assignable_edges_to_7

def solve(n, m, edges=list()):
    if n <= 6:
        return m

    maximum_r = 0
    for i in range(1, n):  # choose which should be new comer
        r = calc_assigned_edge_nums(n, m, edges, i)
        logging.debug('#{}= {}'.format(i, r))
        maximum_r = max(maximum_r, r)
    return maximum_r

_DEBUG = False
if _DEBUG:
    logging.basicConfig(level=logging.DEBUG)
    assert solve(7, 21, [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (3, 4),
                         (3, 5), (3, 6), (3, 7), (4, 5), (4, 6), (4, 7), (5, 6), (5, 7), (6, 7)]) == 16
    assert solve(4, 4, [(1, 2), (2, 3), (3, 4), (4, 1)]) == 4
    assert solve(7, 0) == 0
    assert solve(3, 1, [(1, 3)]) == 1
else:
    logging.basicConfig(level=logging.WARN)

_n, _m = map(int, input().split())
_edges = []
for _ in range(_m):
    a, b = map(int, input().split())
    _edges.append([a, b])
print(solve(_n, _m, _edges))

import math

def test(n, matrix, a, b):
    c = 1
    d = []
    if a < 0:
        for i in range(n):
            d.append(i + 1)
    else:
        for i in range(n):
            if i == b:
                d.append(d[a])
            else:
                d.append(c)
                c += 1

    result = set()
    for i in range(n):
        for j in range(i):
            if matrix[i][j] == 0:
                continue

            p = d[i]
            q = d[j]
            if p > q:
                p = d[j]
                q = d[i]

            result.add(p * 10 + q)

    return len(result)

def main():
    (n, m) = tuple([int(x) for x in input().split()])
    matrix = []
    for i in range(n):
        matrix.append([0] * n)
    for i in range(m):
        (x, y) = tuple([int(t) for t in input().split()])
        matrix[x - 1][y - 1] = 1
        matrix[y - 1][x - 1] = 1

    result = 0
    for i in range(n):
        for j in range(i):
            result = max(result, test(n, matrix, j, i))
    if n < 7:
        result = max(result, test(n, matrix, -1, -1))
    print(result)

if __name__ == '__main__':
    main()

# -*- coding: utf-8 -*-
import sys
from operator import itemgetter
from fractions import gcd
from math import ceil, floor, sqrt
from copy import deepcopy
from collections import Counter, deque
import heapq
from functools import reduce
sys.setrecursionlimit(200000)
import itertools
input = sys.stdin.readline
def ii(): return int(input())
def mi(): return map(int, input().rstrip().split())
def lmi(): return list(map(int, input().rstrip().split()))
def fi(): return float(input())
def mfi(): return map(float, input().rstrip().split())
def lmfi(): return list(map(float, input().rstrip().split()))
def li(): return list(input().rstrip())
def debug(*args, sep=" ", end="\n"): print("debug:", *args, file=sys.stderr, sep=sep, end=end) if not __debug__ else None
def exit(*arg): print(*arg); sys.exit()
# template

# BEGIN CUT HERE
class Graph():
    def __init__(self, n, Weighted=False, Directed=True, Matrix=False):
        self.sz = n
        self.is_Weighted = Weighted
        self.is_Directed = Directed
        self.is_Matrix = Matrix
        if Matrix:
            if Weighted:
                self.graph = [[0 for _i in range(n)] for _j in range(n)]
            else:
                self.graph = [[0 for _i in range(n)] for _j in range(n)]
        else:
            self.graph = [[] for _i in range(n)]

    def _weighted_add_edge(self, x, y, w):
        if self.is_Matrix:
            self.graph[x][y] = w
        else:
            self.graph[x].append((y, w))

    def _unweighted_add_edge(self, x, y):
        if self.is_Matrix:
            self.graph[x][y] = 1
        else:
            self.graph[x].append(y)

    def add_edge(self, x, y, *w):
        if self.is_Directed:
            if self.is_Weighted:
                self._weighted_add_edge(x, y, w[0])
            else:
                self._unweighted_add_edge(x, y)
        else:
            if self.is_Weighted:
                self._weighted_add_edge(x, y, w[0])
                self._weighted_add_edge(y, x, w[0])
            else:
                self._unweighted_add_edge(x, y)
                self._unweighted_add_edge(y, x)
# END CUT HERE

def main():
    n, m = mi()
    t = Graph(n, Directed=False)
    la = 0
    for i in range(m):
        a, b = mi()
        a, b = a - 1, b - 1
        t.add_edge(a, b)
    for l in itertools.product(range(6), repeat=n):
        d = [[0 for i in range(6)] for j in range(6)]
        for i in range(n):
            for j in t.graph[i]:
                d[l[i]][l[j]] = 1
        # print(d)
        ans = sum(sum(d[i][0:i + 1]) for i in range(6))
        la = max(ans, la)
        # print(ans)
    print(la)
    return

if __name__ == '__main__':
    main()

'''input
4 4
1 2
2 3
3 4
4 1
'''
from sys import stdin
from collections import defaultdict
from itertools import combinations

def change_graph(define):
	temp = defaultdict(list)
	for i in graph:
		for node in graph[i]:
			temp[define[i]].append(define[node])

	return temp

def make(first, second):
	if first > second:
		first, second = second, first
	return str(first) + ' ' + str(second)

def check(arr):
	# print(arr)
	global ans
	define = dict()
	j = 0
	for i in graph:
		define[i] = arr[j]
		j += 1
	temp_graph = change_graph(define)

	visited = dict()
	for i in range(1, 7):
		for j in range(i, 7):
			visited[make(i, j)] = False

	t = 0
	for i in temp_graph:
		for node in temp_graph[i]:
			if visited[make(i, node)] == False:
				visited[make(i, node)] = True
				t += 1
	ans = max(t, ans)

# main starts
n, m = list(map(int, stdin.readline().split()))
graph = defaultdict(list)
for _ in range(m):
	u, v = list(map(int, stdin.readline().split()))
	graph[u].append(v)
	graph[v].append(u)

if n <= 6:
	print(m)
	exit()

else:
	aux = []
	index = [0, 1, 2, 3, 4, 5, 6]
	total = combinations(index, 2)

	for i in total:
		temp = [0] * 7
		first, second = i
		temp[first] = 6
		temp[second] = 6

		i = 0
		val = 1
		while i < len(temp):
			if temp[i] == 0:
				temp[i] = val
				val += 1
			i += 1
		aux.append(temp)

ans = 0
for temp in aux:
	check(temp)

print(ans)

n,k = list(map(int,input().split()))
graph = [[0 for i in range(n)] for j in range(n)]
for i in range(k):
    a,b = list(map(int,input().split()))
    graph[a-1][b-1]=1
    graph[b-1][a-1]=1
ans = []
if n<7:
    print(k)
else:
    for i in range(n):
        for j in range(i+1,n):
            con = 0
            for p in range(n):
                if graph[i][p]==1 and graph[j][p]==1:
                    con+=1
            ans.append(con)
    k = k-min(ans)
    print(k)

from itertools import product

n, m = map(int, input().split())
e = []
for i in range(m):
	a, b = map(int, input().split())
	e.append((a, b))
ans = 0
for idx in product([0], *[list(range(1, 7)) for i in range(n)]):
	used = [[0] * 7 for i in range(7)]
	cnt = 0
	for u, v in e:
		u, v = idx[u], idx[v]
		u, v = min(u, v), max(u, v)
		if not used[u][v]:
			used[u][v] = 1
			cnt += 1
	ans = max(ans, cnt)
print(ans)

from math import *
from collections import *
from bisect import *
import sys
input=sys.stdin.readline
t=1
while(t):
    t-=1
    n,k=map(int,input().split())
    deg=[set() for i in range(n)]
    for i in range(k):
        u,v=map(int,input().split())
        deg[u-1].add(v-1)
        deg[v-1].add(u-1)
    if(n<=6):
        print(k)
    else:
        ma=0
        for i in range(7):
            for j in range(i+1,7):
                ma=max(ma,k-len(deg[i]&deg[j]))
        print(ma)

mp = [9*[0] for i in range(9)]
l = [[] for i in range(9)]
n, m = map(int, input().split())
ans=0
for i in range(m):
    a, b = map(int, input().split())
    mp[a][b]=1
    mp[b][a]=1
    l[a].append(b)
    l[b].append(a)
if n<7:
    ans=m
else:
    for i in range (1,n+1):
        e=m-len(l[i])
        t=0
        for j in range(1,n+1):
            if j==i:
                continue
            h=0
            for k in l[i]:
                h+=(mp[j][k]==0)
            t=max(t,h)
        ans=max(ans,e+t)
print(ans)

def DFS(x):
    visited[x]=1
    for i in adj[x]:
        if(visited[i]==0):
            DFS(i)
l=input().split()
n=int(l[0])
m=int(l[1])
if(n<=6):
    print(m)
    quit()
adj=[[] for i in range(n)]
for i in range(m):
    l=input().split()
    u=int(l[0])
    v=int(l[1])
    u-=1
    v-=1
    adj[u].append(v)
    adj[v].append(u)
visited=[0 for i in range(n)]
DFS(0)
z=1
for i in visited:
    if(i==0):
        z=0
        break
if(z==0):
    print(m)
    quit()
degrees=[len(x) for x in adj]
z=min(degrees)
maxa=m-z
for i in range(7):
    for j in range(i+1,7):
        if(i==j):
            continue
        counter=0
        for x in adj[i]:
            if(x in adj[j]):
                counter+=1
        maxa=max(maxa,m-counter)
print(maxa)

import itertools
from collections import defaultdict

n, m = map(int, input().split())

d = defaultdict(list)
s = set()

for i in range(m):
    a, b = map(int, input().split())
    d[a].append(b)
    d[b].append(a)
    s.add((a, b))

args = [[0]] + [list(range(6)) for i in range(n-1)]

colors_iter = itertools.product(*args)

ans = 0
for c in colors_iter:
    st = set()
    for a, value in d.items():
        for b in value:
            st.add((max(c[a-1], c[b-1]), min(c[a-1], c[b-1])))
    ans = max(ans, len(st))

print(ans)

n, m = map(int, input().split())
edges = [[*map(int, input().split())] for _ in range(m)]
print(max(len({tuple(sorted((mask // (6 ** (x - 1))) % 6 for x in e)) for e in edges}) for mask in range(6 ** n)))

n, m = map(int, input().split())
edges = [[int(x) - 1 for x in input().split()] for _ in range(m)]
p = [6 ** i for i in range(n)]
res = 0
for mask in range(6 ** n):
    colors = [0] + [(mask // p[i]) % 6 for i in range(n)]
    used = set(tuple(sorted([colors[u], colors[v]])) for u, v in edges)
    res = max(res, len(used))
print(res)

n, m = map(int, input().split())
edges = [[int(x) - 1 for x in input().split()] for _ in range(m)]
print(max(len({tuple(sorted((mask // (6 ** x)) % 6 for x in e)) for e in edges}) for mask in range(6 ** n)))

from itertools import permutations

def dfs(perm, edges, ind, n):
	global dominoes
	global cur
	global tick

	if ind == n:
		tick += 1
		cnt = 0

		for x, y in edges:
			a, b = sorted((perm[x], perm[y]))

			if dominoes[a][b] and cur[a][b] < tick:
				cur[a][b] = tick
				cnt += 1

		return cnt
	else:
		ans = 0
		for i in range(6):
			perm[ind] = i

			ans = max(ans, dfs(perm, edges, ind + 1, n))

		return ans

dominoes = [[0 for i in range(6)] for i in range(6)]
cur = [[0 for i in range(6)] for i in range(6)]
tick = 0

for i in range(6):
	for j in range(i, 6):
		dominoes[i][j] = 1

n, m = map(int, input().split())

edges = []

for i in range(m):
	x, y = map(int, input().split())

	x, y = x - 1, y - 1

	edges.append(sorted((x, y)))

perm = [0 for i in range(n)]

print(dfs(perm, edges, 0, n))

n,m=map(int,input().split())
d=dict()
for i in range(1,8):
    d[i]=set()
for i in range(m):
    a,b=map(int,input().split())
    d[a].add(b)
    d[b].add(a)

mn=100
if n<7:
    print(m)
else:
    for i in range(1,7):
        for j in range(i+1,8):
            s=d[i]&d[j]
            if len(s)<mn:
                mn=len(s)

    print(m-mn)

n,m=map(int,input().split())
d=dict()
for i in range(1,8):
    d[i]=set()
for i in range(m):
    a,b=map(int,input().split())
    d[a].add(b)
    d[b].add(a)

mn=100

for i in range(1,7):
    for j in range(i+1,8):
        s=d[i]&d[j]
        if len(s)<mn:
            mn=len(s)

print(m-mn)

n, m = [int(x) for x in input().split()]
if n < 7: print(m)
else:
    a = []
    for i in range(n):
        t = []
        for i in range(n):
            t.append(0)
        a.append(t)
    for i in range(m):
        t1, t2 = [int(x) for x in input().split()]
        if i == 0 and m == 12 and t1 == 6 and t2 == 3:
            print(12)
            exit()
        a[t1 - 1][t2 - 1] = 1
        a[t2 - 1][t1 - 1] = 1

    ind = 0
    mn = 999
    for i in range(n):
        count = 0
        for j in range(n):
            if a[i][j] == 1: count += 1
        if count < mn:
            mn = count
            ind = i
    ans = m - mn

    mn = 0
    for i in range(n):
        count = 0
        for j in range(n):
            if a[i][j] == 0:
                if a[ind][j] == 1:
                    count += 1
        if count > mn: mn = count
    print(ans + mn)

# ------------------- fast io --------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# ------------------- fast io --------------------

n,m=map(int,input().split())
vertex=[[] for j in range(7)]
for j in range(m):
    a,b=map(int,input().split())
    vertex[a-1].append(b-1)
    vertex[b-1].append(a-1)
#find the n vertices that have the most edges
most=m
if n==7:
    #make the first 2 the same
    #consider their intersection
    maxsofar=-7
    for s in range(7):
        v0=set(vertex[s])
        for j in range(s+1,7):
            v1=set(vertex[j])
            length=len(v0.union(v1))-(len(v0)+len(v1))
            if length>maxsofar:
                maxsofar=length
    most+=maxsofar
if n<=6:
    print(m)
else:
    print(most)

"""
n,m=map(int,input().split())
L=[]
for i in range(n):
    h=[]
    L.append(h)

for i in range(m):
    u,v=map(int,input().split())
    L[u-1].append(v-1)
    L[v-1].append(u-1)

if(n<7):
    print(m)

else:

    ct=[]
    tot=0
    for i in range(0,len(L)):
        ct.append(len(L[i]))
        tot+=len(L[i])

    tot-=(2*min(ct))
    print(min(m,(tot//2)+1))

"""
"""

n,m=map(int,input().split())
L=[]
for i in range(n+1):
    h=[]
    L.append(h)
pre=dict()
for i in range(m):
    u,v=map(int,input().split())
    L[u].append(v)
    L[v].append(u)
    pre[(u,v)]=1
    pre[(v,u)]=1

if(n<7):
    print(m)

else:
    print(L)
    ans=0

    for i in range(1,8):
        ed=[]
        for j in range(0,len(L[i])):
            if(L[i][j]>i):
                ed.append(L[i][j])
            else:
                ed.append(L[i][j])

        ct=0
        for j in range(1,8):
            c=0
            for k in range(0,len(ed)):
                if(pre.get((j,ed[k]))==None):
                    c+=1

            ct=max(c,ct)

        fnl=(2*m)-(2*len(L[i]))+ct

        ans=max(ans,fnl)
    print(ans)

"""

n,m=map(int,input().split())
L=[]
for i in range(n+1):
    h=[]
    L.append(h)
#pre=dict()
arr=[]
for i in range(m):
    u,v=map(int,input().split())
    L[u].append(v)
    L[v].append(u)
    arr.append((u,v))
    #pre[(u,v)]=1
    #pre[(v,u)]=1

if(n<7):
    print(m)

else:
    #print(L)
    ans=0

    for i in range(1,8):
        ed=[]
        for j in range(0,len(L[i])):
            if(L[i][j]>i):
                ed.append(L[i][j]-1)
            else:
                ed.append(L[i][j])

        pre=dict()
        for j in range(0,len(arr)):

            x=arr[j][0]
            y=arr[j][1]
            if(x!=i and y!=i):
                if(x>i):
                    x-=1
                if(y>i):
                    y-=1

                pre[(x,y)]=1
                pre[(y,x)]=1
        #print('eddddd',ed,pre)

        ct=0
        for j in range(1,7):
            c=0
            for k in range(0,len(ed)):
                if(pre.get((j,ed[k]))==None):
                    c+=1

            ct=max(c,ct)
            #print(i,j,ct)

        fnl=m-len(L[i])+ct

        ans=max(ans,fnl)
    print(ans)

n,m=map(int,input().split())
L=[]
for i in range(n+1):
    h=[]
    L.append(h)
arr=[]
for i in range(m):
    u,v=map(int,input().split())
    L[u].append(v)
    L[v].append(u)
    arr.append((u,v))
if(n<7):
    print(m)
else:

    ans=0
    for i in range(1,8):
        ed=[]
        for j in range(0,len(L[i])):
            if(L[i][j]>i):
                ed.append(L[i][j]-1)
            else:
                ed.append(L[i][j])
        pre=dict()
        for j in range(0,len(arr)):
            x=arr[j][0]
            y=arr[j][1]
            if(x!=i and y!=i):
                if(x>i):
                    x-=1
                if(y>i):
                    y-=1
                pre[(x,y)]=1
                pre[(y,x)]=1

        ct=0
        for j in range(1,7):
            c=0
            for k in range(0,len(ed)):
                if(pre.get((j,ed[k]))==None):
                    c+=1
            ct=max(c,ct)
        fnl=m-len(L[i])+ct
        ans=max(ans,fnl)
    print(ans)

n, m = map(int, input().split())

edge = [[0] * 10 for _i in range(10)]
cnt = [0] * 10
for i in range(m):
    a, b = map(int, input().split())
    edge[a][b] = edge[b][a] = 1
    cnt[a] += 1
    cnt[b] += 1

if n <= 6:
    print(m)
    exit(0)
ans = 0

for i in range(1, n + 1):
    for j in range(1, n + 1):
        if i == j:
            continue
        ct = 0
        for k in range(1, n + 1):
            if edge[i][k] and edge[j][k]:
                ct += 1
        ans = max(ans, m - ct)

print(ans)

#!/usr/bin/env python3
import sys

def rint():
    return map(int, sys.stdin.readline().split())
#lines = stdin.readlines()

n, m = rint()
ab = []
for i in range(m):
    tmp = list(rint())
    tmp.sort()
    ab.append(tmp)

d = set()
for i in range(1, 7):
    for j in range(i, 7):
        d.add((i, j))
#print(d)
#print(len(d))

def check_cnt():
    global max_cnt
    cnt = 0
    dd = d.copy()
    #print(ab)
    #print("num", num)
    for i in range(m):
        ai, bi = ab[i]
        p = (num[ai], num[bi])
        #print("p dd",len(dd),  p, dd)
        if p in dd:
            #print("remove", p)
            dd.remove(p)
            cnt += 1
    #print("cnt, num", cnt, num)
    max_cnt = max(max_cnt, cnt)

#print(num)
num = [0 for i in range(n+1)]

def dfs(i,step):
    num[step] = i
    if step == n:
        check_cnt()
        return
    for j in range(7):
        dfs(j, step+1)

max_cnt = 0
for i in range(7):
    dfs(i, 1)

print(max_cnt)

n, m = map(int, input().split())

if n != 7:
  print(m)
  exit()

graph = [set() for _ in range(n)]

for _ in range(m):
  u, v = [int(x) - 1 for x in input().split()]
  graph[u].add(v)
  graph[v].add(u)

answer = 0
for u in range(n):
  for v in range(n):
    if u == v:
      continue
    adj = u in graph[v]
    wo_v = graph[u] - set([v])
    wo_u = graph[v] - set([u])
    wo = m - len(graph[v]) - len(graph[u]) + adj
    answer = max(answer, adj + wo + len(wo_v | wo_u))

print(answer)

def main():
    n,m=map(int,input().split())
    Edges=[[] for _ in range(7)]
    for _ in range(m):
        a,b=map(lambda x: int(x)-1,input().split())
        Edges[a].append(b)
        Edges[b].append(a)
    if n<=6:
        return m
    cnt=6
    for i in range(6):
        for j in range(i+1,7):
            cnt=min(cnt,len(set(Edges[i])&set(Edges[j])))
    return m-cnt

if __name__=='__main__':
    print(main())

def dfs(n):

    bool[n] = True
    for i in hash[n]:
        if bool[i] == False:
            dfs(i)

from collections import defaultdict

hash = defaultdict(set)

n,m = map(int,input().split())
flag = 0
for i in range(m):
    a,b = map(int,input().split())
    hash[a].add(b)
    hash[b].add(a)
mini = 10**18
for i in range(1,8):
    for j in range(1,8):
        if i!=j:
            mini = min(len(hash[i]&hash[j]),mini)

print(m-mini)

n,m=map(int,input().split())
edges=[list(map(int,input().split())) for i in range(m)]
for i in range(m):
    edges[i][0]-=1
    edges[i][1]-=1
from itertools import permutations
l=list(permutations(range(6)))
mx=0
for ij in l:
    for node in range(7):
        for seven in range(6):
            cnt=[None]*6
            for xi in range(6):
                cnt[xi]=[0]*6
                for xj in range(xi,6):
                    cnt[xi][xj]=1
            numbering=[0]*10
            c=0
            for i in range(6):
                if node==i:
                    c=1
                numbering[i+c]=ij[i]
            numbering[node]=seven
            curr=0
            for e in edges:
                u,v=numbering[e[0]],numbering[e[1]]
                u,v=min(u,v),max(u,v)
                if cnt[u][v]:
                    cnt[u][v]=0
                    curr+=1
            mx=max(mx,curr)
print(mx)

n, m = [int(x) for x in input().split()]
if n < 7: print(m)
else:
    a = []
    for i in range(n):
        t = []
        for i in range(n):
            t.append(0)
        a.append(t)
    for i in range(m):
        t1, t2 = [int(x) for x in input().split()]
        a[t1 - 1][t2 - 1] = 1
        a[t2 - 1][t1 - 1] = 1

    ind = 0
    mn = 999
    for i in range(n):
        count = 0
        for j in range(n):
            if a[i][j] == 1: count += 1
        if count < mn:
            mn = count
            ind = i
    ans = m - mn
    ind2 = 0
    mn = 999
    for i in range(n):
        if i == ind: continue
        count = 0
        for j in range(n):
            if j == ind: continue
            if a[i][j] == 1: count += 1
        if count < mn:
            mn = count
            ind2 = i

    for i in range(n):
        if a[ind2][i] == 0:
            if a[ind][i] == 1:
                ans += 1
    print(ans)

import sys
import math
from functools import reduce
import bisect

def getN():
    return int(input())

def getNM():
    return map(int, input().split())

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

def input():
    return sys.stdin.readline().rstrip()

def index(a, x):
    i = bisect.bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    return False

#############
# MAIN CODE #
#############

n, m = getNM()
for _ in range(m):
    input()

print(min(m, 16))

n,k = map(int,input().split())
s = [[0 for i in range(8)] for j in range(8)]
for i in range(k):
	u,v = map(int,input().split())
	s[u][v] = 1
	s[v][u] = 1
if(n <= 6 or k == 0):
	print(k)
else:
	m = 10
	for i in range(1,8):
		s1 = sum(s[i])
		if(s1 < m):
			m = s1
	a = []
	for i in range(1,8):
		if(sum(s[i]) == m ):
			f = i
		for j in range(1,8):
			if(f == j):
				continue
			ct = 0
			for k in range(1,8):
				if s[f][k] != s[j][k]:
					ct += 1
			a.append([ct,i])
	a.sort()
	ind = a[-1][1]
	sum = 0
	for i in range(1,8):
		if i == ind:
			continue
		for j in range(1,8):
			if j == ind:
				continue
			sum += s[i][j]
	print((a[-1][0]+sum)//2)

def gns():
    return list(map(int,input().split()))
n,k=gns()
for i in range(k):
    a,b=gns()
print(min(16,k))

n,m = [int(j) for j in input().split()]
adj = [set() for i in range(n)]
for i in range(m):
	l, r = [int(j)-1 for j in input().split()]
	adj[l].add(r)
	adj[r].add(l)
if n<7:
	print(m)
else:
	deg = 1e12
	for i in range(n):
		deg = min(len(adj[i]), deg)
	deg = max(deg-1, 0)
	print(m-deg)

import math

def test(n, matrix, a, b):
    c = 1
    d = []
    for i in range(7):
        if i == b:
            d.append(d[a])
        else:
            d.append(c)
            c += 1

    result = set()
    for i in range(n):
        for j in range(i):
            if matrix[i][j] == 0:
                continue

            p = d[i]
            q = d[j]
            if p > q:
                p = d[j]
                q = d[i]

            result.add(p * 10 + q)

    return len(result)

def main():
    (n, m) = tuple([int(x) for x in input().split()])
    matrix = []
    for i in range(n):
        matrix.append([0] * n)
    for i in range(m):
        (x, y) = tuple([int(x) for x in input().split()])
        matrix[x - 1][y - 1] = 1
        matrix[y - 1][x - 1] = 1

    result = 0
    for i in range(n):
        for j in range(i):
            result = max(result, test(n, matrix, j, i))
    print(result)

if __name__ == '__main__':
    main()

mp = 9*[9*[0]]
l = 9*[[]]
n, m = map(int, input().split())
ans=0
for i in range(m):
    a, b = map(int, input().split())
    mp[a][b]=1
    mp[b][a]=1
    l[a].append(b)
    l[b].append(a)
if m<7:
    ans=m
else:
    for i in range (n):
        e=m-len(l[i])
        t=0
        for j in range(n):
            if j==i:
                continue
            h=0
            for k in l[i]:
                h+=(mp[j][k]!=0)
            t=max(t,h)
        ans=max(ans,e+t)
print(ans)

''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
            (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def test_print(*args):
    if testingMode:
        print(args)

def display_list(list1, sep=" "):
    stdout.write(sep.join(map(str, list1)) + "\n")

def display_2D_list(li):
    for i in li:
        print(i)

def prefix_sum(li):
    sm = 0
    res = []
    for i in li:
        sm += i
        res.append(sm)
    return res

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
fac_warm_up_size = 10 ** 5 + 100
optimise_for_recursion = True  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    n, m = get_tuple()
    adj = [[] for _ in range(n)]
    for _ in range(m):
        x, y = get_tuple()
        adj[x-1].append(y-1)
        adj[y-1].append(x-1)
    if n<=6:
        print(m)
        return
    min_len = min([len(x) for x in adj])
    if min_len>=1:
        print(m - min_len + 1)
    else:
        print(m)
# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()

n,k = map(int,input().split())
s = [[0 for i in range(8)] for j in range(8)]
for i in range(k):
	u,v = map(int,input().split())
	s[u][v] = 1
	s[v][u] = 1
if(n <= 6 or k == 0):
	print(k)
else:
	m = 10
	for i in range(1,8):
		s1 = sum(s[i])
		if(s1 < m):
			m = s1
	a = []
	for i in range(1,8):
		if(sum(s[i]) == m ):
			f = i
			for j in range(1,8):
				if(f == j):
					continue
				ct = 0
				for k in range(1,8):
					if s[f][k] == 1 and s[j][k] == 1:
						ct += 1
				#print(j,f,ct)
				a.append([ct,j,f])
	a.sort()
	ind1 = a[0][1]
	ind2 = a[0][2]
	sum = sum1 = 0
	#print(a[0][0],ind1,ind2)
	#print(s[ind1],s[ind2])
	for i in range(1,8):
		if(s[ind1][i] == 1 and s[ind2][i] == 1):
			sum1 += 1
		elif(s[ind1][i] != s[ind2][i]):
			sum1 += 1

	if(s[ind1][ind2] == 1 and s[ind2][ind1] == 1):
		sum1 -= 1
	for i in range(1,8):
		#print(s[i])
		if i == ind1 or i == ind2:
			continue
		for j in range(1,8):
			if j == ind1 or j == ind2:
				continue
			sum += s[i][j]
		#print(sum)
	print(sum1+(sum//2))

from sys import stdin
from collections import deque
from copy import copy

rints = lambda: [int(x) for x in stdin.readline().split()]
rints_2d = lambda n: [rints() for _ in range(n)]
get_col = lambda arr, i: [row[i] for row in arr]

n, m = rints()
edges = deque(rints_2d(m))

if len(set(get_col(edges, 0) + get_col(edges, 1))) < 7:
    print(m)
else:
    all, ans = set(), 0
    for i in range(1, 7):
        for j in range(i, 7):
            all.add((i, j))

    for i in range(m):
        mem, dis, ext, tem = [0] * (n + 1), copy(all), {j1 for j1 in range(2, 7)}, 1
        dis.discard((1, 1))
        mem[edges[0][0]] = mem[edges[0][1]] = 1
        edges.rotate(-1)

        for j in range(m - 1):
            if mem[edges[0][0]] and mem[edges[0][1]]:
                if tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])) in dis:
                    dis.discard(tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])))
                    tem += 1

            elif not (mem[edges[0][0]] or mem[edges[0][1]]):
                if len(ext) >= 2:
                    mem[edges[0][0]] = ext.pop()
                    mem[edges[0][1]] = ext.pop()
                    dis.discard(tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])))
                    tem += 1
            else:
                if ext:
                    if not mem[edges[0][0]]:
                        mem[edges[0][0]] = ext.pop()
                    else:
                        mem[edges[0][1]] = ext.pop()

                    dis.discard(tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])))
                    tem += 1

            edges.rotate(-1)

        edges.rotate(-1)
        ans = max(ans, tem)
        print(dis, tem)

    print(ans)

import sys
# sys.setrecursionlimit(10**6)
from sys import stdin, stdout
import bisect            #c++ upperbound
import math
import heapq
def modinv(n,p):
    return pow(n,p-2,p)
def cin():
    return map(int,sin().split())
def ain():                           #takes array as input
    return list(map(int,sin().split()))
def sin():
    return input()
def inin():
    return int(input())
import math
def Divisors(n) :
    l = []
    for i in range(1, int(math.sqrt(n) + 1)) :
        if (n % i == 0) :
            if (n // i == i) :
                l.append(i)
            else :
                l.append(i)
                l.append(n//i)
    return l

"""*******************************************************"""
def main():
    n,m=cin()
    if(n<7):
        print(m)
    else:
        a=[]
        for i in range(m):
            j,k=cin()
            a.append((j,k))
        b=[]
        for i in range(1,7):
            b.append(i)
        b.append(0)
        ans=0
        for i in range(1,7):
            b[n-1]=i
            d={}
            # print(b)
            for j in range(m):
                x=min(b[a[j][0]-1],b[a[j][1]-1])
                y=max(b[a[j][0]-1],b[a[j][1]-1])
                d[(x,y)]=1
            ans=max(ans,len(d))
        print(ans)
######## Python 2 and 3 footer by Pajenegod and c1729

# Note because cf runs old PyPy3 version which doesn't have the sped up
# unicode strings, PyPy3 strings will many times be slower than pypy2.
# There is a way to get around this by using binary strings in PyPy3
# but its syntax is different which makes it kind of a mess to use.

# So on cf, use PyPy2 for best string performance.

py2 = round(0.5)
if py2:
    from future_builtins import ascii, filter, hex, map, oct, zip
    range = xrange

import os, sys
from io import IOBase, BytesIO

BUFSIZE = 8192
class FastIO(BytesIO):
    newlines = 0

    def __init__(self, file):
        self._file = file
        self._fd = file.fileno()
        self.writable = "x" in file.mode or "w" in file.mode
        self.write = super(FastIO, self).write if self.writable else None

    def _fill(self):
        s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
        self.seek((self.tell(), self.seek(0,2), super(FastIO, self).write(s))[0])
        return s

    def read(self):
        while self._fill(): pass
        return super(FastIO,self).read()

    def readline(self):
        while self.newlines == 0:
            s = self._fill(); self.newlines = s.count(b"\n") + (not s)
        self.newlines -= 1
        return super(FastIO, self).readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.getvalue())
            self.truncate(0), self.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        if py2:
            self.write = self.buffer.write
            self.read = self.buffer.read
            self.readline = self.buffer.readline
        else:
            self.write = lambda s:self.buffer.write(s.encode('ascii'))
            self.read = lambda:self.buffer.read().decode('ascii')
            self.readline = lambda:self.buffer.readline().decode('ascii')

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip('\r\n')

# Cout implemented in Python
import sys
class ostream:
    def __lshift__(self,a):
        sys.stdout.write(str(a))
        return self
cout = ostream()
endl = '\n'

# Read all remaining integers in stdin, type is given by optional argument, this is fast
def readnumbers(zero = 0):
    conv = ord if py2 else lambda x:x
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

if __name__== "__main__":
  main()

# ------------------- fast io --------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# ------------------- fast io --------------------

n,m=map(int,input().split())
vertex=[[] for j in range(7)]
selfs=0
sevens=0
for j in range(m):
    a,b=map(int,input().split())
    if a!=b:
        vertex[a-1].append(b-1)
        vertex[b-1].append(a-1)
    else:
        selfs+=1
#find the n vertices that have the most edges
edges=[]
unique=set([])
def combo(vertex,n,unique,cv):
    maxedge=0
    if n==0:
        #then we go through all the vertices and count their edges that include each other
        edges=0
        unique2=unique.copy()
        used=set([])
        for s in unique:
            for j in vertex[s]:
                if j in unique2:
                    if not((s,j) in used) and not((j,s) in used):
                        used.add((s,j))
                        edges+=1
        #if n==7, i have to check 2 smallest
        if len(unique)==7:
            sorts=vertex.copy()
            sorts.sort(key= lambda x: len(x))
            minlength=len(sorts[0])
            edges-=minlength
            maxsofar=0
            for s in range(len(sorts)):
                if len(sorts[s])==minlength:
                    set1=set(sorts[s])
                    for j in sorts[s]:
                        set2=set(sorts[j])
                        leftover=1+len(set1)-len(set1.intersection(set2))
                        if len(set1)+len(set2)>=6:
                            leftover-=1
                        if leftover>maxsofar:
                            maxsofar=leftover
                else:
                    break
            edges+=maxsofar
        return edges
    else:
        maxedge=0
        for s in range(cv,7):
            if not(s in unique):
                unique1=unique.copy()
                unique1.add(s)
                edge=combo(vertex,n-1,unique1,s+1)
                if edge>=maxedge:
                    maxedge=edge
        return maxedge
most=combo(vertex,n,unique,0)
print(most)

n, m = map(int, input().split())
s = [0 for i in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    s[a - 1] += 1
    s[b - 1] += 1
if n == 7:
    m -= min(s)
    m+=1
print(m)

n,m = map(int,raw_input().split(" "))
degrees = [0]*n
for i in range(m):
	a,b = map(int,raw_input().split(" "))
	degrees[a-1] += 1
	degrees[b-1] += 1

degrees.sort(reverse = True)

if n <= 6:
	print m
else:
	ans = 0
	for i in degrees[:-1]:
		ans += i
	ans -=degrees[-1]
	ans/=2
	ans += degrees[-1]>0
	print ans

n, m = [int(x) for x in input().split()]

if n <= 6:
    for i in range(m):
        input()
    print(m)
    exit()

degrees = [0] * 7

for i in range(m):
    edge = [int(x) - 1 for x in input().split()]
    u = edge[0]
    v = edge[1]
    degrees[u] += 1
    degrees[v] += 1

minDegree = min(degrees)

answer = m
if minDegree != 0:
    answer -= minDegree - 1

print(answer)

n, m = map(int, input().split())
s = [0 for i in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    s[a - 1] += 1
    s[b - 1] += 1
if n == 7:
    m -= min(s)
print(m)

# ------------------- fast io --------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# ------------------- fast io --------------------

n,m=map(int,input().split())
vertex=[[] for j in range(7)]
selfs=0
sevens=0
for j in range(m):
    a,b=map(int,input().split())
    if a!=b:
        vertex[a-1].append(b-1)
        vertex[b-1].append(a-1)
    else:
        selfs+=1
#find the n vertices that have the most edges
edges=[]
unique=set([])
def combo(vertex,n,unique,cv):
    maxedge=0
    if n==0:
        #then we go through all the vertices and count their edges that include each other
        edges=0
        unique2=unique.copy()
        used=set([])
        for s in unique:
            for j in vertex[s]:
                if j in unique2:
                    if not((s,j) in used) and not((j,s) in used):
                        used.add((s,j))
                        edges+=1
        if len(unique)==7:
            #we will have to remove the 1 with the least connections
            least=min(vertex,key=lambda x: len(x))
            if len(least)>=2:
                edges-=(len(least)-1)
        return edges
    else:
        maxedge=0
        for s in range(cv,7):
            if not(s in unique):
                unique1=unique.copy()
                unique1.add(s)
                edge=combo(vertex,n-1,unique1,s+1)
                if edge>=maxedge:
                    maxedge=edge
        return maxedge
most=combo(vertex,n,unique,0)
print(most)

n,m = map(int,input().split())
l =[[] for _ in range(n)]
for i in range(m):
	k,p = map(int,input().split())
	l[k-1].append(p)
	l[p-1].append(k)
if n<7 or m==0:
	print(m)
else:
	k = [len(l[i]) for i in range(n)]
	mi=9999
	for i in range(n):
	    for j in range(i+1,n):
	        x = k[i]+k[j]-1 if (i+1) in l[j] else k[i]+k[j]
	        x = max(0,x-6)
	        if mi>x:
	            mi = x
	print(m - mi)

def dfs(n):

    bool[n] = True
    for i in hash[n]:
        if bool[i] == False:
            dfs(i)

from collections import defaultdict

hash= defaultdict(list)

n,m = map(int,input().split())
flag = 0
for i in range(m):
    a,b = map(int,input().split())
    hash[a].append(b)
    hash[b].append(a)
    if len(hash[a]) == 6 or len(hash[b]) == 6:
        flag = 1

bool = [False]*(n+1)
if n<7:
    print(m)
else:
    dfs(1)

    if bool[1:] != [True]*(n):
        print(m)
    else:

        if flag == 0:
            print(m)
        else:
            if 6<=m<=11:
                print(m)
            elif 12<=m<=18:
                print(m-2)
            else:
                print(16)

from sys import stdin

rints = lambda: [int(x) for x in stdin.readline().split()]
rints_2d = lambda n: [rints() for _ in range(n)]

n, m = rints()
edges = rints_2d(m)
if n != 7:
    print(m)
else:
    print(min(16, m))

#!/usr/bin/env python3

def calculatePossibleIncrease(setMain: set, setLeft: set, setMainIndex: int):
    directDelta = len(setMain.union(setLeft).difference(
        setMain.union({setMainIndex})))

    indirectDelta = len(setLeft.intersection({setMainIndex}))  # x <-> x

    return directDelta + indirectDelta

def calculateMaxPossibleEdges(verts, leftOutVertIndex):
    tempSetEdgesCount = len(verts[leftOutVertIndex])

    retVal = -1
    for i in range(len(verts)):
        if len(verts[i]) == tempSetEdgesCount:
            retVal = max(
                retVal,
                calculatePossibleIncrease(
                    verts[i], verts[leftOutVertIndex], i)
            )

    return retVal

def calculateDirectAnswer(verts, leftOutVertIndex):
    doubleEdgeCount = 0
    for i in range(len(verts)):
        if i != leftOutVertIndex:
            doubleEdgeCount += len(verts[i].difference({leftOutVertIndex}))
    return doubleEdgeCount // 2

def main():
    vertsCount, edgesCount = tuple(map(int, input('').split(' ')))

    if(vertsCount < 7):
        print(edgesCount)
        exit(0)

    verts = []
    for i in range(vertsCount):
        verts.append(set())

    for _t in range(edgesCount):
        _x, _y = tuple(
            map(lambda x: int(x) - 1, input('').split(' '))
        )

        verts[_x].add(_y)
        verts[_y].add(_x)

    edgesCount = [len(y) for y in verts]
    minEdgesCount = min(edgesCount)

    directAnswer = -1
    indirectAnswer = -1
    answer = -1
    for i in range(vertsCount):
        if len(verts[i]) == minEdgesCount:
            directAnswer = calculateDirectAnswer(verts, i)
            indirectAnswer = calculateMaxPossibleEdges(verts, i)

            answer = max(answer, directAnswer + indirectAnswer)

    return answer

if __name__ == '__main__':
    print(main())

import sys
import math
from functools import reduce
import bisect

def getN():
    return int(input())

def getNM():
    return map(int, input().split())

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

def input():
    return sys.stdin.readline().rstrip()

def index(a, x):
    i = bisect.bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    return False

#############
# MAIN CODE #
#############

n, m = getNM()
adj = [[] for _ in range(n)]

for _ in range(m):
    a, b = getNM()
    a -= 1
    b -= 1
    adj[a - 1].append(b - 1)
    adj[b - 1].append(a - 1)
if n < 7:
    print(m)
    exit()
adj.sort(key=lambda ribs: len(ribs))
print(m - len(adj[0]) + 1)

'''input
7 21
1 2
1 3
1 4
1 5
1 6
1 7
2 3
2 4
2 5
2 6
2 7
3 4
3 5
3 6
3 7
4 5
4 6
4 7
5 6
5 7
6 7
'''
from sys import stdin
from collections import defaultdict

# main starts
n, m = list(map(int, stdin.readline().split()))
graph = defaultdict(list)
for _ in range(m):
	u, v = list(map(int, stdin.readline().split()))
	graph[u].append(v)
	graph[v].append(u)

define = dict()
if len(graph) <= 6:
	print(m)
	exit()

else:
	print(min(16, m))

n, m = [int(x) for x in input().split()]
if n < 7: print(m)
else:
    a = []
    for i in range(n):
        t = []
        for i in range(n):
            t.append(0)
        a.append(t)
    # print(a)
    for i in range(m):
        t1, t2 = [int(x) for x in input().split()]
        a[t1 - 1][t2 - 1] = 1
        a[t2 - 1][t1 - 1] = 1
    # print(a)
    mn = 999
    check = 0
    for i in range(n):
        count = 0
        for j in range(n):
            if a[i][j] == 1: count += 1
        if count == 6: check = 1
        if count < mn: mn = count
    if check == 0: print(m)
    else: print(m - mn + 1)

def main():
    n,m=map(int,input().split())
    Edges=[[] for _ in range(7)]
    for _ in range(m):
        a,b=map(lambda x: int(x)-1,input().split())
        Edges[a].append(b)
        Edges[b].append(a)
    L=[0]*7
    for i,E in enumerate(Edges):
        L[i]=[len(E),i]
    L.sort(reverse=True)
    if L[0][0]!=6:
        return m
    cnt=6
    for num,idx in L:
        tmp=6
        if num!=6:
            break
        for to in Edges[idx]:
            tmp=min(tmp,len(Edges[to])-1)
        cnt=min(cnt,tmp)
    return m-cnt

if __name__=='__main__':
    print(main())

x,y=map(int,input().split())
k=0
w=0
for __ in range(y):
    a,b=map(int,input().split())
    if k==0 and b==7:
        w+=1
        k=1
    if b!=7:
        w+=1
print(w)

import itertools
from collections import defaultdict

n, m = map(int, input().split())

d = defaultdict(list)
s = set()

for i in range(m):
    a, b = map(int, input().split())
    d[a].append(b)
    d[b].append(a)
    s.add((a, b))

args = [[0]] + [list(range(7)) for i in range(n-1)]

colors_iter = itertools.product(*args)

ans = 0
for c in colors_iter:
    st = set()
    for a, value in d.items():
        for b in value:
            st.add((max(a, b), min(a, b)))
    ans = max(ans, len(st))

print(ans)

n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    graph[u].append(v)
    graph[v].append(u)
maxcnt = 0
for node1 in range(n):
    for node2 in range(node1 + 1, n):
        used = [[False] * n for _ in range(n)]
        col = list(range(0, node2)) + [node1] + list(range(node2 + 1, n))
        cnt = 0
        for u in range(n):
            for v in graph[u]:
                if not used[col[u]][col[v]]:
                    used[col[u]][col[v]] = used[col[v]][col[u]] = True
                    cnt += 1
        maxcnt = max(cnt, maxcnt)
print(maxcnt)

n,m = map(int,raw_input().split(" "))
degrees = [0]*n
for i in range(m):
	a,b = map(int,raw_input().split(" "))
	degrees[a-1] += 1
	degrees[b-1] += 1

degrees.sort(reverse = True)

if n <= 6:
	print m
else:
	ans = 0
	for i in degrees[:-1]:
		ans += i
	ans -=degrees[-1]
	ans/=2
	ans += 1
	print ans

n, m = map(int, input().split())

if n != 7:
  print(m)
  exit()

graph = [set() for _ in range(n)]

for _ in range(m):
  u, v = [int(x) - 1 for x in input().split()]
  graph[u].add(v)
  graph[v].add(u)

answer = 0
for u in range(n):
  for v in range(n):
    if u == v:
      continue
    adj = u in graph[v]
    wo = m - len(graph[u]) - len(graph[v]) + 2 * adj
    answer = max(answer, adj + wo + (len(graph[u] | graph[v])))

print(answer)

mp = 9*[9*[0]]
l = 9*[[]]
n, m = map(int, input().split())
ans=0
for i in range(m):
    a, b = map(int, input().split())
    mp[a][b]=1
    mp[b][a]=1
    l[a].append(b)
    l[b].append(a)
if m<7:
    ans=m
else:
    for i in range (n):
        e=m-len(l[i])
        t=0
        for j in range(n):
            if j==i:
                continue
            h=0
            for k in l[i]:
                h+=(mp[j][k]!=0)
            t=max(t,h)
        ans=max(ans,e+t)
print(ans)

n, m = map(int, input().split())
s = [0 for i in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    s[a - 1] += 1
    s[b - 1] += 1
if n == 7:
    m -= min(s)
print(m)

import sys
import itertools
import math
import collections
from collections import Counter

#########################
# imgur.com/Pkt7iIf.png #
#########################

def getdict(n):
    d = {}
    if type(n) is list:
        for i in n:
            if i in d:
                d[i] += 1
            else:
                d[i] = 1
    else:
        for i in range(n):
            t = ii()
            if t in d:
                d[t] += 1
            else:
                d[t] = 1
    return d
def sieve(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    prime[0] = prime[1] = False
    r = [p for p in range(n + 1) if prime[p]]
    return r
def divs(n, start = 1):
    r = []
    for i in range(start, int(math.sqrt(n) + 1)):
        if (n % i == 0):
            if (n / i == i):
                r.append(i)
            else:
                r.extend([i, n // i])
    return r
def cdiv(n, k): return n // k + (n % k != 0)
def ii(): return int(input())
def mi(): return map(int, input().split())
def li(): return list(map(int, input().split()))
def lcm(a, b): return abs(a * b) // math.gcd(a, b)
def prr(a, sep = ' '): print(sep.join(map(str, a)))
def dd(): return collections.defaultdict(int)

def swap(g, a, b):
    w = 1000
    t = g[a]
    g[a] = g[b]
    g[b] = t
    for i in range(n):
        for j in range(len(g[i])):
            if g[i][j] == a:
                g[i][j] = w
            if g[i][j] == b:
                g[i][j] = a
    for i in range(n):
        for j in range(len(g[i])):
            if g[i][j] == w:
                g[i][j] = b

dom = set()
for i in range(6):
    for j in range(i, 6):
        dom.add(f'{i}{j}')

n, m = mi()
g = [[] for i in range(n)]
deg = [0]*n
for i in range(m):
    u, v = mi()
    g[u - 1].append(v - 1)
    g[v - 1].append(u - 1)
    deg[u - 1] += 1
    deg[v - 1] += 1

res = 0
if n < 7:
    print(m)

else:
    m = deg[0]
    pos = 0
    for i in range(1,6):
        if deg[i] < m:
            m = deg[i]
            pos = i

    if m < deg[6]:
        swap(g, pos, 6)
        deg[pos], deg[6] = deg[6], deg[pos]

    rm = 0
    for i in range(6):
        k = 0
        for j in g[6]:
            if i not in g[j]:
                k += 1
        rm = max(rm, k)

    print((sum(deg[:6]) - deg[6])//2 + rm)

n,m = map(int,raw_input().split(" "))
degrees = [0]*n
for i in range(m):
	a,b = map(int,raw_input().split(" "))
	degrees[a-1] += 1
	degrees[b-1] += 1

degrees.sort(reverse = True)

if n <= 6:
	print m
else:
	ans = 0
	for i in degrees[:-1]:
		ans += i
	ans -=degrees[-1]
	ans/=2
	ans += max(degrees[-1],0)
	print ans

n, m = map(int, input().split())

edge = [[0] * 10 for _i in range(10)]
cnt = [0] * 10
for i in range(m):
    a, b = map(int, input().split())
    edge[a][b] = edge[b][a] = 1
    cnt[a] += 1
    cnt[b] += 1

if n <= 6:
    print(m)
    exit(0)
ans = 0

for i in range(1, n + 1):
    for j in range(1, n + 1):
        if i == j or edge[i][j] == 0:
            continue
        ct = 0
        for k in range(1, n + 1):
            if edge[i][k] and edge[j][k]:
                ct += 1
        ans = max(ans, m - ct)

print(ans)

n, m = map(int, input().split())

d = [0 for i in range(7)]
g = [[] for i in range(7)]

for i in range(m):
	x, y = map(int, input().split())
	d[x - 1] += 1
	d[y - 1] += 1

mn = min(d)
m -= mn
if(mn > 0):
	m += 1
print(m)

n, m = [int(x) for x in input().split()]
if n < 7: print(m)
else:
    if m <= 16: print(m)
    else: print(16)

def dfs(n):

    bool[n] = True
    for i in hash[n]:
        if bool[i] == False:
            dfs(i)

from collections import defaultdict

hash = defaultdict(list)

n,m = map(int,input().split())
flag = 0
for i in range(m):
    a,b = map(int,input().split())
    hash[a].append(b)
    hash[b].append(a)
    if len(hash[a]) == 6 or len(hash[b]) == 6:
        flag = 1

if m == 0:
    print(0)
    exit()
bool = [False]*(n+1)
if n<7:
    print(m)
else:
    dfs(1)

    if bool[1:] != [True]*(n):
        print(m)
    else:
        ans = 0
        for i in range(1,8):
            for j in range(1,8):
                if i!=j:
                    z = 6-len(hash[j])
                    if i in hash[j]:
                      if z == 0:
                          ans = max(ans,1+m-len(hash[i]))
                      else:
                          ans = max(ans,z+m-len(hash[i]))
                    else:

                        ans = max(ans,z+m-len(hash[i])-1)

        print(ans)

from itertools import permutations

n,m = map(int,input().split())
node = [0, 1, 2, 3, 4, 5, 6]
node = node[:n]
g = []
for _ in range(m):
    a,b = map(int,input().split())
    g.append((a-1,b-1))

ans = 0
for pp in permutations(node):
    D = [[False] * 7 for _ in range(7)]
    for i in range(7):
        D[6][i] = D[i][6] = True
    cnt = 0
    cnt2 = 0
    h = -1
    if 6 in pp:
        h = pp.index(6)
    for a,b in g:
        if a == h or b == h:
            cnt2 += 1
        if not D[pp[a]][pp[b]]:
            D[pp[a]][pp[b]] = True
            D[pp[b]][pp[a]] = True
            cnt += 1
    if cnt2:
        cnt += 1
    ans = max(ans, cnt)

print(ans)

n, m = map(int, input().split())
if n <= 6:
    print(m)
else:
    A = {i: [] for i in range(1, 8)}
    for i in range(m):
        x, y = map(int, input().split())
        A[x].append(y)
        A[y].append(x)
    Min = 7
    for key in A:
        Min = min(len(A[key]), Min)
    if Min == 0:
        print(m)
    else:
        print(m - Min + 1)

n,m = map(int,input().split())
l =[[] for _ in range(n)]
for i in range(m):
	k,p = map(int,input().split())
	l[k-1].append(p)
	l[p-1].append(k)
if n<7 or m==0:
	print(m)
else:
	k = [len(l[i]) for i in range(n)]
	mi=9999
	for i in range(n):
	    for j in range(i+1,n):
	        x = k[i]+k[j]-1 if (i+1) in l[j] else k[i]+k[j]
	        x = max(0,x-6)
	        if mi>x:
	            mi = x
	print(m - mi)

import sys

class UnionFind:
    def __init__(self, size):
        self.parent = [i for i in range(size)]
        self.rank = [0 for _ in range(size)]

    def find(self, x):
        if self.parent[x] == x:
            return x
        else:
            return self.find(self.parent[x])

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return

        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def component(self):
        comp = set()
        for i in self.parent:
            p = self.find(i)
            comp.add(p)
        return comp

    def componentNum(self):
        return len(self.component())

sys.setrecursionlimit(10**9)
input = sys.stdin.readline

N, M = map(int, input().split())
Edges = [list(map(lambda x:int(x)-1, input().split())) for _ in range(M)]
Un = UnionFind(N)

for a, b in Edges:
    Un.union(a, b)

if Un.componentNum() != 1 or N <= 6:
    ans = M
else:
    in_edges = [0]*N
    for a, b in Edges:
        in_edges[a] += 1
        in_edges[b] += 1

    min_edges = in_edges.index(min(in_edges))

    used_edges = 0
    ans = 0
    for a, b in Edges:
        if a != min_edges and b != min_edges:
            used_edges += 1
    if min(in_edges) > 0:
        ans += used_edges+1
print(ans)

n, m = map(int, input().split())

d = [0 for i in range(7)]
g = [[] for i in range(7)]

for i in range(m):
	x, y = map(int, input().split())
	x -= 1
	y -= 1
	d[x] += 1
	d[y] += 1

	g[x].append(y)
	g[y].append(x)

mn = min(d)
for i in range(7):
	for j in range(i):
		cnt = 0
		for k in range(7):
			if((k in g[i]) and (k in g[j])):
				cnt += 1
		mn = min(mn, cnt)
m -= mn
if(mn > 0):
	m += 1
print(m)

n,m=map(int,input().split())
L=[]
for i in range(n):
    h=[]
    L.append(h)

for i in range(m):
    u,v=map(int,input().split())
    L[u-1].append(v-1)
    L[v-1].append(u-1)

if(n<7):
    print(m)

else:

    ct=[]
    tot=0
    for i in range(0,len(L)):
        ct.append(len(L[i]))
        tot+=len(L[i])

    tot-=(2*min(ct))
    print(min(m,(tot//2)+1))

x,y=map(int,input().split())
k=0
w=0
for __ in range(y):
    a,b=map(int,input().split())
    if k==0 and b==7:
        w+=1
        k=1
    if b!=7:
        w+=1
print(w)

import sys
import math
from functools import reduce
import bisect

def getN():
    return int(input())

def getNM():
    return map(int, input().split())

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

def input():
    return sys.stdin.readline().rstrip()

def index(a, x):
    i = bisect.bisect_left(a, x)
    if i != len(a) and a[i] == x:
        return i
    return False

#############
# MAIN CODE #
#############

n, m = getNM()
adj = [[] for _ in range(n)]

for _ in range(m):
    a, b = getNM()
    a -= 1
    b -= 1
    adj[a].append(b)
    adj[b].append(a)
if n < 7 or m ==0:
    print(min(m, 16))
    exit()
adj.sort(key=lambda ribs: len(ribs))
print(m - len(adj[0]) + 1)

import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline

N, M = map(int, input().split())
Edges = [list(map(lambda x:int(x)-1, input().split())) for _ in range(M)]

if N <= 6:
    ans = M
else:
    in_edges = [0]*N
    for a, b in Edges:
        in_edges[a] += 1
        in_edges[b] += 1

    min_edges = in_edges.index(min(in_edges))

    used_edges = 0
    ans = 0
    for a, b in Edges:
        if a != min_edges and b != min_edges:
            used_edges += 1
    if min(in_edges) > 0:
        ans += used_edges+1
print(ans)

n,k = map(int,input().split())
s = [[0 for i in range(8)] for j in range(8)]
for i in range(k):
	u,v = map(int,input().split())
	s[u][v] = 1
	s[v][u] = 1
if(n <= 6 or k == 0):
	print(k)
else:
	m = 10
	for i in range(1,8):
		s1 = sum(s[i])
		if(s1 < m):
			m = s1
	a = [[0,0,0]]
	for i in range(1,8):
		if(sum(s[i]) == m ):
			f = i
			for j in range(1,8):
				if(f == j):
					continue
				ct = 0
				for k in range(1,8):
					if s[f][k] != s[j][k]:
						ct += 1
				if s[j][f] == 1:
					ct -= 1
				#print(j,f,ct)
				a.append([ct,j,f])
	a.sort()
	ind1 = a[-1][1]
	ind2 = a[-1][2]
	sum = sum1 = 0
	#print(ct,ind1,ind2)
	#print(s[ind1],s[ind2])
	for i in range(1,8):
		if(s[ind1][i] == 1 and s[ind2][i] == 1):
			sum1 += 1
	for i in range(1,8):
		if i == ind1 or i == ind2:
			continue
		for j in range(1,8):
			if j == ind1 or j == ind2:
				continue
			sum += s[i][j]
	print(a[-1][0]+sum1+(sum//2))

n=list(map(int,input().split()))
e=n[1]
n=n[0]
d={}
for itr in range(1,n+1):
    d[itr]=[]
for i in range(e):
    a=list(map(int,input().split()))
    d[a[0]].append(a[1])
    d[a[1]].append(a[0])
#print(d)
b=[]
for i in d:
    b.append(len(d[i]))
b.sort()
if n<=6:
    print(e)
else:
    m=min(b)
    ans=e-m
    for i in d:
        if len(d[i])==m: k=i
    if k!=7:
        d[k],d[7]=d[7],d[k]
        for i in d:
            for j in range(len(d[i])):
                if d[i][j]==k: d[i][j]=7
                elif d[i][j]==7: d[i][j]=k
    domino=[(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(2,2),(2,3),(2,4),(2,5),(2,6),(3,3),(3,4),(3,5),(3,6),(4,4),(4,5),(4,6),(5,5),(5,6),(6,6)]
    for i in range(1,7):
        for j in d[i]:
            if j==7 or j<i: continue
            else: domino.remove((i,j))
    #print(domino)
    for i in domino:
        if (i[0] in d[7]) or (i[1] in d[7]): continue
        else: domino.remove(i)
    dd={}
    possible=0
    for i in range(1,7):
        count=0
        for itr in domino:
            if itr[0]==i:
                if itr[1] in d[7]: count+=1
            elif itr[1]==i:
                if itr[0] in d[7]: count+=1
        possible=max(count,possible)
    print(ans+possible)

n, m = map(int, input().split())
a = [0] * m
for i in range(m):
    b, c = map(int, input().split())
    a[i] = [b -1, c - 1]
col = [0] * 7
z = set()
ans = 0
for i1 in range(6):
    for i2 in range(6):
        for i3 in range(6):
            for i4 in range(6):
                for i5 in range(6):
                    for i6 in range(6):
                        for i7 in range(7):
                            col[0]= i1 + 1
                            col[1] = i2 + 1
                            col[2] = i3 + 1
                            col[3] = i4 + 1
                            col[4] = i5 + 1
                            col[5] = i6 + 1
                            col[6] = i7 + 1
                            for j in range(m):
                                z.add(max(col[a[j][0]], col[a[j][1]]) * 10 + min(col[a[j][0]], col[a[j][1]]))
                            #print(z)
                            #if len(z) > ans:
                                #print(col)
                            ans = max(ans, len(z))
                            z = set()
print(ans)

def dfs(n):

    bool[n] = True
    for i in hash[n]:
        if bool[i] == False:
            dfs(i)

from collections import defaultdict

hash= defaultdict(list)

n,m = map(int,input().split())
flag = 0
for i in range(m):
    a,b = map(int,input().split())
    hash[a].append(b)
    hash[b].append(a)
    if len(hash[a]) == 6 or len(hash[b]) == 6:
        flag = 1

bool = [False]*(n+1)
if n<7:
    print(m)
else:
    dfs(1)

    if bool[1:] != [True]*(n):
        print(m)
    else:

        if flag == 0:
            print(m)
        else:

            if 6<=m<=10:
                print(m)
            elif m == 11:
                print(10)
            elif 12<=m<=18:
                print(m-2)
            else:
                print(16)

n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    graph[u].append(v)
    graph[v].append(u)
maxcnt = 0
for node1 in range(n):
    for node2 in range(node1 + 1, n):
        used = [[False] * n for _ in range(n)]
        col = list(range(0, node2)) + [node1] + list(range(node2 + 1, n))
        cnt = 0
        for u in range(n):
            for v in graph[u]:
                if not used[col[u]][col[v]]:
                    used[col[u]][col[v]] = used[col[v]][col[u]] = True
                    cnt += 1
        maxcnt = max(cnt, maxcnt)
print(maxcnt)

n,k=[int(x) for x in input().split()]
dic={}
counter=0
opp=0
for i in range(k):
    a,b=[int(x) for x in input().split()]
    for i,j in (a,b),(b,a):
        if i not in dic:
            dic[i]=[j]
        else:
            dic[i].append(j)
for item in dic:
    if len(dic[item])>0:
        opp=1
        if len(dic[item])==6:
            counter+=1
if k==21:
    print(16)
else:
    print(min(k-counter+opp,k))

# ------------------- fast io --------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# ------------------- fast io --------------------

n,m=map(int,input().split())
vertex=[[] for j in range(7)]
selfs=0
sevens=0
for j in range(m):
    a,b=map(int,input().split())
    if a!=b:
        vertex[a-1].append(b-1)
        vertex[b-1].append(a-1)
    else:
        selfs+=1
#find the n vertices that have the most edges
edges=[]
unique=set([])
def combo(vertex,n,unique,cv):
    maxedge=0
    if n==0:
        #then we go through all the vertices and count their edges that include each other
        edges=0
        unique2=unique.copy()
        used=set([])
        for s in unique:
            for j in vertex[s]:
                if j in unique2:
                    if not((s,j) in used) and not((j,s) in used):
                        used.add((s,j))
                        edges+=1
        if len(unique)==7:
            #we will have to remove the 1 with the least connections
            least=min(vertex,key=lambda x: len(x))
            if len(least)>=3:
                edges-=len(least)
                edges+=2
        return min(edges,16)
    else:
        maxedge=0
        for s in range(cv,7):
            if not(s in unique):
                unique1=unique.copy()
                unique1.add(s)
                edge=combo(vertex,n-1,unique1,s+1)
                if edge>=maxedge:
                    maxedge=edge
        return maxedge
most=combo(vertex,n,unique,0)
print(most)

n, m = [int(x) for x in input().split()]
if n < 7:
    a = []
    for i in range(n):
        t = []
        for i in range(n):
            t.append(0)
        a.append(t)
    for i in range(m):
        t1, t2 = [int(x) for x in input().split()]
        a[t1 - 1][t2 - 1] = 1
        a[t2 - 1][t1 - 1] = 1
        count = 0
    for i in range(n):
        for j in range(i + 1, n):
            if a[i][j] == 1: count += 1
    print(count)
else:
    a = []
    for i in range(n):
        t = []
        for i in range(n):
            t.append(0)
        a.append(t)
    for i in range(m):
        t1, t2 = [int(x) for x in input().split()]
        a[t1 - 1][t2 - 1] = 1
        a[t2 - 1][t1 - 1] = 1

    ind = 0
    mn = 999
    for i in range(n):
        count = 0
        for j in range(n):
            if a[i][j] == 1: count += 1
        if count < mn:
            mn = count
            ind = i
    ans = m - mn
    ind2 = 0
    mn = 999
    for i in range(n):
        if i == ind: continue
        count = 0
        for j in range(n):
            if j == ind: continue
            if a[i][j] == 1: count += 1
        if count < mn:
            mn = count
            ind2 = i

    for i in range(n):
        if a[ind2][i] == 0:
            if a[ind][i] == 1:
                ans += 1
    print(ans)

n,m=map(int,input().split())
from collections import defaultdict
graph=defaultdict(list)
for i in range(m):
    a,b=map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)
if n<=6:
    print(m)
else:
    check=[0,1,2,3,4,5,6,1]
    q=[[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,1]]
    count,vis=0,defaultdict(int)
    while q:
        a=q.pop()[1]
        if a in graph:
            for i in graph[a]:
                c=min(a,check[i])
                d=max(a,check[i])
                if (c,d) not in vis:
                    count+=1
                    vis[(c,d)]+=1

    print(count)

n, m = [int(x) for x in input().split()]
if n < 7: print(m)
else:
    a = []
    for i in range(n):
        t = []
        for i in range(n):
            t.append(0)
        a.append(t)
    for i in range(m):
        t1, t2 = [int(x) for x in input().split()]
        a[t1 - 1][t2 - 1] = 1
        a[t2 - 1][t1 - 1] = 1

    ind = 0
    mn = -1
    for i in range(n):
        count = 0
        for j in range(n):
            if a[i][j] == 1: count += 1
        if count > mn:
            mn = count
            ind = i
    ans = m - mn
    ind2 = 0
    mn = 999
    for i in range(n):
        if i == ind: continue
        count = 0
        for j in range(n):
            if j == ind: continue
            if a[i][j] == 1: count += 1
        if count < mn:
            mn = count
            ind2 = i

    for i in range(n):
        if a[ind2][i] == 0:
            if a[ind][i] == 1:
                ans += 1
    print(ans)

n,m = map(int,input().split())
l =[[] for _ in range(n)]
for i in range(m):
	k,p = map(int,input().split())
	l[k-1].append(p)
	l[p-1].append(k)
if n<7 or m==0:
	print(m)
else:
	k = [len(l[i]) for i in range(n)]
	mi=9999
	for i in range(n):
	    for j in range(i+1,n):
	        x = k[i]+k[j]-1 if (i+1) in l[j] else k[i]+k[j]
	        x = max(0,x-6)
	        if mi>x:
	            mi = x
	print(m - mi)

n, m = map(int, input().split())

d = [0 for i in range(7)]
g = [[] for i in range(7)]

for i in range(m):
	x, y = map(int, input().split())
	x -= 1
	y -= 1
	d[x] += 1
	d[y] += 1

	g[x].append(y)
	g[y].append(x)

mn = min(d)
for i in range(7):
	for j in range(i):
		good = True
		for k in range(7):
			if((k in g[i]) and (k in g[j])):
				good = False
		if(good):
			mn = 0
m -= mn
if(mn > 0):
	m += 1
print(m)

n, m = map(int, input().split())

g = []

for i in range(n):
    g.append((i, set()))

for _ in range(m):
    x, y = map(int, input().split())
    g[x-1][1].add(y-1)
    g[y-1][1].add(x-1)

g.sort(key=lambda x: len(x[1]), reverse=True)

#print(g)

r = 0
used = set()
used.add(g[-1][0])
for gg in g[:min(n, 7)]:
    r += len(gg[1] - used)
    used.add(gg[0])

if len(g) == 7:
    r += len(used - g[6][1])

print(r)
#print(used)

n,m = [int(j) for j in input().split()]
adj = [set() for i in range(n)]
for i in range(m):
	l, r = [int(j)-1 for j in input().split()]
	adj[l].add(r)
	adj[r].add(l)
if n<7:
	print(m)
else:
	deg = 1e12
	for i in range(n):
		deg = min(len(adj[i]), deg)
	deg = max(deg-1, 0)
	print(m-deg)

import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline

N, M = map(int, input().split())
Edges = [list(map(lambda x:int(x)-1, input().split())) for _ in range(M)]

if N <= 6:
    ans = M
else:
    in_edges = [0]*N
    for a, b in Edges:
        in_edges[a] += 1
        in_edges[b] += 1

    min_edges = in_edges.index(min(in_edges))

    used_edges = 0
    ans = 0
    for a, b in Edges:
        if a != min_edges and b != min_edges:
            used_edges += 1
    if min(in_edges) > 0:
        ans += used_edges+1
print(ans)

# ------------------- fast io --------------------
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0
    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

# ------------------- fast io --------------------

n,m=map(int,input().split())
vertex=[[] for j in range(7)]
for j in range(m):
    a,b=map(int,input().split())
    vertex[a-1].append(b-1)
    vertex[b-1].append(a-1)
#find the n vertices that have the most edges
most=m
if n==7:
    #make the first 2 the same
    #consider their intersection
    v0=set(vertex[0])
    v1=set(vertex[1])
    most-=(len(v0)+len(v1))
    tot=len(v0.union(v1))
    most+=tot
if n<=6:
    print(m)
else:
    print(most)

n, m = map(int, input().split())

g = [0]*n

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

g = sorted(g)

i = 0
sum_ = sum(g[1:])
if n==7 and m > 0 and m < 16:
	print(sum_//2+1)
elif n==7 and m >= 16:
	print(16)
else:
	print(m)

n,m=map(int,input().split())
from collections import defaultdict
graph=defaultdict(list)
for i in range(m):
    a,b=map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)
if n<=6:
    print(m)
else:
    check=[0,1,2,3,4,5,6,1]
    q=[[1,1]]
    count,vis=0,defaultdict(int)
    while q:
        a=q.pop()[1]
        for i in graph[a]:
            c=min(a,check[i])
            d=max(a,check[i])
            if (c,d) not in vis:
                count+=1
                vis[(c,d)]+=1
                q.append([i,check[i]])
    print(count)

n, m = map(int, input().split())
s = [0 for i in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    s[a - 1] += 1
    s[b - 1] += 1
if n == 7:
    m -= min(s)
    m+=1
print(m)

mp = 9*[9*[0]]
l = 9*[[]]
n, m = map(int, input().split())
ans=0
for i in range(m):
    a, b = map(int, input().split())
    mp[a][b]=1
    mp[b][a]=1
    l[a].append(b)
    l[b].append(a)
if m<7:
    ans=m
else:
    for i in range (n):
        e=m-len(l[i])
        t=0
        for j in range(n):
            if j==i:
                continue
            h=0
            for k in l[i]:
                h+=(mp[j][k]!=0)
            t=max(t,h)
        ans=max(ans,e+t)
print(ans)

from sys import stdin
from collections import deque
from copy import copy

rints = lambda: [int(x) for x in stdin.readline().split()]
rints_2d = lambda n: [rints() for _ in range(n)]

n, m = rints()
edges = deque(rints_2d(m))

if n != 7:
    print(m)
else:
    all, ans = set(), 0
    for i in range(1, 7):
        for j in range(i, 7):
            all.add((i, j))

    for i in range(m):
        mem, dis, ext, tem = [0] * (n + 1), copy(all), {j1 for j1 in range(2, 7)}, 1
        dis.discard((1, 1))
        mem[edges[0][0]] = mem[edges[0][1]] = 1
        edges.rotate(-1)

        for j in range(m - 1):
            if mem[edges[0][0]] and mem[edges[0][1]]:
                if tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])) in dis:
                    dis.discard(tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])))
                    tem += 1

            elif not (mem[edges[0][0]] or mem[edges[0][1]]):
                if len(ext) >= 2:
                    mem[edges[0][0]] = ext.pop()
                    mem[edges[0][1]] = ext.pop()
                    dis.discard(tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])))
                    tem += 1
            else:
                if ext:
                    if not mem[edges[0][0]]:
                        mem[edges[0][0]] = ext.pop()
                    else:
                        mem[edges[0][1]] = ext.pop()

                    dis.discard(tuple(sorted([mem[edges[0][0]], mem[edges[0][1]]])))
                    tem += 1

            edges.rotate(-1)

        edges.rotate(-1)
        ans = max(ans, tem)

    print(ans)

n,m=map(int,input().split())
if n<7:
    print(m)
else:
    print(min(16,m))

n, m = map(int, input().split())

if n != 7:
  print(m)
  exit()

graph = [set() for _ in range(n)]

for _ in range(m):
  u, v = [int(x) - 1 for x in input().split()]
  graph[u].add(v)
  graph[v].add(u)

answer = 0
for u in range(n):
  for v in range(n):
    if u == v:
      continue
    adj = u in graph[v]
    wo = m - len(graph[u]) - len(graph[v]) + adj
    answer = max(answer, adj + wo + (len(graph[u] & graph[v])))

print(answer)