Petya loves lucky numbers. Everybody knows that positive integers are lucky if their decimal representation doesn't contain digits other than 4 and 7. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.

One night Petya was sleeping. He was dreaming of being the president of some island country. The country is represented by islands connected by two-way roads. Between some islands there is no road way, even through other islands, that's why the country is divided into several regions. More formally, each island belongs to exactly one region, there is a path between any two islands located in the same region; there is no path between any two islands from different regions. A region is lucky if the amount of islands in it is a lucky number.

As a real president, Petya first decided to build a presidential palace. Being a lucky numbers' fan, Petya wants to position his palace in one of the lucky regions. However, it is possible that initially the country has no such regions. In this case Petya can build additional roads between different regions, thus joining them. Find the minimum number of roads needed to build to create a lucky region.
The first line contains two integers *n* and *m* (1 ≤ *n*, *m* ≤ 10<sup class="upper-index">5</sup>). They are the number of islands and the number of roads correspondingly. Next *m* lines contain road descriptions. Each road is defined by the numbers of islands that it connects: that is, by two integers *u* and *v* (1 ≤ *u*, *v* ≤ *n*). Some roads can connect an island with itself; there can be more than one road between a pair of islands. Numbers in each line are separated by exactly one space character.
none
4 3
1 2
2 3
1 3
1
5 4
1 2
3 4
4 5
3 5
-1
7 6
1 2
2 3
3 4
4 5
5 6
6 7
0
7 5
2 3
3 4
4 5
3 6
2 2
2
1 1
1 1
-1
2 3
1 2
2 1
1 2
-1
10 1
1 10
2
4 6
1 2
1 3
1 4
3 4
2 4
2 3
0
16 14
2 3
2 4
4 3
5 6
7 6
8 9
12 13
12 14
15 14
13 15
13 14
12 15
16 13
15 16
1
15 14
2 3
2 4
3 4
5 6
6 7
8 9
8 10
8 11
12 13
12 14
14 15
13 15
12 15
13 14
0
4 1
3 3
3
7 1
5 5
3
47 10
1 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
3
47 45
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
31 32
32 33
33 34
34 35
35 36
36 37
37 38
38 39
39 40
40 41
41 42
42 43
43 44
44 45
45 46
46 47
1
20 10
13 7
19 1
5 10
3 2
6 19
3 12
12 10
4 3
5 7
11 9
1
20 50
1 13
1 13
11 4
15 8
8 4
4 1
19 12
15 16
9 20
2 16
9 11
17 6
2 11
9 6
3 7
4 14
14 6
9 4
4 16
11 7
14 7
15 2
12 12
15 13
6 8
5 9
20 19
20 14
12 8
11 11
12 10
20 19
5 18
5 19
10 13
17 13
2 15
17 12
9 7
7 6
19 18
13 3
11 19
3 7
15 11
15 15
5 10
13 8
17 14
2 2
-1
20 1
5 15
2
20 5
10 19
11 20
14 3
16 15
19 1
1
20 30
17 4
10 17
12 3
9 11
17 2
13 12
6 11
14 19
11 14
6 19
18 3
15 1
10 18
3 20
16 15
9 6
13 12
17 5
5 13
20 18
8 19
13 1
2 5
12 15
5 19
6 13
15 16
19 19
19 15
16 6
-1
20 15
10 9
4 14
16 13
13 5
9 10
20 13
13 11
16 14
14 9
14 20
1 19
8 20
7 12
3 20
7 17
1
30 20
29 21
22 2
8 18
16 15
9 12
28 12
24 1
15 23
1 14
18 3
14 10
5 8
19 4
13 29
15 29
30 24
28 25
17 3
8 26
27 20
0
30 4
4 28
7 18
16 17
16 11
1
47 20
41 32
5 36
4 14
15 45
10 36
24 7
12 25
12 43
31 19
28 11
41 43
9 39
33 20
33 28
28 1
39 19
8 20
36 42
22 45
29 7
0
50 50
17 30
29 29
50 42
15 18
34 10
30 3
44 11
4 35
42 8
14 41
30 4
11 1
3 23
7 28
35 6
24 37
6 12
8 7
36 40
41 26
13 46
15 40
32 34
15 28
46 31
36 25
38 43
16 19
35 9
6 21
16 42
38 43
32 12
12 32
43 21
16 35
3 11
24 13
36 24
43 22
29 36
18 15
29 47
30 31
4 7
18 42
9 48
17 32
42 9
2 6
1
64 18
35 37
30 35
56 39
18 46
26 35
39 48
50 27
5 12
28 54
18 51
31 60
1 63
5 51
20 5
23 53
64 11
17 50
14 27
0
100 40
13 92
21 56
53 71
55 8
35 39
45 54
84 14
16 15
15 7
75 31
76 5
32 70
31 71
77 67
38 10
27 48
24 28
33 19
61 70
26 74
11 85
20 15
67 17
37 38
20 66
8 31
62 8
2 7
71 90
91 67
55 35
7 57
10 22
85 64
18 61
75 23
64 50
30 99
27 45
49 42
0
100 3
54 47
85 25
59 47
1
1000 1
908 655
2
1000 10
117 228
530 348
119 116
239 658
102 791
736 786
617 192
396 109
286 509
754 207
1
5000 24
4725 3848
4135 4259
2109 3306
213 3847
1627 3379
4290 2314
9 774
3174 4435
1778 3821
1128 1465
3011 74
501 2861
2935 1995
989 4268
3944 1154
3172 1888
3817 2992
398 4722
4873 4958
1196 4398
3441 1536
4259 3474
4559 1598
2163 2612
1
100000 1
16796 47477
2
20 19
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
-1
7 6
1 2
2 3
3 4
4 5
5 6
6 7
0
20 17
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
12 13
13 14
14 15
15 16
16 17
17 18
18 19
-1
47 42
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
28 29
29 30
30 31
31 32
32 33
33 34
34 35
35 36
37 38
38 39
39 40
40 41
42 43
43 44
44 45
45 46
4
7 5
1 2
2 3
3 4
4 5
6 7
1
4 2
2 3
3 4
1
import sys,math
import random
from bisect import bisect_left , bisect_right 
from collections import defaultdict, Counter, deque



