```go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
buf := make([]byte, 64*1024)
scanner.Buffer(buf, 1024*1024)
scanner.Split(bufio.ScanWords)
nextInt := func() int {
scanner.Scan()
res, _ := strconv.Atoi(scanner.Text())
return res
}
if !scanner.Scan() {
return
}
n, _ := strconv.Atoi(scanner.Text())
m := nextInt()
parent := make([]int, n+1)
size := make([]int, n+1)
for i := 1; i <= n; i++ {
parent[i] = i
size[i] = 1
}
var find func(i int) int
find = func(i int) int {
if parent[i] == i {
return i
}
parent[i] = find(parent[i])
return parent[i]
}
union := func(i, j int) {
rootI := find(i)
rootJ := find(j)
if rootI != rootJ {
parent[rootI] = rootJ
size[rootJ] += size[rootI]
}
}
for i := 0; i < m; i++ {
u := nextInt()
v := nextInt()
union(u, v)
}
count := make(map[int]int)
for i := 1; i <= n; i++ {
if parent[i] == i {
count[size[i]]++
}
}
type Item struct {
weight int
cost int
}
var items []Item
for w, c := range count {
for k := 1; k <= c; k *= 2 {
items = append(items, Item{weight: w * k, cost: k})
c -= k
}
if c > 0 {
items = append(items, Item{weight: w * c, cost: c})
}
}
dp := make([]int, n+1)
const INF int = 1e9
for i := 1; i <= n; i++ {
dp[i] = INF
}
dp[0] = 0
for _, item := range items {
for i := n; i >= item.weight; i-- {
if dp[i-item.weight]+item.cost < dp[i] {
dp[i] = dp[i-item.weight] + item.cost
}
}
}
var lucky []int
var gen func(int)
gen = func(v int) {
if v > n {
return
}
if v > 0 {
lucky = append(lucky, v)
}
gen(v*10 + 4)
gen(v*10 + 7)
}
gen(0)
ans := INF
for _, L := range lucky {
if dp[L] < ans {
ans = dp[L]
}
}
if ans == INF {
fmt.Println("-1")
} else {
fmt.Println(ans - 1)
}
}
```