def rd(): return sys.stdin.readline().strip()
def rdl(typ,sep=" "): return list(map(typ, rd().split(sep)))
def rdlInt(dlt=0,sep=" ") : return [int(x)+dlt for x in rd().split(sep)]
def wt(x,sep="\n") : sys.stdout.write(str(x) + sep)    # string / num
def wtBoolUp(x): wt("YES" if x else "NO")  # True = YES/ False =NO
def wtBoolLow(x): wt("Yes" if x else "No")  # True = Yes/ False =No
def wtlArr(arr,sep=" "):   # Print_ arr in single line
    for x in arr: wt(x, sep) 
    wt("")
def wtlsArr(arr):  # Print_ arr in mult lines
    for x in arr: wt(x)
def wtlsArrArr(arr, sep=" "):    # print_ Arrays in multiple lines
    for a in arr: wtlArr(a, sep)


# for dfs use this and use 'yield' during dfs and at last
from types import GeneratorType
def bootstrap(f, stack=[]):              
    def wrappedfunc(*args, **kwargs):
        if stack:
            return f(*args, **kwargs)
        else:
            to = f(*args, **kwargs)
            while True:
                if type(to) is GeneratorType:
                    stack.append(to)
                    to = next(to)
                else:
                    stack.pop()
                    if not stack:
                        break
                    to = stack[-1].send(to)
            return to
    return wrappedfunc

# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

INF = 10**18
MOD = 10**9 + 7 


class mydefaultdict:  # key is always integer
    def __init__(self,default):
        self.RANDOM = random.randint(0,1<<32)
        self.default = default
        self.dict = {}
    def __getitem__(self,key):
        myKey=self.RANDOM^key
        if myKey not in self.dict:
            self.dict[myKey] = self.default()
        return self.dict[myKey]
    def __setitem__(self,key,item):
        myKey=self.RANDOM^key
        self.dict[myKey]=item
    def __delitem__(self, key):
        myKey=self.RANDOM^key
        del self.dict[myKey]
    def __iter__(self):
        return iter(i^self.RANDOM for i in self.dict)
    def __contains__(self,key):
        return key^self.RANDOM in self.dict

def myCounter(seq):
    res = mydefaultdict(0)
    for x in seq: 
        res[x] +=1
    return res


class mySet():   # key is always integer
    def __init__(self):
        self.RANDOM = random.randint(1<<30, 1<<60)
        self.set = set()
 
    def __contains__(self, item):
        return item ^ self.RANDOM in self.set
 
    def add(self, item):
        self.set.add(item ^ self.RANDOM)
 
    def discard(self, item):
        myKey = item ^ self.RANDOM
        if myKey in self.set:
            self.set.remove(myKey)
    
    def pop(self):
        return self.st.pop() ^ self.RANDOM


def binPow(a,b,mod) :
    res = 1
    while b :
        if b % 2: 
            res = res * a % mod
        a = a * a % mod
        b //= 2
    return res

def invMod(x,mod): return pow(x,mod-2,mod)      

def getFacts(n,mod):   # O(n)
    fact = [1]*(n+1)
    for i in range(2,n+1): fact[i] = (i*fact[i-1])%mod
    return fact

def nCr(n, r, fact, mod) :  # O(logMOD)
    num = fact[n]       # numerator
    den = (fact[r] * fact[n - r]) % mod   # denominator
    return (num * invMod(den, mod)) % mod

def lcm(num1,num2):
    hcf = math.gcd(num1,num2)
    lcm_ = (num1*num2)//hcf
    return lcm_

def sqrtFloat(num):  # req : https://codeforces.com/contest/1809/problem/B
    l, r = 0 , num
    res = 0
    while l <= r :
        mid = (l+r)//2
        if mid*mid <= num :
            res = mid
            l = mid + 1
        else : #number will be on l side
            r = mid-1
    
    return res + 0.1*(res*res != num)

def floorDiv(a,b): return a//b
def ceilDiv(a,b): return (a+b-1)//b

def prefixSum(arr):   # 0 at last of prefix sum
    pref = [0]*(len(arr)+1)
    for i in range(len(arr)): pref[i] = arr[i] + pref[i-1]
    return pref

def prefixXor(arr):   # 0 at last of prefix Xor
    pref = [0]*(len(arr)+1)
    for i in range(len(arr)): pref[i] = arr[i] ^ pref[i-1]
    return pref

def apNth(n, a=1, d=1) : return a+(n-1)*d
def apSum(n, a=1, d=1):  return (2*a+(n-1)*d)*n//2
def apSumMod(n, a=1, d=1, mod=MOD):  return ((2*a+(n-1)*d)*n*invMod(2,mod))%mod
def apSumRange(l, r, d=1) : return apSum((r-l+1)//d, l, d)
def apSumRangeMod(l, r, d=1, mod=MOD) : return apSumMod((r-l+1)//d, l, d, mod)

def hypot(p1,p2):
    return ((p2[0]-p1[0])**2 + (p2[1]-p1[1])**2)**0.5
def manhat(p1,p2):
    return abs(p2[0]-p1[0]) + abs(p2[1]-p1[1])

def comb(n,r):   # for small x otherwise TC higher
    res = 1
    for i in range(r) : res = res*(n-i)//(i+1)   # res*(n-i) % (i+1) == 0  always
    return res

def powerArr(base,n,mod):
    pwr = [1]*(n+1)
    for i in range(1,n+1):
        pwr[i] = (base*pwr[i-1]) % mod
    return pwr

def invModArr(n, mod):
    modInv = [1]*(n+1)
    for i in range(2, n+1):  modInv[i] = (modInv[mod % i]*(mod - mod // i)) % mod
    return modInv

def cntlk(incArr, k): return bisect_left(incArr, k)   # < k cnt
def cntleqk(incArr, k): return bisect_right(incArr, k)   # <= k cnt
def cntgk(incArr, k): return len(incArr) - cntleqk(incArr, k)  # > k cnt
def cntgeqk(incArr, k): return len(incArr) - cntlk(incArr, k)  # >= k cnt
def getClosest(num,sortArr,notTake=-INF,notTakeCnt=1):
    idx = bisect_left(sortArr,num)  # find closest to x , not take notTake
    closeArr = []
    for i in range(max(0,idx-2),min(len(sortArr),idx+3)) : # [idx-2,idx-1,idx,idx+1,idx+2]
        if notTakeCnt>0 and sortArr[i] == notTake:
            notTakeCnt -= 1
            continue
        closeArr.append(sortArr[i])
    return min(closeArr, key=lambda x:abs(x-num),default=-INF)

def grouping(itr, notTake=INF):  # grouping of similar elements
    n = len(itr)
    res = []
    i = 0
    while i < n:
        st = i  # start
        while i+1 <n and itr[i] == itr[i+1] :
            i += 1
        if itr[st] != notTake:
            res.append([itr[st],st,i,i-st+1])
        i += 1
    return res

# Geometry :
def getLine(y,m,x):
    c = y-m*x
    return (m,c)


dirnsRD = [(0,1),(1,0)]
dirnsLU = [(0,-1),(-1,0)]
dirns = [(0,1),(1,0),(0,-1),(-1,0)]  # RDLU
dirnsDiag = dirns + [(1,1),(1,-1),(-1,1),(-1,-1)]
chessDirns = [(-2,-1),(-1,-2),(1,-2),(2,-1),(2,1),(1,2),(-1,2),(-2,1)]


def cntBits(n):
    n -= ((n >> 1) & 0x5555555555555555)
    n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333)
    n = (n + (n >> 4)) & 0x0f0f0f0f0f0f0f0f
    n += ((n >> 8) & 0x00ff00ff00ff00ff)
    n += ((n >> 16) & 0x0000ffff0000ffff)
    n += ((n >> 32) & 0x00000000ffffffff)
    return n & 0x7f
def lowBit(a) : return a & -a
def rmvLowBit(a) : return a & (a-1)
def rmvSelectedBits(mask, remover): return mask & ~remover
def isSubset(mask, checker): return mask & checker == checker
def isSuperSet(mask , checker): return mask | checker == mask
def isRepSumP2(num, x): return cntBits(num) <= x <= num  # num in sum two's power in x moves ?
def binry(decimal): return bin(decimal).replace('0b', '')
def deciml(binary): return int(str(binary),2)
def printAllBin(arr):
    maxLen = len(binry(max(arr)))
    for x in arr:
        curr = binry(x)
        res = " ".join(list("0"*(maxLen-len(curr))+curr))
        wt( res + f"   <- {x}")

def c2i(ch,up=0): return ord(ch) - ord('A' if up else 'a')  # ch to integer
def i2c(n,up=0): return chr(ord('A' if up else 'a') + n)    # integer to ch

def setPrecRound(num, cnt): return round(num, cnt)
def setPrec(num, cnt): return format(num,f".{cnt}f")
# Interactive :
def flush(): sys.stdout.flush()
def ojAsk(quesArr, anstyp=int, ansIsList=0): 
    wt("?"," ") ; wtlArr(quesArr)
    flush()
    ans = None
    if ansIsList: ans = rdl(anstyp)
    else: ans = anstyp(rd())
    return ans
def ojAns(ansArr): wt("!"," ") ; wtlArr(ansArr) ; flush()

def clearCache(func): func.cache_clear()   # used to clear the lru cache for every new test case
def SSS(l, r, isReverse):  # in [l,r] strt,stop,stepsize ; use *in range
    if isReverse:
        return [r, l-1, -1]
    return [l, r+1, 1]


# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

# sys.setrecursionlimit(300_005)
INF = 10**9
# MOD = 10**9 + 7


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = list(range(n))
        self.size = [1] * n
        self.compCnt = n

    def findAP(self, curr):
        v = curr
        while self.parent[curr] != curr:
            curr = self.parent[curr]
        while v != curr:
            self.parent[v], v = curr, self.parent[v]
        return curr
    
    def isSame(self, u, v):
        return self.findAP(u) == self.findAP(v)
    
    def getSize(self, u):
        return self.size[self.findAP(u)]
    
    def union(self, u, v):
        uap = self.findAP(u)
        vap = self.findAP(v)
        if uap == vap:
            return False
        if self.size[uap] > self.size[vap]:
            uap, vap = vap, uap
        self.parent[uap] = vap
        self.size[vap] += self.size[uap]  # new AP size increase get uap size
        self.compCnt -= 1
        return True
    
    def linkedCompCount(self): 
        return self.compCnt
    
    def linkedComp(self):
        linkedComp = defaultdict(list)   # components linked to AP, similarly can do for size
        for i in range(self.n):
            ap = self.findAP(i)
            linkedComp[ap].append(i)
        return linkedComp
    
    def linkedCompSize(self):
        compSize = defaultdict(int)
        for i in range(self.n):
            ap = self.findAP(i)
            compSize[ap] += 1
        return compSize


dp = []
limit = None

@bootstrap
def getAns(x):
    global dp, limit
    if x > limit:
        yield INF
    res = INF
    if x > 0:
        res = min(res, dp[x])
    res = min(res, (yield getAns(x*10 + 4)))
    res = min(res, (yield getAns(x*10 + 7)))
    yield res
    


def builtSubsetMin(tot, compressedArr): 
    global dp, limit
    dp = [INF]*(tot+1)  # dp = [0] * (size+1)
    dp[0] = 0
    for x, cnt in compressedArr:
        for i in range(len(dp)-1-x, -1, -1):
            dp[i+x] = min(dp[i+x], dp[i] + cnt)
    
    limit = tot
    res = getAns(0)  # comps Joined , edges required = comps joined-1
    if res == INF:
        return -1
    return res-1


def compress(arr):  
    n = len(arr)
    compressedArr = []
    i = 0
    while i < n:
        st = i  # start
        while i+1 <n and arr[i] == arr[i+1] :
            i += 1
        
        x = arr[i]
        cnt = i-st+1
        j = 1
        while j < cnt:
            compressedArr.append((x*j, j))
            cnt -= j
            j *= 2
        compressedArr.append((x*cnt, cnt))  # remain will be group together
        i += 1  # Move to next group

    return compressedArr
    

def subsetSumMin(arr):  
    n = len(arr)
    if n == 0:
        return 0
    
    tot = sum(arr)

    compressedArr = compress(arr)
    res = builtSubsetMin(tot, compressedArr)    
    return res




def solve():
    n, m = rdl(int)
    uf = UnionFind(n)
    for _ in range(m):
        u,v = rdlInt(-1)
        uf.union(u, v)
    
    ##  -----------------------------------------  
    

    sizes = list(uf.linkedCompSize().values())
    
    res = subsetSumMin(sizes)

    return res


# Don't forget the mod and recursion limit and INF

wt(solve())


