#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sz(x) ((int)(x).size())
#define rep(i,l,r) for(int i=(l);i<(r);++i)
//-------
const int N = 1e5 + 7;
int n;
ll w[N], ic[N], dc[N];
vector<int> e[N];
void dfs(int u, int fa) {
	rep(i, 0, sz(e[u])) {
		int v = e[u][i];
		if (v == fa)
			continue;
		dfs(v, u);
		ic[u] = max(ic[u], ic[v]);
		dc[u] = max(dc[u], dc[v]);
	}
	w[u] += ic[u] - dc[u];
	w[u] >= 0 ? dc[u] += w[u] : ic[u] -= w[u];
}
int main() {
	scanf("%d", &n);
	rep(i, 1, n) {
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v), e[v].push_back(u);
	}
	rep(i, 1, n + 1)
		scanf("%lld", &w[i]);
	dfs(1, -1);
	printf("%lld", ic[1] + dc[1]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sz(x) ((int)(x).size())
#define rep(i,l,r) for(int i=(l);i<(r);++i)
//-------
const int N = 1e5 + 7;
const ll INF = 1e18 + 7;
int n;
ll ans, w[N], add[N];
vector<int> e[N];
void dfs(int u, int fa) {
	ll mn = INF, mx = -INF;
	rep(i, 0, sz(e[u])) {
		int v = e[u][i];
		if (v == fa)
			continue;
		dfs(v, u);
		add[u] += add[v];
		mn = min(mn, w[v]), mx = max(mx, w[v]);
	}
	if (mn < 0)
		ans += -mn, add[u] -= mn;
	if (mx > 0)
		ans += mx, add[u] -= mx;
	w[u] += add[u];
}
int main() {
	scanf("%d", &n);
	rep(i, 1, n) {
		int u, v;
		scanf("%d%d", &u, &v);
		e[u].push_back(v), e[v].push_back(u);
	}
	rep(i, 1, n + 1)
		scanf("%lld", &w[i]), add[i] = 0;
	ans = 0;
	dfs(1, -1);
	ans += abs(w[1]);
	printf("%lld", ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mid ((s + e) / 2)
#define makefast ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define comp(x) (lower_bound(vec.begin(), vec.end(), x) - vec.begin())
#define pb(x) push_back(x)
long long M = 1e9 + 9;
//>>>>>>>>>>>>>>>>>>>

const int N = 1e5 + 7;

vector <int> ad[N];
int n, m;
int cnt[N], mrk[N];

int dfs(int v) {
	mrk[v] = 1;
	int sz = 1;
	for (auto u: ad[v])
		if (!mrk[u])
			sz += dfs(u);
	return sz;
}
int dp[2][N];

void solve(int sz, int w, int a, int b) {
	for (int i = 0; i < w; i++) {
		int laz = 0;
		deque < pair <int, int> > dq;
		for (int j = i; j < N; j += w) {
			laz++;
			int x = dp[b][j] - laz;
			while (dq.size() && dq.back().second >= x)
				dq.pop_back();
			dq.push_back({j, x});
			while (j - dq.front().first > sz * w)
				dq.pop_front();
			dp[a][j] = dq.front().second + laz;
		}
	}
}

int main() {
	makefast;
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		int v, u;
		cin >> v >> u;
		ad[v].push_back(u);
		ad[u].push_back(v);
	}
	for (int i = 1; i <= n; i++)
		if (!mrk[i])
			cnt[dfs(i)]++;
	int cg = 0;
	for (int i = 1; i < N; i++)
		dp[0][i] = 1e9;
	for (int i = 1; i < N; i++)
		if (cnt[i]) {
			cg++;
			solve(cnt[i], i, cg % 2, (cg + 1) % 2);
		}
	int mn = 1e9;
	for (int i = 1; i < N; i++) {
		string s = to_string(i);
		bool lck = 1;
		for (auto c: s)
			if (c != '7' && c != '4')
				lck = 0;
		if (lck)
			mn = min(mn, dp[cg % 2][i]);
	}
	if (mn > N)
		cout << -1;
	else
		cout << mn - 1;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define F first
#define S second

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

const int MAX_N = 500 + 10;
const int MAX_W = 1e5 + 10;
int a[MAX_N], b[MAX_N];
int dp[MAX_W];
vector <int> lucky;

vector <int> adj[MAX_W];
bool mark[MAX_W];

int dfs(int v) {
	mark[v] = 1;

	int ret = 1;
	for (auto u : adj[v])
		if (!mark[u])
			ret += dfs(u);

	return ret;
}

void print_vec(vector <int> vec) {
	for (auto i : vec)
		cerr << i << '*';
	cerr << '\n';
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	int n, m;
	cin >> n >> m;

	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;

		u--, v--;
		adj[u].pb(v);
		adj[v].pb(u);
	}

	int cnt = 0;
	for (int i = 0; i < n; i++)
		if (!mark[i]) {
			int x = dfs(i);

			bool y = 1;
			for (int j = 0; j < cnt; j++)
				if (a[j] == x)
					y = 0, b[j] ++;

			if (y)
				b[cnt] = 1, a[cnt++] = x;

		//	cerr << "*" << a[cnt - 1] << '\n';
		}

	lucky.pb(4), lucky.pb(7);
	int s = 0;
	for (int i = 0; i < 4; i++) {
		int x = lucky.size();

		for (int j = s; j < x; j++) {
			lucky.pb(lucky[j] * 10 + 4);
			lucky.pb(lucky[j] * 10 + 7);
		}

		s = x;
	}

	memset(dp, 63, sizeof dp);
	dp[0] = -1;

	int ans = 1e9;
	for (int i = 0; i < cnt; i++) {
		vector <int> vec;
		for (int j = b[i]; j > 0; j /= 2)
			vec.pb(j);
		reverse(vec.begin(), vec.end());

		//print_vec(vec);

		for (auto j : vec) {
			for (int k = n; k > 0; k--) {
				if (k - a[i] * (j / 2) >= 0)
					dp[k] = min(dp[k], dp[k - a[i] * (j / 2)] + j / 2);

				if (j % 2 && k - a[i] * (j / 2 + 1) >= 0)
					dp[k] = min(dp[k], dp[k - a[i] * (j / 2 + 1)] + j / 2 + 1);
			}
		}

		for (auto l : lucky)
			ans = min(ans, dp[l]);
	}

	if (ans == (int)1e9)
		cout << -1;
	else
		cout << ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define F first
#define S second

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

const int MAX_N = 500 + 10;
const int MAX_W = 1e5 + 10;
int a[MAX_N], b[MAX_N];
int dp[MAX_W];
vector <int> lucky;

vector <int> adj[MAX_W];
bool mark[MAX_W];

int dfs(int v) {
	mark[v] = 1;

	int ret = 1;
	for (auto u : adj[v])
		if (!mark[u])
			ret += dfs(u);

	return ret;
}

void print_vec(vector <int> vec) {
	for (auto i : vec)
		cerr << i << '*';
	cerr << '\n';
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);

	int n, m;
	cin >> n >> m;

	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;

		u--, v--;
		adj[u].pb(v);
		adj[v].pb(u);
	}

	int cnt = 0;
	for (int i = 0; i < n; i++)
		if (!mark[i]) {
			int x = dfs(i);

			bool y = 1;
			for (int j = 0; j < cnt; j++)
				if (a[j] == x)
					y = 0, b[j] ++;

			if (y)
				b[cnt] = 1, a[cnt++] = x;

		//	cerr << "*" << a[cnt - 1] << '\n';
		}

	lucky.pb(0);
	int s = 0;
	for (int i = 0; i < 5; i++) {
		int x = lucky.size();

		for (int j = s; j < x; j++) {
			lucky.pb(lucky[j] * 10 + 4);
			lucky.pb(lucky[j] * 10 + 7);
		}

		s = x;
	}

	memset(dp, 63, sizeof dp);
	dp[0] = -1;

	int ans = 1e9;
	for (int i = 0; i < cnt; i++) {
		vector <int> vec;
		for (int j = b[i]; j > 0; j /= 2)
			vec.pb(j);
		reverse(vec.begin(), vec.end());

		//print_vec(vec);

		for (auto j : vec) {
			for (int k = n; k > 0; k--) {
				if (k - a[i] * (j / 2) >= 0)
					dp[k] = min(dp[k], dp[k - a[i] * (j / 2)] + j / 2);

				if (j % 2 && k - a[i] * (j / 2 + 1) >= 0)
					dp[k] = min(dp[k], dp[k - a[i] * (j / 2 + 1)] + j / 2 + 1);

				for (auto l : lucky)
					if (l == k)
						ans = min(ans, dp[k]);
			}
		}
	}

	if (ans == (int)1e9)
		cout << -1;
	else
		cout << ans;

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N = (int)1e5 + 50, INF = (int)1e9;

int n, m;
bool vis[N];
vector<int> a;
int dp[N];
vector<int> G[N];

int dfs(int v) {
    vis[v] = true;
    int res = 1;
    for(int nxt : G[v]) {
        if(!vis[nxt]) res += dfs(nxt);
    }
    return res;
}

bool is_lucky(int x) {
    while(x > 0) {
        if(x % 10 != 4 && x % 10 != 7) return false;
        x /= 10;
    }
    return true;
}

void put_in(int cost, int wei) {
    for(int j = n; j >= wei; j--) dp[j] = min(dp[j], dp[j - wei] + cost);
}

int main() {
    cin >> n >> m;
    for(int i = 0; i < m; i++) {
        int u, v; cin >> u >> v; u--, v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i = 0; i < n; i++) if(!vis[i]) a.push_back(dfs(i));
    sort(a.begin(), a.end());
    memset(dp, 0x3f, sizeof(dp));
    dp[0] = 0;
    for(int i = 0, r = 0; i < a.size(); i = r) {
        while(r < n && a[r] == a[i]) r++;
        int cnt = r - i;
        for(int k = 1; k <= cnt; k *= 2) {
            put_in(k, k * a[i]);
            cnt -= k;
        }
        if(cnt > 0) put_in(cnt, cnt * a[i]);
    }
    int res = INF;
    for(int i = 1; i <= n; i++) if(is_lucky(i)) res = min(res, dp[i]);
    cout << (res == INF ? -1 : res - 1) << endl;

}


#include <iostream>
#include <vector>
#include <set>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <stdio.h>
#include <cmath>
#include <queue>
#include <string>
#include <map>
#include <complex>
#include <stack>
#include <unordered_map>
#include <set>

#define FOR(i,n) for(int i=0;i<n;i++)
#define FORE(i,a,b) for(int i=a;i<=b;i++)
#define ll long long int
#define vi vector<int>
#define ii pair<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define pll pair<ll,ll>
#define cd complex<double>
const int INF = 1000000000;
const ll MOD = 1000000007;
const int MAXN = 100001;
using namespace std;
// in each segment, we store dp[i][j] denoting cost if it starts at minimum i and ends at maximum j
vi* g;
bool* vis;
int SIZE;

void dfs(int node){
	if(vis[node])return;
	SIZE++;
	vis[node] = 1;
	FOR(i,g[node].size()){
		dfs(g[node][i]);
	}
}

bool lucky(int i){
	if(i == 0)return false;
	while(i > 0){
		if(i%10 != 4 and i%10 != 7)return false;
		i/=10;
	}
	return true;
}

int main(){
	int n,m;
	cin >> n >> m;
	g = new vi[n];
	vis = new bool[n];
	FOR(i,m){
		int a,b;
		cin >>a  >> b;
		a--;
		b--;
		g[a].pb(b);
		g[b].pb(a);
	}
	FOR(i,n)vis[i] = 0;
	vector<int> all;
	FOR(i,n){
		if(!vis[i]){

			SIZE = 0;
			dfs(i);
			all.pb(SIZE);
		}
	}
	int freq[MAXN];
	FOR(i,MAXN)freq[i] = 0;
	FOR(i,all.size())freq[all[i]]++;

	vector<ii> items;
	FOR(i,MAXN){
		int item = 0;
		int ctr = 1;
		while(ctr <= freq[i]){
			//if(freq[i]%2 == 1){
			items.pb(mp(ctr*i,ctr));
			//}
			ctr*=2;
			freq[i]/=2;
		}
	}

	FOR(i,items.size()){
		//cout << items[i].ff << " " << items[i].ss << endl;
	}

	int dp[n+1];

	FOR(i,n+1)dp[i] = INF;
	dp[0] = 0;

	FOR(i,items.size()){
		for(int j = n;j>=0;j--){
			if(j-items[i].ff <0)continue;
			dp[j] = min(dp[j],dp[j-items[i].ff] + items[i].ss);
		}
		FOR(i,n+1){
		//cout << dp[i] << " ";
	}
	//cout << endl;
	}

	int mn = INF;
	FOR(i,n+1){
		if(lucky(i)){mn = min(mn,dp[i]);}//cout << "dfsd" << i << endl;}
	}
	if(mn == INF){
		cout << "-1" << endl;
	}else{
		cout << mn-1 << endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <stdio.h>
#include <cmath>
#include <queue>
#include <string>
#include <map>
#include <complex>
#include <stack>
#include <unordered_map>
#include <set>

#define FOR(i,n) for(int i=0;i<n;i++)
#define FORE(i,a,b) for(int i=a;i<=b;i++)
#define ll long long int
#define vi vector<int>
#define ii pair<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define pll pair<ll,ll>
#define cd complex<double>
const int INF = 1000000000;
const ll MOD = 1000000007;
const int MAXN = 100001;
using namespace std;
// in each segment, we store dp[i][j] denoting cost if it starts at minimum i and ends at maximum j
vi* g;
bool* vis;
int SIZE;

void dfs(int node){
	if(vis[node])return;
	SIZE++;
	vis[node] = 1;
	FOR(i,g[node].size()){
		dfs(g[node][i]);
	}
}

bool lucky(int i){
	if(i == 0)return false;
	while(i > 0){
		if(i%10 != 4 and i%10 != 7)return false;
		i/=10;
	}
	return true;
}

int main(){
	int n,m;
	cin >> n >> m;
	g = new vi[n];
	vis = new bool[n];
	FOR(i,m){
		int a,b;
		cin >>a  >> b;
		a--;
		b--;
		g[a].pb(b);
		g[b].pb(a);
	}
	FOR(i,n)vis[i] = 0;
	vector<int> all;
	FOR(i,n){
		if(!vis[i]){

			SIZE = 0;
			dfs(i);
			all.pb(SIZE);
		}
	}
	int freq[MAXN];
	FOR(i,MAXN)freq[i] = 0;
	FOR(i,all.size())freq[all[i]]++;

	vector<ii> items;
	FOR(i,MAXN){
		int item = 0;
		int ctr = 1;
		while(ctr <= freq[i]){
			//if(freq[i]%2 == 1){
			items.pb(mp(ctr*i,ctr));
			//}
			ctr*=2;
			//freq[i]/=2;
		}
	}

	FOR(i,items.size()){
		//cout << items[i].ff << " " << items[i].ss << endl;
	}

	int dp[n+1];

	FOR(i,n+1)dp[i] = INF;
	dp[0] = 0;

	FOR(i,items.size()){
		for(int j = n;j>=0;j--){
			if(j-items[i].ff <0)continue;
			dp[j] = min(dp[j],dp[j-items[i].ff] + items[i].ss);
		}
		FOR(i,n+1){
		//cout << dp[i] << " ";
	}
	//cout << endl;
	}

	int mn = INF;
	FOR(i,n+1){
		if(lucky(i)){mn = min(mn,dp[i]);}//cout << "dfsd" << i << endl;}
	}
	if(mn == INF){
		cout << "-1" << endl;
	}else{
		cout << mn-1 << endl;
	}

	return 0;
}


#include <iostream>
#include <vector>
#include <set>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <stdio.h>
#include <cmath>
#include <queue>
#include <string>
#include <map>
#include <complex>
#include <stack>
#include <unordered_map>
#include <set>

#define FOR(i,n) for(int i=0;i<n;i++)
#define FORE(i,a,b) for(int i=a;i<=b;i++)
#define ll long long int
#define vi vector<int>
#define ii pair<int,int>
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define pll pair<ll,ll>
#define cd complex<double>
const int INF = 1000000000;
const ll MOD = 1000000007;
const int MAXN = 100001;
using namespace std;
// in each segment, we store dp[i][j] denoting cost if it starts at minimum i and ends at maximum j
vi* g;
bool* vis;
int SIZE;

void dfs(int node){
	if(vis[node])return;
	SIZE++;
	vis[node] = 1;
	FOR(i,g[node].size()){
		dfs(g[node][i]);
	}
}

bool lucky(int i){
	if(i == 0)return false;
	while(i > 0){
		if(i%10 != 4 and i%10 != 7)return false;
		i/=10;
	}
	return true;
}

int main(){
	int n,m;
	cin >> n >> m;
	g = new vi[n];
	vis = new bool[n];
	FOR(i,m){
		int a,b;
		cin >>a  >> b;
		a--;
		b--;
		g[a].pb(b);
		g[b].pb(a);
	}
	FOR(i,n)vis[i] = 0;
	vector<int> all;
	FOR(i,n){
		if(!vis[i]){

			SIZE = 0;
			dfs(i);
			all.pb(SIZE);
		}
	}
	int freq[MAXN];
	FOR(i,MAXN)freq[i] = 0;
	FOR(i,all.size())freq[all[i]]++;

	vector<ii> items;
	FOR(i,MAXN){
		int item = 0;
		int ctr = 1;
		while(freq[i] > 0){
			if(freq[i] %2 == 1){
				items.pb(mp(ctr*i,ctr));
			}
			ctr*=2;
			freq[i]/=2;
		}
	}

	FOR(i,items.size()){
		//cout << items[i].ff << " " << items[i].ss << endl;
	}

	int dp[n+1];

	FOR(i,n+1)dp[i] = INF;
	dp[0] = 0;

	FOR(i,items.size()){
		for(int j = n;j>=0;j--){
			if(j-items[i].ff <0)continue;
			dp[j] = min(dp[j],dp[j-items[i].ff] + items[i].ss);
		}
		FOR(i,n+1){
		//cout << dp[i] << " ";
	}
	//cout << endl;
	}

	int mn = INF;
	FOR(i,n+1){
		if(lucky(i)){mn = min(mn,dp[i]);}//cout << "dfsd" << i << endl;}
	}
	if(mn == INF){
		cout << "-1" << endl;
	}else{
		cout << mn-1 << endl;
	}

	return 0;
}


    //BISMILLAHIR RAHMANIR RAHIM
    #include<bits/stdc++.h>

    //Solution Idea
    //
    using namespace std;

    typedef long long int ll;
    typedef vector<int> vi;
    typedef vector<ll> vl;
    typedef vector<vi> vvi;
    typedef vector<vl> vvl;
    typedef pair<int,int> pii;
    typedef pair <pii , int> piii;
    typedef pair<double, int > pdi;
    typedef pair<ll, ll> pll;
    typedef vector<pii> vii;
    typedef vector<pll> vll;
    typedef pair < ll , pll > plll;
    typedef pair < pll , pll > pllll;

    #define all(v) (v).begin(), (v).end()
    #define KeepUnique(v) (v).erase( unique(all(v)), v.end() )
    #define PB push_back
    #define F first
    #define S second
    #define MP make_pair
    #define endl '\n'
    #define mx 100005
    #define mx1 100005
    #define mx2 200005
    #define mx3 300005
    #define WHITE 0
    #define RED 1
    #define BLACK 2

    #define bp __builtin_popcountll
    #define fraction() cout.unsetf(ios::floatfield); cout.precision(20); cout.setf(ios::fixed,ios::floatfield);
    #define hi cout<<"Dhukse " << endl;
    #define si(x) scanf("%d",&x)
    #define sii(x,y) scanf("%d %d",&x,&y)
    #define siii(x,y,z) scanf("%d %d %d",&x,&y,&z)
    #define sl(x) scanf("%lld",&x)
    #define sll(x,y) scanf("%lld %lld",&x,&y)
    #define slll(x,y,z) scanf("%lld %lld %lld",&x,&y,&z)

    const double PI = acos(-1);
    const double eps = 1e-12;
    const int inf = 2000000000;
    const ll infLL = (ll)1e18;
    ll MOD =  1000000007;
    int MOD1 = 1000000007;
    int MOD2 = 1000000009;

    #define harmonic(n) 0.57721566490153286l(Eulers-Mascharoni constant)+log(n) ( 1/1 + 1/2 + .... + 1/n );

    #define mem(a,b) memset(a, b, sizeof(a) )
    #define gcd(a,b) __gcd(a,b)
    #define lcm(a,b) (a*(b/gcd(a,b)))
    #define sqr(a) ((a) * (a))
    #define optimize() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    typedef vector<int>::iterator vit;
    typedef set<int>::iterator sit;

    inline bool checkBit(ll n, ll i) { return n&(1LL<<i); }
    inline ll setBit(ll n, ll i) { return n|(1LL<<i);; }
    inline ll resetBit(ll n, ll i) { return n&(~(1LL<<i)); }

    int dx[] = {0, 0, +1, -1};
    int dy[] = {+1, -1, 0, 0};
    //int dx[] = {+1, 0, -1, 0, +1, +1, -1, -1};
    //int dy[] = {0, +1, 0, -1, +1, -1, +1, -1};

    inline bool EQ(double a, double b) { return fabs(a-b) < 1e-9; }
    inline bool isLeapYear(ll year) { return (year%400==0) || (year%4==0 && year%100!=0); }
    inline void normal(ll &a) { a %= MOD; (a < 0) && (a += MOD); }
    inline ll modMul(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a*b)%MOD; }
    inline ll modAdd(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); return (a+b)%MOD; }
    inline ll modSub(ll a, ll b) { a %= MOD, b %= MOD; normal(a), normal(b); a -= b; normal(a); return a; }
    inline ll modPow(ll b, ll p) { ll r = 1LL; while(p) { if(p&1) r = modMul(r, b); b = modMul(b, b); p >>= 1LL; } return r; }
    inline ll modDiv(ll a, ll b) { return modMul(a, modPow(b, MOD-2)); }

    bool comp( const pair < ll , pll > &p1 , const pair < ll , pll > &p2 ){ return p1.F > p2.F ;}
    bool comp1( const pll &p1 , const pll &p2 ){
              if( p1.F == p2.F ){
                     return p1.S > p2.S;
              }
              return p1.F < p2.F ;
    }
    ll converter( string a ){
        ll i , mul = 1LL , r , t ,ans = 0LL;if( a.length() == 0 )return 0;for( i = a.length() - 1 ; i >= 0 ; i-- ){
            t = a[i] - '0';r = t%10;ans += (mul*r);mul = mul*10;
        }
        return ans;
    }
    int msb(unsigned x) {
        union { double a; int b[2]; };
        a = x;
        return (b[1] >> 20) - 1023;
    }

    //
    //debug
    #ifndef ONLINE_JUDGE
    template < typename F, typename S >
    ostream& operator << ( ostream& os, const pair< F, S > & p ) {
                return os << "(" << p.first << ", " << p.second << ")";
    }

    template < typename T >
    ostream &operator << ( ostream & os, const vector< T > &v ) {
                os << "{";
                    for(auto it = v.begin(); it != v.end(); ++it) {
                                    if( it != v.begin() ) os << ", ";
                                            os << *it;
                                                }
                        return os << "}";
    }

    template < typename T >
    ostream &operator << ( ostream & os, const set< T > &v ) {
                os << "[";
                    for(auto it = v.begin(); it != v.end(); ++it) {
                                    if( it != v.begin() ) os << ", ";
                                            os << *it;
                                                }
                        return os << "]";
    }

    template < typename T >
    ostream &operator << ( ostream & os, const multiset< T > &v ) {
                os << "[";
                    for(auto it = v.begin(); it != v.end(); ++it) {
                                    if( it != v.begin() ) os << ", ";
                                            os << *it;
                                                }
                            return os << "]";
    }

    template < typename F, typename S >
    ostream &operator << ( ostream & os, const map< F, S > &v ) {
                os << "[";
                    for(auto it = v.begin(); it != v.end(); ++it) {
                                    if( it != v.begin() ) os << ", ";
                                            os << it -> first << " = " << it -> second ;
                                                }
                        return os << "]";
    }

    #define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0)

    void faltu () {
                cerr << endl;
    }

    template <typename T>
    void faltu( T a[], int n ) {
                for(int i = 0; i < n; ++i) cerr << a[i] << ' ';
                    cerr << endl;
    }

    template <typename T, typename ... hello>
    void faltu( T arg, const hello &... rest) {
                cerr << arg << ' ';
                    faltu(rest...);
    }
    #else
    #define dbg(args...)
    #endif
    const int MAX = 200005;
    int par[MAX], sz[MAX] , n , m;
    unordered_map<int,int>cnt;
    int dp[MAX];

    bool is_lucky(int x) {
        while(x > 0 ) {
            int r = x % 10;
            if(r != 4 && r != 7) return false;
            x /= 10;
           // dbg(x);
        }
        return true;
    }

    void banao(int w , int c) {
        dbg(w , c);
       for(int i = n; i >= 0; i--){
            if( i-w >= 0){
                dp[i] = min(dp[i], dp[i-w] + c);
            }
        }
    }

    int solve() {
        fill(dp , dp + MAX , inf);
        dp[0] = 0;
        for(auto it : cnt) {
            int tw = it.F;
            int koita = it.S;
            int k = 1;
            while(2*k - 1 < koita) {
                int w = tw*k;
                int c = k;
                banao(w,c);
                k *= 2;
               // dbg(k);
            }
            k = koita - k + 1;
            //dbg(tw*k,  k);
            banao(tw*k , k);
        }
    }

    void init(){
        for(int i = 1; i<= n; i++)
            par[i] = i, sz[i] = 1;
    }

    int fnd(int u){
        if(par[u] == u) return u;
        return par[u] = fnd(par[u]);
    }

    void merge(int a, int b) {
        //cout << "DHukse" << endl;
        dbg(a , b, a , b);
        a = fnd(a), b = fnd(b);
        if(sz[a] < sz[b]) swap(a, b);
        if(a != b) sz[a] += sz[b];

        par[b] = a;
       // cout << "-> ber hosie" << endl;
        dbg( a,  b);
    }
    int main() {
        optimize();

        #ifndef ONLINE_JUDGE
            freopen("input.txt","r",stdin) ;
            freopen("output.txt","w",stdout);
        #endif
            cin >> n >> m;
            init();
            int x , y;
            for(int i = 0 ; i < m ; ++i) {
                cin >> x >> y;
                merge(x,y);
            }
            for(int i = 1 ; i <= n; ++i) if( fnd(i) == i)cnt[sz[i]]++;
           // dbg(n , m);

            solve();
            int res = inf;

            for(int i = 1; i <= n; ++i) if(is_lucky(i)){
                res = min(res, dp[i]);
            }
            if(res == inf) cout << "-1" << endl;
            else cout << res - 1 << endl;

    }


import java.io.*;
import java.util.*;

public class CF {
    FastScanner in;
    PrintWriter out;

    class Dsu {
        int[] p;
        int[] sz;

        Dsu(int n) {
            p = new int[n];
            for (int i = 0; i < n; i++)
                p[i] = i;
            sz = new int[n];
            Arrays.fill(sz, 1);
        }

        int get(int v) {
            return p[v] == v ? v : (p[v] = get(p[v]));
        }

        void union(int v, int u) {
            v = get(v);
            u = get(u);
            if (v == u)
                return;
            p[v] = u;
            sz[u] += sz[v];
        }
    }

    class Number {
        int count, value;

        public Number(int count, int value) {
            super();
            this.count = count;
            this.value = value;
        }

        @Override
        public String toString() {
            return "Number [count=" + count + ", value=" + value + "]";
        }

    }

    class Knapsack {
        int sz;
        int[] cost;
        int n;
        int[] qPos, qCost;

        Knapsack(int n) {
            this.n = n;
            cost = new int[n + 1];
            Arrays.fill(cost, Integer.MAX_VALUE / 2);
            qPos = new int[n + 1];
            qCost = new int[n + 1];
            cost[0] = 0;
        }

        void addNumber(int count, int value) {
            for (int startPos = 0; startPos < value; startPos++) {
                if (startPos > n)
                    break;
                int qIt = 0, qSz = 0;
                int qAddAll = 0;
                for (int pos = startPos, rPos = 0; pos <= n; pos += value, rPos++) {
                    if (cost[pos] != Integer.MAX_VALUE / 2) {
                        int nCost = -qAddAll + cost[pos];
                        while (qIt < qSz && qCost[qSz - 1] > nCost)
                            qSz--;
                        qCost[qSz] = nCost;
                        qPos[qSz++] = rPos;
                    }
                    while (qIt < qSz && rPos - qPos[qIt] > count)
                        qIt++;
                    if (qIt < qSz) {
                        int realCost = qAddAll + qCost[qIt];
                        cost[pos] = Math.min(cost[pos], realCost);
                    }
                    qAddAll++;
                }
            }
        }
    }

    int getAnswer(Knapsack knapsack, int cur, int max) {
        if (cur > max)
            return Integer.MAX_VALUE;
        int res = Integer.MAX_VALUE;
        if (cur != 0) {
            res = knapsack.cost[cur];
        }
        res = Math.min(res, getAnswer(knapsack, cur * 10 + 4, max));
        res = Math.min(res, getAnswer(knapsack, cur * 10 + 7, max));
        return res;
    }

    void solve() {
        int n = in.nextInt();
        int m = in.nextInt();
        Dsu d = new Dsu(n);
        for (int i = 0; i < m; i++) {
            d.union(in.nextInt() - 1, in.nextInt() - 1);
        }
        ArrayList<Integer> sizes = new ArrayList<>();
        boolean[] was = new boolean[n];
        for (int i = 0; i < n; i++) {
            int v = d.get(i);
            if (was[v])
                continue;
            was[v] = true;
            sizes.add(d.sz[v]);
        }
        Collections.sort(sizes);
        ArrayList<Number> numbers = new ArrayList<>();
        for (int i = 0; i < sizes.size();) {
            int j = i;
            while (j != sizes.size() && sizes.get(j) == sizes.get(i))
                j++;
            numbers.add(new Number(j - i, sizes.get(i)));
            i = j;
        }
        Knapsack knapsack = new Knapsack(n);
        for (Number number : numbers) {
            knapsack.addNumber(number.count, number.value);
        }
        int res = getAnswer(knapsack, 0, n);
        out.println(res >= Integer.MAX_VALUE / 2 ? -1 : res - 1);
    }

    void run() {
        try {
            in = new FastScanner(new File("test.in"));
            out = new PrintWriter(new File("test.out"));

            solve();

            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    void runIO() {

        in = new FastScanner(System.in);
        out = new PrintWriter(System.out);

        solve();

        out.close();
    }

    class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(File f) {
            try {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        public FastScanner(InputStream f) {
            br = new BufferedReader(new InputStreamReader(f));
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return null;
                st = new StringTokenizer(s);
            }
            return st.nextToken();
        }

        boolean hasMoreTokens() {
            while (st == null || !st.hasMoreTokens()) {
                String s = null;
                try {
                    s = br.readLine();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (s == null)
                    return false;
                st = new StringTokenizer(s);
            }
            return true;
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }
    }

    public static void main(String[] args) {
        new CF().runIO();
    }
}


#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=1e5+10,INF=1e9+7;
int tot,sz[MAXN],fa[MAXN],n,m,num[MAXN],f[MAXN],ans;
bool check(int x)
{
	while(x>0)
	{
		if(x%10!=4&&x%10!=7)
			return 0;
		x=x/10;
	}
	return 1;
}
int find(int x)
{
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
void uni(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx==fy)
		return;
	sz[fx]+=sz[fy];
	fa[fy]=fx;
}
void workk(int w,int v)
{
	for(int i=n;i>=w;--i)
		f[i]=min(f[i-w]+v,f[i]);
}
void work(int x,int y)
{
	int num=1;
	if(y==0)
		return ;
	while(y-num>0)
	{
		workk(x*num,num);
		y=y-num;
		num=num*2;
	}
	workk(x*num,num);
}
int main()
{
	int T;
	scanf("%d",&T);
	for(int ii=1;ii<=T;++ii)
	{
		scanf("%d%d",&n,&m);
		tot=0;
		ans=INF;
		for(int i=1;i<=n;++i)
			fa[i]=i,sz[i]=1,num[i]=0;
		for(int i=1;i<=m;++i)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			uni(a,b);
		}
		for(int i=1;i<=n;++i)
			if(fa[i]==i)
				++num[sz[i]];
		for(int i=1;i<=n;++i)
			f[i]=INF;
		f[0]=0;
		for(int i=1;i<=n;++i)
			work(i,num[i]);
		for(int i=1;i<=n;++i)
			if(check(i))
				ans=min(ans,f[i]);
		printf("%d\n",ans==INF?-1:ans-1);
	}
	return 0;
}


#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN=1e5+10,INF=1e9+7;
int tot,sz[MAXN],fa[MAXN],n,m,num[MAXN],f[MAXN],ans;
bool check(int x)
{
	while(x>0)
	{
		if(x%10!=4&&x%10!=7)
			return 0;
		x=x/10;
	}
	return 1;
}
int find(int x)
{
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
void uni(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx==fy)
		return;
	sz[fx]+=sz[fy];
	fa[fy]=fx;
}
void workk(int w,int v)
{
	for(int i=n;i>=w;--i)
		f[i]=min(f[i-w]+v,f[i]);
}
void work(int x,int y)
{
	int num=1;
	if(y==0)
		return ;
	while(y-num>0)
	{
		workk(x*num,num);
		y=y-num;
		num=num*2;
	}
	workk(x*num,num);
}
int main()
{
	int T;
	T=1;
	for(int ii=1;ii<=T;++ii)
	{
		scanf("%d%d",&n,&m);
		tot=0;
		ans=INF;
		for(int i=1;i<=n;++i)
			fa[i]=i,sz[i]=1,num[i]=0;
		for(int i=1;i<=m;++i)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			uni(a,b);
		}
		for(int i=1;i<=n;++i)
			if(fa[i]==i)
				++num[sz[i]];
		for(int i=1;i<=n;++i)
			f[i]=INF;
		f[0]=0;
		for(int i=1;i<=n;++i)
			work(i,num[i]);
		for(int i=1;i<=n;++i)
			if(check(i))
				ans=min(ans,f[i]);
		printf("%d\n",ans==INF?-1:ans-1);
	}
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
#define ALL(X) X.begin(),X.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int MAXN = 1e5 + 5;
const int INF = 1e9;
int n, m;
int par[MAXN];
int cnt[MAXN];
int get(int a){
	if(par[a] == a) return a;
	return par[a] = get(par[a]);
}
void merg(int a, int b){
	int p1 = get(a), p2 = get(b);
	if(cnt[p1] < cnt[p2])
		swap(p1, p2);
	if(p1 == p2) return;
	par[p2] = p1;
	cnt[p1] += cnt[p2];
}
int top;
int r[MAXN];
int k[MAXN];
int w[MAXN];
int wt;
int dp[MAXN];
deque<pii> mq[MAXN];
int main(){
	scanf("%d%d", n, m);
	for(int i = 0; i < n; i++){
		par[i] = i;
		cnt[i] = 1;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		cin>>a>>b;
		scanf("%d%d", a, b);
		a--;b--;
		merg(a, b);
	}
	for(int i = 0; i < n; i++)
		if(par[i] == i)
			w[wt++] = cnt[i];
	sort(w, w + wt);
	for(int i = 1; i <= n; i++){
		int l = upper_bound(w, w + wt, i) - lower_bound(w, w + wt, i);
		if(l != 0){
			r[top] = i;
			k[top ++] = l;
		}
	}
	//cout<<r[0]<<' '<<k[0]<<endl;
	dp[0] = 0;
	for(int i = 1; i <= n; i++)
		dp[i] = INF;
	for(int i = 0; i < top; i++){
		for(int j = 0; j < r[i]; j++)
			mq[j].clear();
		for(int j = 0; j <= n; j++){
			while(mq[j % r[i]].size() && mq[j % r[i]].front().fi > dp[j] - j / r[i])
				mq[j % r[i]].pop_front();
			mq[j % r[i]].push_front(pii(dp[j] - j / r[i], j));
			if(j - mq[j % r[i]].back().se > r[i] * k[i])
				mq[j % r[i]].pop_back();
			dp[j] = mq[j % r[i]].back().fi + j / r[i];
		}
	}
	int ans = INF;
	for(int i = 1; i <= n; i++){
		int x = i;
		while(x > 0){
			if(x % 10 != 4 && x % 10 != 7)
				break;
			x /= 10;
		}
		if(x == 0)
			ans = min(ans, dp[i]);
	}
	if(ans == INF) ans = 0;
	printf("%d\n", ans - 1);
}


#include<bits/stdc++.h>
#define pb push_back
#define ALL(X) X.begin(),X.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int MAXN = 1e5 + 5;
const int INF = 1e9;
int n, m;
int par[MAXN];
int cnt[MAXN];
int get(int a){
	if(par[a] == a) return a;
	return par[a] = get(par[a]);
}
void merg(int a, int b){
	int p1 = get(a), p2 = get(b);
	if(cnt[p1] < cnt[p2])
		swap(p1, p2);
	if(p1 == p2) return;
	par[p2] = p1;
	cnt[p1] += cnt[p2];
}
int top;
int r[MAXN];
int k[MAXN];
int w[MAXN];
int wt;
int dp[MAXN];
deque<pii> mq[MAXN];
int main(){
	scanf("%d%d", n, m);
	for(int i = 0; i < n; i++){
		par[i] = i;
		cnt[i] = 1;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", a, b);
		a--;b--;
		merg(a, b);
	}
	for(int i = 0; i < n; i++)
		if(par[i] == i)
			w[wt++] = cnt[i];
	sort(w, w + wt);
	for(int i = 1; i <= n; i++){
		int l = upper_bound(w, w + wt, i) - lower_bound(w, w + wt, i);
		if(l != 0){
			r[top] = i;
			k[top ++] = l;
		}
	}
	//cout<<r[0]<<' '<<k[0]<<endl;
	dp[0] = 0;
	for(int i = 1; i <= n; i++)
		dp[i] = INF;
	for(int i = 0; i < top; i++){
		for(int j = 0; j < r[i]; j++)
			mq[j].clear();
		for(int j = 0; j <= n; j++){
			while(mq[j % r[i]].size() && mq[j % r[i]].front().fi > dp[j] - j / r[i])
				mq[j % r[i]].pop_front();
			mq[j % r[i]].push_front(pii(dp[j] - j / r[i], j));
			if(j - mq[j % r[i]].back().se > r[i] * k[i])
				mq[j % r[i]].pop_back();
			dp[j] = mq[j % r[i]].back().fi + j / r[i];
		}
	}
	int ans = INF;
	for(int i = 1; i <= n; i++){
		int x = i;
		while(x > 0){
			if(x % 10 != 4 && x % 10 != 7)
				break;
			x /= 10;
		}
		if(x == 0)
			ans = min(ans, dp[i]);
	}
	if(ans == INF) ans = 0;
	printf("%d\n", ans - 1);
}


#include<bits/stdc++.h>
#define pb push_back
#define ALL(X) X.begin(),X.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int MAXN = 1e5 + 5;
const int INF = 1e9;
int n, m;
int par[MAXN];
int cnt[MAXN];
int get(int a){
	if(par[a] == a) return a;
	return par[a] = get(par[a]);
}
void merg(int a, int b){
	int p1 = get(a), p2 = get(b);
	if(cnt[p1] < cnt[p2])
		swap(p1, p2);
	if(p1 == p2) return;
	par[p2] = p1;
	cnt[p1] += cnt[p2];
}
int top;
int r[MAXN];
int k[MAXN];
int w[MAXN];
int wt;
int dp[MAXN];
deque<pii> mq[MAXN];
int main(){
	ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i = 0; i < n; i++){
		par[i] = i;
		cnt[i] = 1;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		cin>>a>>b;
		a--;b--;
		merg(a, b);
	}
	for(int i = 0; i < n; i++)
		if(par[i] == i)
			w[wt++] = cnt[i];
	sort(w, w + wt);
	for(int i = 1; i <= n; i++){
		int l = upper_bound(w, w + wt, i) - lower_bound(w, w + wt, i);
		if(l != 0){
			r[top] = i;
			k[top ++] = l;
		}
	}
	//cout<<r[0]<<' '<<k[0]<<endl;
	dp[0] = 0;
	for(int i = 1; i <= n; i++)
		dp[i] = INF;
	for(int i = 0; i < top; i++){
		for(int j = 0; j < r[i]; j++)
			mq[j].clear();
		for(int j = 0; j <= n; j++){
			while(mq[j % r[i]].size() && mq[j % r[i]].front().fi > dp[j] - j / r[i])
				mq[j % r[i]].pop_front();
			mq[j % r[i]].push_front(pii(dp[j] - j / r[i], j));
			if(j - mq[j % r[i]].back().se > r[i] * k[i])
				mq[j % r[i]].pop_back();
			dp[j] = mq[j % r[i]].back().fi + j / r[i];
		}
	}
	int ans = INF;
	for(int i = 1; i <= n; i++){
		int x = i;
		while(x > 0){
			if(x % 10 != 4 && x % 10 != 7)
				break;
			x /= 10;
		}
		if(x == 0)
			ans = min(ans, dp[i]);
	}
	if(ans == INF) ans = 0;
	cout<<ans - 1<<endl;
}


#include<bits/stdc++.h>
#define pb push_back
#define ALL(X) X.begin(),X.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int MAXN = 1e5 + 5;
const int INF = 1e9;
int n, m;
int par[MAXN];
int cnt[MAXN];
int get(int a){
	if(par[a] == a) return a;
	return par[a] = get(par[a]);
}
void merg(int a, int b){
	int p1 = get(a), p2 = get(b);
	if(cnt[p1] < cnt[p2])
		swap(p1, p2);
	if(p1 == p2) return;
	par[p2] = p1;
	cnt[p1] += cnt[p2];
}
int top;
int r[MAXN];
int k[MAXN];
int w[MAXN];
int wt;
int dp[MAXN];
deque<pii> mq[MAXN];
int main(){
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i++){
		par[i] = i;
		cnt[i] = 1;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		scanf("%d%d", &a, &b);
		a--;b--;
		merg(a, b);
	}
	for(int i = 0; i < n; i++)
		if(par[i] == i)
			w[wt++] = cnt[i];
	sort(w, w + wt);
	for(int i = 1; i <= n; i++){
		int l = upper_bound(w, w + wt, i) - lower_bound(w, w + wt, i);
		if(l != 0){
			r[top] = i;
			k[top ++] = l;
		}
	}
	//cout<<r[0]<<' '<<k[0]<<endl;
	dp[0] = 0;
	for(int i = 1; i <= n; i++)
		dp[i] = INF;
	for(int i = 0; i < top; i++){
		for(int j = 0; j < r[i]; j++)
			mq[j].clear();
		for(int j = 0; j <= n; j++){
			while(mq[j % r[i]].size() && mq[j % r[i]].front().fi > dp[j] - j / r[i])
				mq[j % r[i]].pop_front();
			mq[j % r[i]].push_front(pii(dp[j] - j / r[i], j));
			if(j - mq[j % r[i]].back().se > r[i] * k[i])
				mq[j % r[i]].pop_back();
			dp[j] = mq[j % r[i]].back().fi + j / r[i];
		}
	}
	int ans = INF;
	for(int i = 1; i <= n; i++){
		int x = i;
		while(x > 0){
			if(x % 10 != 4 && x % 10 != 7)
				break;
			x /= 10;
		}
		if(x == 0)
			ans = min(ans, dp[i]);
	}
	if(ans == INF) ans = 0;
	printf("%d\n", ans - 1);
}


#include<bits/stdc++.h>
#define pb push_back
#define ALL(X) X.begin(),X.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int MAXN = 1e5 + 5;
const int INF = 1e9;
int n, m;
int par[MAXN];
int cnt[MAXN];
int get(int a){
	if(par[a] == a) return a;
	return par[a] = get(par[a]);
}
void merg(int a, int b){
	int p1 = get(a), p2 = get(b);
	if(cnt[p1] < cnt[p2])
		swap(p1, p2);
	if(p1 == p2) return;
	par[p2] = p1;
	cnt[p1] += cnt[p2];
}
int top;
int r[MAXN];
int k[MAXN];
vector<int> w;
int dp[MAXN];
deque<pii> mq[MAXN];
int main(){
	ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i = 0; i < n; i++){
		par[i] = i;
		cnt[i] = 1;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		cin>>a>>b;
		a--;b--;
		merg(a, b);
	}
	for(int i = 0; i < n; i++)
		if(par[i] == i){
			w.pb(cnt[i]);
	//		cout<<i<<' '<<cnt[i]<<endl;
		}
	sort(ALL(w));
	for(int i = 1; i <= n; i++){
		int l = upper_bound(ALL(w), i) - lower_bound(ALL(w), i);
		if(l != 0){
			r[top] = i;
			k[top ++] = l;
		}
	}
	//cout<<r[0]<<' '<<k[0]<<endl;
	dp[0] = 0;
	for(int i = 1; i <= n; i++)
		dp[i] = INF;
	for(int i = 0; i < top; i++){
		for(int j = 0; j < r[i]; j++)
			mq[j].clear();
		for(int j = 0; j <= n; j++){
			while(mq[j % r[i]].size() && mq[j % r[i]].front().fi > dp[j] - j / r[i])
				mq[j % r[i]].pop_front();
			mq[j % r[i]].push_front(pii(dp[j] - j / r[i], j));
			if(j - mq[j % r[i]].back().se > r[i] * k[i])
				mq[j % r[i]].pop_back();
			dp[j] = mq[j % r[i]].back().fi + j / r[i];
		}
	}
	int ans = INF;
	for(int i = 1; i <= n; i++){
		int x = i;
		while(x > 0){
			if(x % 10 != 4 && x % 10 != 7)
				break;
			x /= 10;
		}
		if(x == 0)
			ans = min(ans, dp[i]);
	}
	if(ans == INF) ans = 0;
	cout<<ans - 1<<endl;
}


#include<bits/stdc++.h>
#define pb push_back
#define ALL(X) X.begin(),X.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int MAXN = 1e5 + 5;
const int INF = 1e9;
int n, m;
int par[MAXN];
int cnt[MAXN];
int get(int a){
	if(par[a] == a) return a;
	return par[a] = get(par[a]);
}
void merg(int a, int b){
	int p1 = get(a), p2 = get(b);
	if(cnt[p1] < cnt[p2])
		swap(p1, p2);
	if(p1 == p2) return;
	par[p2] = p1;
	cnt[p1] += cnt[p2];
}
int top;
int r[MAXN];
int k[MAXN];
vector<int> w;
int dp[MAXN];
deque<pii> mq[MAXN];
int main(){
	cin>>n>>m;
	for(int i = 0; i < n; i++){
		par[i] = i;
		cnt[i] = 1;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		cin>>a>>b;
		a--;b--;
		merg(a, b);
	}
	for(int i = 0; i < n; i++)
		if(par[i] == i){
			w.pb(cnt[i]);
	//		cout<<i<<' '<<cnt[i]<<endl;
		}
	sort(ALL(w));
	for(int i = 1; i <= n; i++){
		int l = upper_bound(ALL(w), i) - lower_bound(ALL(w), i);
		if(l != 0){
			r[top] = i;
			k[top ++] = l;
		}
	}
	//cout<<r[0]<<' '<<k[0]<<endl;
	dp[0] = 0;
	for(int i = 1; i <= n; i++)
		dp[i] = INF;
	for(int i = 0; i < top; i++){
		for(int j = 0; j < r[i]; j++)
			mq[j].clear();
		for(int j = 0; j <= n; j++){
			while(mq[j % r[i]].size() && mq[j % r[i]].front().fi > dp[j] - j / r[i])
				mq[j % r[i]].pop_front();
			mq[j % r[i]].push_front(pii(dp[j] - j / r[i], j));
			if(j - mq[j % r[i]].back().se > r[i] * k[i])
				mq[j % r[i]].pop_back();
			dp[j] = mq[j % r[i]].back().fi + j / r[i];
		}
	}
	int ans = INF;
	for(int i = 1; i <= n; i++){
		int x = i;
		while(x > 0){
			if(x % 10 != 4 && x % 10 != 7)
				break;
			x /= 10;
		}
		if(x == 0)
			ans = min(ans, dp[i]);
	}
	if(ans == INF) ans = 0;
	cout<<ans - 1<<endl;
}


#include<bits/stdc++.h>
#define pb push_back
#define ALL(X) X.begin(),X.end()
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int MAXN = 1e5 + 5;
const int INF = 1e9;
int n, m;
int par[MAXN];
int cnt[MAXN];
int get(int a){
	if(par[a] == a) return a;
	return par[a] = get(par[a]);
}
void merg(int a, int b){
	int p1 = get(a), p2 = get(b);
	if(cnt[p1] < cnt[p2])
		swap(p1, p2);
	if(p1 == p2) return;
	par[p2] = p1;
	cnt[p1] += cnt[p2];
}
int top;
int r[MAXN];
int k[MAXN];
vector<int> w;
int dp[MAXN];
deque<pii> mq[MAXN];
int main(){
	cin>>n>>m;
	for(int i = 0; i < n; i++){
		par[i] = i;
		cnt[i] = 1;
	}
	for(int i = 0; i < m; i++){
		int a, b;
		cin>>a>>b;
		a--;b--;
		merg(a, b);
	}
	for(int i = 0; i < n; i++)
		if(par[i] == i){
			w.pb(cnt[i]);
	//		cout<<i<<' '<<cnt[i]<<endl;
		}
	sort(ALL(w));
	for(int i = 1; i <= n; i++){
		int l = upper_bound(ALL(w), i) - lower_bound(ALL(w), i);
		if(l != 0){
			r[top] = i;
			k[top ++] = l;
		}
	}
	//cout<<r[0]<<' '<<k[0]<<endl;
	dp[0] = 0;
	for(int i = 1; i <= n; i++)
		dp[i] = INF;
	for(int i = 0; i < top; i++){
		for(int j = 0; j < r[i]; j++)
			mq[j].clear();
		for(int j = 0; j <= n; j++){
			while(mq[j % r[i]].size() && mq[j % r[i]].front().fi > dp[j] - j / r[i])
				mq[j % r[i]].pop_front();
			mq[j % r[i]].push_front(pii(dp[j] - j / r[i], j));
			if(j - mq[j % r[i]].back().se > r[i] * k[i])
				mq[j % r[i]].pop_back();
			dp[j] = mq[j % r[i]].back().fi + j / r[i];
			cout<<dp[j]<<' ';
		}
		cout<<endl;
	}
	int ans = INF;
	for(int i = 1; i <= n; i++){
		int x = i;
		while(x > 0){
			if(x % 10 != 4 && x % 10 != 7)
				break;
			x /= 10;
		}
		if(x == 0)
			ans = min(ans, dp[i]), cout<<"d";
	}
	if(ans == INF) ans = 0;
	cout<<ans - 1<<endl;
}


#include<bits/stdc++.h>
using namespace std;

const int N =  1e5 + 12, INF = 1e9, lg = 20;

int n, m;
vector <int> ad[N];
int sz[N], cnt[N];
int dp[N], ans = INF;

bool ch(int a) {
	while (a) {
		if ((a % 10) != 4 && (a % 10) != 7) return 0;
		a /= 10;
	}
	return 1;
}

void dfs (int root) {
	sz[root] = 1;
	for (auto x : ad[root]) {
		if (sz[x]) continue;
		dfs(x);
		sz[root] += sz[x];
	}
	return;
}

int32_t main() {
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int u, v;
		cin >> u >> v;
		u--, v--;
		ad[u].push_back(v);
		ad[v].push_back(u);
	}

	for (int i = 1; i < N; i++) dp[i] = INF;

	for (int i = 0; i < n; i++) {
		if (sz[i]) continue;
		dfs(i);
		cnt[sz[i]]++;
	}

	dp[0] = -1;

	for (int i = 1; i <= n; i++) {
		if (cnt[i] == 0) continue;

		for (int j = lg - 1; j >= 0; j--) {
			if (cnt[i] < (1 << j)) continue;

			int val = (1 << j) * i;

			for (int l = N; l >= val; l--) {
				if (dp[l - val] == INF) continue;
				dp[l] = min(dp[l], dp[l - val] + (1 << j));
			}
		}
	}

	for (int i = 1; i <= n; i++) {
		if (!ch(i)) continue;
		ans = min(ans, dp[i]);
	}

	if (ans == INF) ans = -1;

	return cout << ans, 0;
}


#pragma region
#include <bits/stdc++.h>
using namespace std;

typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<vector<vector<int>>> vvvi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef vector<vector<ii>> vvii;
typedef vector<vector<vector<ii>>> vvvii;

typedef vector<double> vd;
typedef vector<vector<double>> vvd;
typedef vector<long long> vll;
typedef vector<vector<long long>> vvll;

#define FORI(n) for (int i=0;i<(n);i++)
#define FORJ(n) for (int j=0;j<(n);j++)
#define FORK(n) for (int k=0;k<(n);k++)
#define MOD 1000000007
#define POS_MOD(n,M) (n)%(M) < 0 ? (n)%(M) + (M) : (n)%(M)
#pragma endregion

template <class T>
class SWM{
private:
    deque<pair<T,int>> s;
    int size;
    int last=0;
public:
    SWM(int size){s=deque<pair<T,int>>(); this->size=size; }
    void slide(T elem){
        while (!s.empty() && s.back().first>=elem){
            s.pop_back();
        }
        s.push_back({elem,last++});
        if (s.front().second == last-size-1){
            s.pop_front();
        }
    }
    pair<T, int> min(){
        return s.front();
    }
};

vi visited;
vvi neigh;

int dfs(int i){
    visited[i]=1;
    int cnt=1;
    for (int n:neigh[i]){
        if (!visited[n]){
            cnt+=dfs(n);
        }
    }
    return cnt;
}

bool check47(int i){
    while (i>0){
        if (i%10!=4 && i%10!=7){
            return false;
        }
        i/=10;
    }
    return true;
}

int main(){
    ios_base::sync_with_stdio(false);
    //cin.tie(NULL);

    int n,m; cin>>n>>m;
    visited=vi(n);
    neigh=vvi(n);
    FORI(m){
        int u,v; cin>>u>>v; u--; v--;
        neigh[u].push_back(v);
        neigh[v].push_back(u);
    }

    map<int,int> W;
    FORI(n){
        if (!visited[i]){
            W[dfs(i)]++;
        }
    }

    vvi DP(W.size()+1,vi(n+1));
    FORI(n+1) DP[0][i]=MOD;
    DP[0][0]=0;

    int k=0;
    for (ii p:W){
        k++;
        int num=p.first;
        int count=p.second;
        FORI(num){
            SWM<int> s = SWM<int>(count+1);
            int curr=i;
            int offsetter=0;
            while (curr<=n){
                //cout << curr << " ";
                s.slide(DP[k-1][curr]-offsetter);
                DP[k][curr]=s.min().first+offsetter;
                curr+=num;
                offsetter++;
            }
        }
        //cout << endl;
    }

    int mini = MOD;
    for (int i=1;i<=n;i++){
        if (check47(i)){
            mini=min({mini,DP[W.size()][i]});
        }
    }

    if (mini==MOD){
        cout << -1 << endl;
    }
    else{
        cout << mini-1 << endl;
    }
}


#include <bits/stdc++.h>
using namespace std;

const int DIM = 100005;

int cnt[DIM], dp[DIM], aux[DIM];

deque<pair<int, int>> deq;
bitset<DIM> oki; vector<int> edg[DIM];

int dfs(int x, int nr = 1)
{
    oki[x] = true;
    for (int y : edg[x])
        if (!oki[y]) nr += dfs(y);
    return nr;
}

bool lucky(int x)
{
    for (; x; x /= 10)
        if (x % 10 != 4 and x % 10 != 7)
            return false;
    return true;
}

int main(void)
{
    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= m; ++i) {
        int x, y;
        cin >> x >> y;

        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    for (int i = 1; i <= n; ++i)
        if (!oki[i]) ++cnt[dfs(i)];
    memset(dp, 0x3f, sizeof dp); dp[0] = -1;

    for (int i = 1; i <= n; ++i) if (cnt[i]) {
        for (int s = 0; s < i; ++s) {
            deq.clear();

            for (int j = s, nr = 0; j <= n; j += i, ++nr) {
                while (deq.size() and deq.back().first + deq.back().second >= dp[j] - nr)
                    deq.pop_back();
                deq.push_back(make_pair(dp[j], nr));

                if (deq.front().second == nr - cnt[i] - 1)
                    deq.pop_front();
                aux[j] = deq.front().first + deq.front().second + nr;
            }
        }

        for (int j = 0; j <= n; ++j)
            dp[j] = aux[j];
    }

    int ans = 0x3f3f3f3f;
    for (int i = 1; i <= n; ++i)
        if (lucky(i)) ans = min(ans, dp[i]);

    if (ans > n)
        ans = -1;
    cout << ans << endl;
    return 0;
}

// dp[i] = min(dp[i] + 0, dp[i - k] + 1, dp[i - 2k] + 2, ..., dp[i - pk] + p)


#include <bits/stdc++.h>
using namespace std;

const int DIM = 100005;

int cnt[DIM], dp[DIM], aux[DIM];

deque<pair<int, int>> deq;
bitset<DIM> oki; vector<int> edg[DIM];

int dfs(int x, int nr = 1)
{
    oki[x] = true;
    for (int y : edg[x])
        if (!oki[y]) nr += dfs(y);
    return nr;
}

bool lucky(int x)
{
    for (; x; x /= 10)
        if (x % 10 != 4 and x % 10 != 7)
            return false;
    return true;
}

int main(void)
{
    int n, m;
    cin >> n >> m;

    for (int i = 1; i <= m; ++i) {
        int x, y;
        cin >> x >> y;

        edg[x].push_back(y);
        edg[y].push_back(x);
    }

    for (int i = 1; i <= n; ++i)
        if (!oki[i]) ++cnt[dfs(i)];
    memset(dp, 0x3f, sizeof dp); dp[0] = -1;

    for (int i = 1; i <= n; ++i) if (cnt[i]) {
        for (int s = 0; s < i; ++s) {
            deq.clear();

            for (int j = s, nr = 0; j <= n; j += i, ++nr) {
                while (deq.size() and deq.back().first - deq.back().second >= dp[j] - nr)
                    deq.pop_back();
                deq.push_back(make_pair(dp[j], nr));

                if (deq.front().second == nr - cnt[i] - 1)
                    deq.pop_front();
                aux[j] = deq.front().first - deq.front().second + nr;
            }
        }

        for (int j = 0; j <= n; ++j)
            dp[j] = aux[j];
    }

    int ans = 0x3f3f3f3f;
    for (int i = 1; i <= n; ++i)
        if (lucky(i)) ans = min(ans, dp[i]);

    if (ans > n)
        ans = -1;
    cout << ans << endl;
    return 0;
}

// dp[i] = min(dp[i] + 0, dp[i - k] + 1, dp[i - 2k] + 2, ..., dp[i - pk] + p)


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PI;
int par[100010],size[100010];
bool vis[100010];
void init(int n){
	for(int i=1;i<=n;i++)
		par[i]=i,size[i]=1;
}
int find(int x){
	if(par[x]==x) return x;
	return par[x]=find(par[x]);
}
void unite(int x,int y){
	x=find(x),y=find(y);
	if(x==y) return;
	if(size[x]<size[y]) swap(x,y);
	par[y]=x;
	size[x]+=size[y];
}
inline bool isLucky(int x){
	while(x>0){
		if(x%10!=4 && x%10!=7) return false;
		x/=10;
	}
	return true;
}
map<int,int> mp;
int dp[2][100010];
int main(){
	int n,m,u,v;
	scanf("%d%d",&n,&m);
	init(n);
	for(int i=0;i<m;i++){
		scanf("%d%d",&u,&v);
		unite(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!vis[find(i)]){
			vis[find(i)]=true;
			mp[size[find(i)]]++;
		}
	}
	memset(dp[0],0x3f,sizeof dp[0]);
	dp[0][0]=0;
	int idx=1;
	for(auto it=mp.begin();it!=mp.end();it++){
		int v=it->first,num=it->second;
		int cur=idx&1,pre=!cur;
		for(int mod=0;mod<v;mod++){
			deque<PI> dq;
			for(int w=mod,k=0;w<=n;w+=v,k++){
				dp[cur][w]=min(0x3f3f3f3f,dp[pre][w]);
				while(!dq.empty() && k-dq.front().second>num) dq.pop_front();
				if(!dq.empty()) dp[cur][w]=min(dp[cur][w],dq.front().first+k);
				PI p=PI(dp[pre][w]-k,k);
				while(!dq.empty() && dq.back().first>=p.first) dq.pop_back();
				dq.push_back(p);
			}
		}
		idx++;
	}
	idx--;
	int ans=-1;
	for(int i=1;i<=n;i++){
		if(isLucky(i) && dp[idx&1][i]!=0x3f3f3f3f && (dp[idx&1][i]-1<ans || ans==-1))
			ans=dp[idx&1][i]-1;
	}
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PI;
int par[100010],size[100010];
bool vis[100010];
void init(int n){
	for(int i=1;i<=n;i++)
		par[i]=i,size[i]=1;
}
int find(int x){
	if(par[x]==x) return x;
	return par[x]=find(par[x]);
}
void unite(int x,int y){
	x=find(x),y=find(y);
	if(x==y) return;
	if(size[x]<size[y]) swap(x,y);
	par[y]=x;
	size[x]+=size[y];
}
inline bool isLucky(int x){
	while(x>0){
		if(x%10!=4 && x%10!=7) return false;
		x/=10;
	}
	return true;
}
map<int,int> mp;
int dp[2][100010];
int main(){
	int n,m,u,v;
	scanf("%d%d",&n,&m);
	init(n);
	for(int i=0;i<m;i++){
		scanf("%d%d",&u,&v);
		unite(u,v);
	}
	for(int i=1;i<=n;i++){
		if(!vis[find(i)]){
			vis[find(i)]=true;
			mp[size[find(i)]]++;
		}
	}
	memset(dp[0],0x3f,sizeof dp[0]);
	dp[0][0]=0;
	int idx=1;
	for(auto it=mp.begin();it!=mp.end();it++){
		int v=it->first,num=it->second;
		int cur=idx&1,pre=!cur;
		for(int mod=0;mod<v;mod++){
			deque<PI> dq;
			for(int w=mod,k=0;w<=n;w+=v,k++){
				dp[cur][w]=0x3f3f3f3f;
				while(!dq.empty() && k-dq.front().second>num) dq.pop_front();
				if(!dq.empty()) dp[cur][w]=min(dp[cur][w],dq.front().first+k);
				PI p=PI(dp[pre][w]-k,k);
				while(!dq.empty() && dq.back()<=p) dq.pop_back();
				dq.push_back(p);
			}
		}
		idx++;
	}
	idx--;
	int ans=-1;
	for(int i=1;i<=n;i++){
		if(isLucky(i) && dp[idx&1][i]!=0x3f3f3f3f && (dp[idx&1][i]-1<ans || ans==-1))
			ans=dp[idx&1][i]-1;
	}
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=350,inf=1e9;

int n,m,dp[maxn],amount[maxn],ans=inf;
vector<int> v[maxn];

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,dp[a]);
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    dp[0]=0;
    int *par;
    par=new int(n);
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
        dp[i+1]=inf;
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            vector<int>().swap(v[B]);
        }
    }
    delete[] par;
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
            vector<int>().swap(v[i]);
        }
    }
    rep(v,1,n+1)
    {
        if(amount[v])
        {
            int c=amount[v];
            int pw=1;
            while(c)
            {
                if(c<pw)
                {
                    pw=c;
                }
                c-=pw;
                for(int j=n;j>=pw*v;j--)
                {
                    dp[j]=min(dp[j],dp[j-pw*v]+pw);
                }
                pw*=2;
            }
        }
    }
    lucky_generator(0);
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=400,inf=1e9;

int n,m,par[maxn],dp[sqr][maxn],value[sqr],amount[maxn],dsize,ans=inf;
vector<int> v[maxn];

int solve(int a,int b)
{
    if(!b) return 0;
    if(a<0) return inf;
    if(dp[a][b])
    {
        return dp[a][b];
    }
    dp[a][b]=inf;
    int v=value[a];
    rep(i,0,amount[v]+1)
    {
        if(b>=i*v)
        {
            int s=solve(a-1,b-i*v);
            if(s!=inf)
                dp[a][b]=min(dp[a][b],s+i);
        }
    }
    return dp[a][b];
}

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,solve(dsize-1,a));
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            v[B].clear();
        }
    }
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
        }
    }
    rep(i,1,n+1)
    {
        if(amount[i])
        {
            value[dsize++]=i;
        }
    }
    lucky_generator(0);
    if(ans>=inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=400,inf=1e9;

int n,m,par[maxn],dp[maxn],value[sqr],amount[maxn],dsize,ans=inf;
vector<int> v[maxn];

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,dp[a]);
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    dp[0]=0;
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
        dp[i+1]=inf;
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            v[B].clear();
        }
    }
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
        }
    }
    rep(i,1,n+1)
    {
        if(amount[i])
        {
            value[dsize++]=i;
        }
    }
    rep(i,0,dsize)
    {
        int v=value[i];
        int c=amount[v];
        int pw=1;
        while(c)
        {
            if(c<pw)
            {
                pw=c;
            }
            c-=pw;
            for(int j=n;j>=pw*v;j--)
            {
                dp[j]=min(dp[j],dp[j-pw*v]+pw);
            }
            pw*=2;
        }
    }
    lucky_generator(0);
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=400,inf=1e9;

int n,m,par[maxn],dp[maxn],value[sqr],amount[maxn],dsize,ans=inf;
vector<int> v[maxn];

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,dp[a]);
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    dp[0]=0;
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
        dp[i+1]=inf;
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            v[B].clear();
        }
    }
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
            vector<int>().swap(v[i]);
        }
    }
    rep(i,1,n+1)
    {
        if(amount[i])
        {
            value[dsize++]=i;
        }
    }
    rep(i,0,dsize)
    {
        int v=value[i];
        int c=amount[v];
        int pw=1;
        while(c)
        {
            if(c<pw)
            {
                pw=c;
            }
            c-=pw;
            for(int j=n;j>=pw*v;j--)
            {
                dp[j]=min(dp[j],dp[j-pw*v]+pw);
            }
            pw*=2;
        }
    }
    lucky_generator(0);
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=350,inf=1e9;

int n,m,dp[maxn],amount[maxn],ans=inf;
vector<int> v[maxn];

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,dp[a]);
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    dp[0]=0;
    int *par;
    par=new int[n];
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
        dp[i+1]=inf;
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        a--,b--;
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            vector<int>().swap(v[B]);
        }
    }
    delete[] par;
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
            vector<int>().swap(v[i]);
        }
    }
    rep(v,1,n+1)
    {
        if(amount[v])
        {
            int c=amount[v];
            int pw=1;
            while(c)
            {
                if(c<pw)
                {
                    pw=c;
                }
                c-=pw;
                for(int j=n;j>=pw*v;j--)
                {
                    dp[j]=min(dp[j],dp[j-pw*v]+pw);
                }
                pw*=2;
            }
        }
    }
    lucky_generator(0);
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=400,inf=1e9;

int n,m,par[maxn],dp[maxn],value[sqr],amount[maxn],dsize,ans=inf;
vector<int> v[maxn];

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,dp[a]);
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    dp[0]=0;
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
        dp[i+1]=inf;
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            v[B].clear();
        }
    }
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
            v[i].clear();
        }
    }
    rep(i,1,n+1)
    {
        if(amount[i])
        {
            value[dsize++]=i;
        }
    }
    rep(i,0,dsize)
    {
        int v=value[i];
        int c=amount[v];
        int pw=1;
        while(c)
        {
            if(c<pw)
            {
                pw=c;
            }
            c-=pw;
            for(int j=n;j>=pw*v;j--)
            {
                dp[j]=min(dp[j],dp[j-pw*v]+pw);
            }
            pw*=2;
        }
    }
    lucky_generator(0);
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=350,inf=1e9;

int n,m,dp[maxn],amount[maxn],ans=inf;
vector<int> v[maxn];
bool mark[maxn];

int dfs(int a)
{
    mark[a]=1;
    int sum=1;
    rep(i,0,v[a].size())
    {
        if(!mark[v[a][i]])
        {
            sum+=dfs(v[a][i]);
        }
    }
    return sum;
}

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,dp[a]);
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    dp[0]=0;
    rep(i,0,n)
    {
        dp[i+1]=inf;
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        a--,b--;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    rep(i,0,n)
    {
        if(!mark[i])
        {
            amount[dfs(i)]++;
        }
    }
    rep(v,1,n+1)
    {
        if(amount[v])
        {
            int c=amount[v];
            int pw=1;
            while(c)
            {
                if(c<pw)
                {
                    pw=c;
                }
                c-=pw;
                for(int j=n;j>=pw*v;j--)
                {
                    dp[j]=min(dp[j],dp[j-pw*v]+pw);
                }
                pw*=2;
            }
        }
    }
    lucky_generator(0);
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=400,inf=1e9;

int n,m,par[maxn],dp[sqr][maxn],value[sqr],amount[maxn],dsize,ans=inf;
vector<int> v[maxn];

int solve(int a,int b)
{
    if(!b) return 0;
    if(a<0) return inf;
    if(dp[a][b]!=-1)
    {
        return dp[a][b];
    }
    dp[a][b]=inf;
    int v=value[a];
    rep(i,0,amount[v]+1)
    {
        if(b>=i*v)
        {
            int s=solve(a-1,b-i*v);
            if(s!=inf)
                dp[a][b]=min(dp[a][b],s+i);
        }
    }
    return dp[a][b];
}

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,solve(dsize-1,a));
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    cin>>n>>m;
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
        rep(j,0,sqr)
        {
            dp[j][i+1]=-1;
        }
    }
    rep(i,0,m)
    {
        int a,b;
        cin>>a>>b;
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            v[B].clear();
        }
    }
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
        }
    }
    rep(i,1,n+1)
    {
        if(amount[i])
        {
            value[dsize++]=i;
        }
    }
    lucky_generator(0);
    if(ans>=inf) cout<<-1<<endl;
    else cout<<ans-1<<endl;
}


#include <bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cout<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define push push_back
#define pop pop_back
#define make make_pair
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=1e5+10,sqr=350,inf=1e9;

int n,m,dp[maxn],amount[maxn],ans=inf;
vector<int> v[maxn];

void lucky_generator(int a)
{
    if(a>n) return;
    if(a) ans=min(ans,dp[a]);
    lucky_generator(a*10+4);
    lucky_generator(a*10+7);
}

int main()
{
    scanf("%d %d",&n,&m);
    dp[0]=0;
    int *par;
    par=new int[n];
    rep(i,0,n)
    {
        par[i]=i;
        v[i].push_back(i);
        dp[i+1]=inf;
    }
    rep(i,0,m)
    {
        int a,b;
        scanf("%d %d",&a,&b);
        if(par[a]!=par[b])
        {
            int A=par[a],B=par[b];
            if(v[A]<v[B]) swap(A,B);
            rep(i,0,v[B].size())
            {
                par[v[B][i]]=A;
                v[A].push_back(v[B][i]);
            }
            vector<int>().swap(v[B]);
        }
    }
    delete[] par;
    rep(i,0,n)
    {
        if(v[i].size())
        {
            amount[v[i].size()]++;
            vector<int>().swap(v[i]);
        }
    }
    rep(v,1,n+1)
    {
        if(amount[v])
        {
            int c=amount[v];
            int pw=1;
            while(c)
            {
                if(c<pw)
                {
                    pw=c;
                }
                c-=pw;
                for(int j=n;j>=pw*v;j--)
                {
                    dp[j]=min(dp[j],dp[j-pw*v]+pw);
                }
                pw*=2;
            }
        }
    }
    lucky_generator(0);
    if(ans==inf) printf("-1\n");
    else printf("%d\n",ans-1);
}


#include <bits/stdc++.h>
#define MOD 1000000009
#define Nmax 1000005
#define pb push_back
#define mp make_pair
#define INF 1000000000
#define eps 0.000000000001

using namespace std;

int n,cnt;
int nr[Nmax],dp[Nmax],dp1[Nmax];
bool viz[Nmax];
vector <int> L[Nmax];
vector < pair<int,int> > Vec;

inline bool Lucky(int x)
{
    while(x)
    {
        if(x%10!=4 && x%10!=7) return false;
        x/=10;
    }
    return true;
}

inline void Dfs(int nod)
{
    viz[nod]=1; ++cnt;
    for(auto it : L[nod])
    {
        if(viz[it]) continue;
        Dfs(it);
    }
}

inline void Add(int val, int cnt)
{
    int i;
    for(i=0;i<20;++i)
        if((cnt&(1<<i)))
            Vec.pb(mp((1<<i) , (1<<i)*val));
}

inline void Dp()
{
    int i;
    for(i=1;i<=n;++i) dp[i]=INF;
    for(auto it : Vec)
    {
        for(i=1;i<=n;++i) dp1[i]=dp[i];
        for(i=1;i<=n;++i)
            if(i>=it.second) dp[i]=min(dp[i],dp1[i-it.second]+it.first);
    }
}

int main()
{
    int i,j,x,y,sol=INF,m;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin.sync_with_stdio(0);
    cin>>n>>m;
    while(m--)
    {
        cin>>x>>y;
        L[x].pb(y); L[y].pb(x);
    }
    for(i=1;i<=n;++i)
    {
        if(viz[i]) continue;
        cnt=0; Dfs(i);
        ++nr[cnt];
    }
    for(i=1;i<=n;++i) Add(i,nr[i]);
    Dp();
    for(i=1;i<=n;++i)
        if(Lucky(i)) sol=min(sol,dp[i]-1);
    if(sol>=INF-1) cout<<"-1\n";
    else cout<<sol;
    return 0;
}


#include <bits/stdc++.h>
#define MOD 1000000009
#define Nmax 1000005
#define pb push_back
#define mp make_pair
#define INF 1000000000
#define eps 0.000000000001

using namespace std;

int n,cnt;
int nr[Nmax],dp[Nmax],dp1[Nmax];
bool viz[Nmax];
vector <int> L[Nmax];
vector < pair<int,int> > Vec;

inline bool Lucky(int x)
{
    while(x)
    {
        if(x%10!=4 && x%10!=7) return false;
        x/=10;
    }
    return true;
}

inline void Dfs(int nod)
{
    viz[nod]=1; ++cnt;
    for(auto it : L[nod])
    {
        if(viz[it]) continue;
        Dfs(it);
    }
}

inline void Add(int val, int cnt)
{
    int i;
    for(i=0;i<20;++i)
    {
        if((1<<i)>cnt) continue;
        cnt-=(1<<i);
        Vec.pb(mp((1<<i) , (1<<i)*val));
    }
}

inline void Dp()
{
    int i;
    for(i=1;i<=n;++i) dp[i]=INF;
    for(auto it : Vec)
    {
        //cout<<it.first<<" "<<it.second<<"\n";
        for(i=1;i<=n;++i) dp1[i]=dp[i];
        for(i=1;i<=n;++i)
            if(i>=it.second) dp[i]=min(dp[i],dp1[i-it.second]+it.first);
    }
}

int main()
{
    int i,j,x,y,sol=INF,m;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin.sync_with_stdio(0);
    cin>>n>>m;
    while(m--)
    {
        cin>>x>>y;
        L[x].pb(y); L[y].pb(x);
    }
    for(i=1;i<=n;++i)
    {
        if(viz[i]) continue;
        cnt=0; Dfs(i);
        ++nr[cnt];
    }
    for(i=1;i<=n;++i) Add(i,nr[i]);
    Dp();
    for(i=1;i<=n;++i)
        if(Lucky(i)) sol=min(sol,dp[i]-1);
    if(sol>=INF-1) cout<<"-1\n";
    else cout<<sol;
    return 0;
}


#include <bits/stdc++.h>
#define MOD 1000000009
#define Nmax 1000005
#define pb push_back
#define mp make_pair
#define INF 1000000000
#define eps 0.000000000001

using namespace std;

int n,cnt;
int nr[Nmax],dp[Nmax],dp1[Nmax];
bool viz[Nmax];
vector <int> L[Nmax];
vector < pair<int,int> > Vec;

inline bool Lucky(int x)
{
    while(x)
    {
        if(x%10!=4 && x%10!=7) return false;
        x/=10;
    }
    return true;
}

inline void Dfs(int nod)
{
    viz[nod]=1; ++cnt;
    for(auto it : L[nod])
    {
        if(viz[it]) continue;
        Dfs(it);
    }
}

inline void Add(int val, int cnt)
{
    int i;
    for(i=0;i<20;++i)
    {
        if((1<<i)>cnt) continue;
        cnt-=(1<<i);
        Vec.pb(mp((1<<i) , (1<<i)*val));
    }
    if(cnt) Vec.pb(mp(cnt , cnt*val));
}

inline void Dp()
{
    int i;
    for(i=1;i<=n;++i) dp[i]=INF;
    for(auto it : Vec)
    {
        //cout<<it.first<<" "<<it.second<<"\n";
        for(i=1;i<=n;++i) dp1[i]=dp[i];
        for(i=1;i<=n;++i)
            if(i>=it.second) dp[i]=min(dp[i],dp1[i-it.second]+it.first);
    }
}

int main()
{
    int i,j,x,y,sol=INF,m;
    #ifndef ONLINE_JUDGE
        freopen ("date.in","r",stdin);
        freopen ("date.out","w",stdout);
    #endif
    cin.sync_with_stdio(0);
    cin>>n>>m;
    while(m--)
    {
        cin>>x>>y;
        L[x].pb(y); L[y].pb(x);
    }
    for(i=1;i<=n;++i)
    {
        if(viz[i]) continue;
        cnt=0; Dfs(i);
        ++nr[cnt];
    }
    for(i=1;i<=n;++i) Add(i,nr[i]);
    Dp();
    for(i=1;i<=n;++i)
        if(Lucky(i)) sol=min(sol,dp[i]-1);
    if(sol>=INF-1) cout<<"-1\n";
    else cout<<sol;
    return 0;
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=1e5+5;
int d[maxm];
//
int v[maxm],num;
int w[maxm];
//
int pre[maxm];
int cnt[maxm];
int n,m;
int ffind(int x){
    return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
int luck(int x){
    while(x){
        if(x%10!=4&&x%10!=7)return 0;
        x/=10;
    }
    return 1;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)pre[i]=i,cnt[i]=1;
    for(int i=1;i<=m;i++){
        int a,b;cin>>a>>b;
        int x=ffind(a),y=ffind(b);
        if(x!=y){
            pre[x]=y;
            cnt[y]+=cnt[x];
        }
    }
    map<int,int>mark;
    for(int i=1;i<=n;i++){
        if(pre[i]==i){
            mark[cnt[i]]++;
        }
    }
    if(mark.size()==1){
        if(luck(n)){
            cout<<0<<endl;;
        }else{
            cout<<-1<<endl;
        }
        return 0;
    }
    for(auto i:mark){
        int p=1;
        while(i.second>=p){
            num++;
            v[num]=p*i.first;
            w[num]=p;
            i.second-=p;
            p*=2;
        }
        if(i.second){
            num++;
            v[num]=i.second*i.first;
            w[num]=i.second;
        }
    }
    for(int i=1;i<maxm;i++){
        d[i]=1e9;
    }
    d[0]=0;
    for(int i=1;i<=num;i++){
        for(int j=7777;j>=v[i];j--){
            d[j]=min(d[j],d[j-v[i]]+w[i]);
        }
    }
    int ans=1e9;
    for(int i=4;i<=7777;i++){
        if(luck(i)){
            ans=min(ans,d[i]);
        }
    }
    if(ans==1e9)cout<<-1<<endl;
    else cout<<ans-1<<endl;
    return 0;
}
/*

*/


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=1e5+5;
int d[maxm];
//
int v[maxm],num;
int w[maxm];
//
int pre[maxm];
int cnt[maxm];
int n,m;
int ffind(int x){
    return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
int luck(int x){
    while(x){
        if(x%10!=4&&x%10!=7)return 0;
        x/=10;
    }
    return 1;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)pre[i]=i,cnt[i]=1;
    for(int i=1;i<=m;i++){
        int a,b;cin>>a>>b;
        int x=ffind(a),y=ffind(b);
        if(x!=y){
            pre[x]=y;
            cnt[y]+=cnt[x];
        }
    }
    map<int,int>mark;
    for(int i=1;i<=n;i++){
        if(pre[i]==i){
            mark[cnt[i]]++;
        }
    }
    for(auto i:mark){
        int p=1;
        while(i.second>=p){
            num++;
            v[num]=p*i.first;
            w[num]=p;
            i.second-=p;
            p*=2;
        }
        if(i.second){
            num++;
            v[num]=i.second*i.first;
            w[num]=i.second;
        }
    }
    for(int i=1;i<maxm;i++){
        d[i]=1e9;
    }
    d[0]=0;
    for(int i=1;i<=num;i++){
        for(int j=maxm;j>=v[i];j--){
            d[j]=min(d[j],d[j-v[i]]+w[i]);
        }
    }
    int ans=1e9;
    for(int i=1;i<maxm;i++){
        if(luck(i)){
            ans=min(ans,d[i]);
        }
    }
    if(ans==1e9)cout<<-1<<endl;
    else cout<<ans-1<<endl;
    return 0;
}
/*

*/


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=1e5+5;
int d[maxm];
//
int v[maxm],num;
int w[maxm];
//
int pre[maxm];
int cnt[maxm];
int n,m;
int ffind(int x){
    return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
int luck(int x){
    while(x){
        if(x%10!=4&&x%10!=7)return 0;
        x/=10;
    }
    return 1;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)pre[i]=i,cnt[i]=1;
    for(int i=1;i<=m;i++){
        int a,b;cin>>a>>b;
        int x=ffind(a),y=ffind(b);
        if(x!=y){
            pre[x]=y;
            cnt[y]+=cnt[x];
        }
    }
    map<int,int>mark;
    for(int i=1;i<=n;i++){
        if(pre[i]==i){
            mark[cnt[i]]++;
        }
    }
    for(auto i:mark){
        int p=1;
        while(i.second>=p){
            num++;
            v[num]=p*i.first;
            w[num]=p;
            i.second-=p;
            p*=2;
        }
        if(i.second){
            num++;
            v[num]=i.second*i.first;
            w[num]=i.second;
        }
    }
    for(int i=1;i<maxm;i++){
        d[i]=1e9;
    }
    d[0]=0;
    for(int i=1;i<=num;i++){
        for(int j=7777;j>=v[i];j--){
            d[j]=min(d[j],d[j-v[i]]+w[i]);
        }
    }
    int ans=1e9;
    for(int i=4;i<=7777;i++){
        if(luck(i)){
            ans=min(ans,d[i]);
        }
    }
    if(ans==1e9)cout<<-1<<endl;
    else cout<<ans-1<<endl;
    return 0;
}
/*

*/


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int MX = 77778;
int parent[N];
int sizes[N];
int n , m;
int a , b;
int dp[MX];
vector < pair < int , int > > v[N + N];
int find(int node){
    if(parent[node] == node){
        return node;
    }
    return parent[node] = find(parent[node]);
}
bool lucky(int num){
    while(num){
        if((num % 10) != 4 && (num % 10) != 7){
            return 0;
        }
        num /= 10;
    }
    return 1;
}
vector < pair < int , int > > arr;
int main(){
    scanf("%d %d" , &n , &m);
    for(int i = 1 ; i <= n ; ++i){
        parent[i] = i;
        sizes[i] = 1;
    }
    for(int i = 1 ; i <= m ; ++i){
        scanf("%d %d" , &a , &b);
        if(find(a) != find(b)){
            sizes[find(a)] += sizes[find(b)];
            parent[find(b)] = find(a);
        }
    }
    for(int i = 1 ; i <= n ; ++i){
        if(find(i) == i){
            v[sizes[i]].emplace_back(make_pair(1 , 0));
        }
    }
    for(int i = 1 ; i < MX ; ++i){
        if(!v[i].empty()){
            sort(v[i].begin() , v[i].end());
            vector < pair < int , int > > tmp;
            tmp.clear();
            for(auto it : v[i]){
                if(!tmp.empty() && tmp.back() == it){
                    tmp.back().first += it.first;
                }
                else{
                    tmp.emplace_back(it);
                }
            }
            for(auto it : tmp){
                if(it.first > 2){
                    int cnt = it.first - 1 >> 1;
                    v[i + i].emplace_back(make_pair(cnt , it.second * 2 + 1));
                    it.first -= cnt * 2;
                }
                while(it.first--){
                    arr.emplace_back(make_pair(i , it.second));
                }
            }
        }
    }
    dp[0] = 0;
    for(int i = 1 ; i < MX ; ++i){
        dp[i] = N;
    }
    for(auto it : arr){
        for(int i = MX - 1 ; i >= it.first ; --i){
            dp[i] = min(dp[i] , dp[i - it.first] + it.second + 1);
        }
    }
    int ans = N;
    for(int i = 1 ; i < MX ; ++i){
        if(lucky(i)){
            ans = min(ans , dp[i]);
        }
    }
    ans %= N;
    printf("%d\n" , ans - 1);
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int MX = 77778;
int parent[N];
int sizes[N];
int n , m;
int a , b;
int dp[MX];
vector < pair < int , int > > v[N + N];
int find(int node){
    if(parent[node] == node){
        return node;
    }
    return parent[node] = find(parent[node]);
}
bool lucky(int num){
    while(num){
        if((num % 10) != 4 && (num % 10) != 7){
            return 0;
        }
        num /= 10;
    }
    return 1;
}
vector < pair < int , int > > arr;
int main(){
    scanf("%d %d" , &n , &m);
    for(int i = 1 ; i <= n ; ++i){
        parent[i] = i;
        sizes[i] = 1;
    }
    for(int i = 1 ; i <= m ; ++i){
        scanf("%d %d" , &a , &b);
        if(find(a) != find(b)){
            sizes[find(a)] += sizes[find(b)];
            parent[find(b)] = find(a);
        }
    }
    for(int i = 1 ; i <= n ; ++i){
        if(find(i) == i){
            v[sizes[i]].emplace_back(make_pair(1 , 0));
        }
    }
    for(int i = 1 ; i < MX ; ++i){
        if(!v[i].empty()){
            sort(v[i].begin() , v[i].end());
            vector < pair < int , int > > tmp;
            tmp.clear();
            for(auto it : v[i]){
                if(!tmp.empty() && tmp.back() == it){
                    tmp.back().first += it.first;
                }
                else{
                    tmp.emplace_back(it);
                }
            }
            for(auto it : tmp){
                if(it.first > 2){
                    int cnt = it.first - 1 >> 1;
                    v[i + i].emplace_back(make_pair(cnt , it.second * 2 + 1));
                    it.first -= cnt * 2;
                }
                while(it.first--){
                    arr.emplace_back(make_pair(i , it.second));
                }
            }
        }
    }
    dp[0] = 0;
    for(int i = 1 ; i < MX ; ++i){
        dp[i] = N;
    }
    assert(arr.size() <= 1000);
    for(auto it : arr){
        for(int i = MX - 1 ; i >= it.first ; --i){
            dp[i] = min(dp[i] , dp[i - it.first] + it.second + 1);
        }
    }
    int ans = N;
    for(int i = 1 ; i < MX ; ++i){
        if(lucky(i)){
            ans = min(ans , dp[i]);
        }
    }
    ans %= N;
    printf("%d\n" , ans - 1);
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int MX = 77778;
int parent[N];
int sizes[N];
int n , m;
int a , b;
int dp[MX];
vector < pair < int , int > > v[N + N];
int find(int node){
    if(parent[node] == node){
        return node;
    }
    return parent[node] = find(parent[node]);
}
bool lucky(int num){
    while(num){
        if((num % 10) != 4 && (num % 10) != 7){
            return 0;
        }
        num /= 10;
    }
    return 1;
}
vector < pair < int , int > > arr;
int main(){
    scanf("%d %d" , &n , &m);
    for(int i = 1 ; i <= n ; ++i){
        parent[i] = i;
        sizes[i] = 1;
    }
    for(int i = 1 ; i <= m ; ++i){
        scanf("%d %d" , &a , &b);
        if(find(a) != find(b)){
            sizes[find(a)] += sizes[find(b)];
            parent[find(b)] = find(a);
        }
    }
    for(int i = 1 ; i <= n ; ++i){
        if(find(i) == i){
            v[sizes[i]].emplace_back(make_pair(0 , 1));
        }
    }
    for(int i = 1 ; i < MX ; ++i){
        if(!v[i].empty()){
            sort(v[i].begin() , v[i].end());
            vector < pair < int , int > > tmp;
            tmp.clear();
            for(auto it : v[i]){
                if(!tmp.empty() && tmp.back().first == it.first){
                    tmp.back().second += it.second;
                }
                else{
                    tmp.emplace_back(it);
                }
            }
            for(auto it : tmp){
                if(it.second > 2){
                    int cnt = it.second - 1 >> 1;
                    v[i + i].emplace_back(make_pair(it.first * 2 + 1 , cnt));
                    it.second -= cnt * 2;
                }
                while(it.second--){
                    arr.emplace_back(make_pair(i , it.second));
                }
            }
        }
    }
    dp[0] = 0;
    for(int i = 1 ; i < MX ; ++i){
        dp[i] = N;
    }
    for(auto it : arr){
        for(int i = MX - 1 ; i >= it.first ; --i){
            dp[i] = min(dp[i] , dp[i - it.first] + it.second + 1);
        }
    }
    int ans = N;
    for(int i = 1 ; i < MX ; ++i){
        if(lucky(i)){
            ans = min(ans , dp[i]);
        }
    }
    ans %= N;
    printf("%d\n" , ans - 1);
}


#include "bits/stdc++.h"
using namespace std;
const int N = 1e5 + 5;
const int MX = 77778;
int parent[N];
int sizes[N];
int n , m;
int a , b;
int dp[MX];
vector < pair < int , int > > v[N + N];
int find(int node){
    if(parent[node] == node){
        return node;
    }
    return parent[node] = find(parent[node]);
}
bool lucky(int num){
    while(num){
        if((num % 10) != 4 && (num % 10) != 7){
            return 0;
        }
        num /= 10;
    }
    return 1;
}
vector < pair < int , int > > arr;
int main(){
    scanf("%d %d" , &n , &m);
    for(int i = 1 ; i <= n ; ++i){
        parent[i] = i;
        sizes[i] = 1;
    }
    for(int i = 1 ; i <= m ; ++i){
        scanf("%d %d" , &a , &b);
        if(find(a) != find(b)){
            sizes[find(a)] += sizes[find(b)];
            parent[find(b)] = find(a);
        }
    }
    for(int i = 1 ; i <= n ; ++i){
        if(find(i) == i){
            v[sizes[i]].emplace_back(make_pair(0 , 1));
        }
    }
    for(int i = 1 ; i < MX ; ++i){
        if(!v[i].empty()){
            sort(v[i].begin() , v[i].end());
            vector < pair < int , int > > tmp;
            tmp.clear();
            for(auto it : v[i]){
                if(!tmp.empty() && tmp.back().first == it.first){
                    tmp.back().second += it.second;
                }
                else{
                    tmp.emplace_back(it);
                }
            }
            for(auto it : tmp){
                if(it.second > 2){
                    int cnt = it.second - 1 >> 1;
                    v[i + i].emplace_back(make_pair(it.first * 2 + 1 , cnt));
                    it.second -= cnt * 2;
                }
                while(it.second--){
                    arr.emplace_back(make_pair(i , it.first));
                }
            }
        }
    }
    dp[0] = 0;
    for(int i = 1 ; i < MX ; ++i){
        dp[i] = N;
    }
    for(auto it : arr){
        for(int i = MX - 1 ; i >= it.first ; --i){
            dp[i] = min(dp[i] , dp[i - it.first] + it.second + 1);
        }
    }
    int ans = N;
    for(int i = 1 ; i < MX ; ++i){
        if(lucky(i)){
            ans = min(ans , dp[i]);
        }
    }
    ans %= N;
    printf("%d\n" , ans - 1);
}


/*
problem's name:
statue:
writer:Chris
*/
#include <iostream>
#include <map>
#include <vector>
#include <cstring>
#include <utility>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <string>
#include <stack>
#include <set>
#include <deque>
#include <cctype>
#include <sstream>
#include <math.h>
#include <stdio.h>
#include <time.h>
#define mp make_pair
typedef long long ll;
using namespace std;
const int INF=1e9;
/*------------main part------------*/

vector<int> edg[100005];
int n,m;
bool vis[100005];
vector<int> num;
int cnt=0;
int dp[100005];
map<int,int> tim;
bool lucky(int x)
{
    if(x%10!=4 and x%10!=7)
	{
		return false;
	}
    if(x<10)
	{
		return true;
	}
    return lucky(x/10);
}
void dfs(int x)
{
	if(vis[x])
		return;
	cnt++;
	vis[x]=true;
	for(int i=0;i<edg[x].size();i++)
	{
		dfs(edg[x][i]);
	}
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		edg[a].push_back(b);
		edg[b].push_back(a);
	}
	for(int i=1;i<=n;i++)
	{
		cnt=0;
		if(!vis[i])
		{
			dfs(i);
			num.push_back(cnt);
		}
	}
	for(int i=0;i<num.size();i++)
	{
		tim[num[i]]++;
	}
	for(int i=0;i<=n;i++)
	{
		dp[i]=INF;
	}
	dp[0]=0;
	for(map<int,int>::iterator it=tim.begin();it!=tim.end();it++)
	{
		int a=it->first;
		int b=it->second;
		while(b>0)
		{
			for(int i=n;i>=(b+1)/2*a;i--)
			{
				dp[i]=min(dp[i],dp[i-a*(b+1)/2]+(b+1)/2);
			}
			b/=2;
		}
	}
	int ans=INF;
	for(int i=0;i<=n;i++)
	{
		if(lucky(i))
		{
			ans=min(ans,dp[i]);
		}
	}
	if(ans==INF)
	{
		cout<<-1;
	}
	else
	{
		cout<<ans-1;
	}
	return 0;
}


/*
problem's name:
statue:
writer:Chris
*/
#include <iostream>
#include <map>
#include <vector>
#include <cstring>
#include <utility>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <string>
#include <stack>
#include <set>
#include <deque>
#include <cctype>
#include <sstream>
#include <math.h>
#include <stdio.h>
#include <time.h>
#define mp make_pair
typedef long long ll;
using namespace std;
const int INF=1e9;
/*------------main part------------*/

vector<int> edg[100005];
int n,m;
bool vis[100005];
vector<int> num;
int cnt=0;
int dp[100005];
map<int,int> tim;
bool lucky(int x)
{
    if(x%10!=4 and x%10!=7)
	{
		return false;
	}
    if(x<10)
	{
		return true;
	}
    return lucky(x/10);
}
void dfs(int x)
{
	if(vis[x])
		return;
	cnt++;
	vis[x]=true;
	for(int i=0;i<edg[x].size();i++)
	{
		dfs(edg[x][i]);
	}
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		edg[a].push_back(b);
		edg[b].push_back(a);
	}
	for(int i=1;i<=n;i++)
	{
		cnt=0;
		if(!vis[i])
		{
			dfs(i);
			num.push_back(cnt);
		}
	}
	for(int i=0;i<num.size();i++)
	{
		tim[num[i]]++;
	}
	for(int i=0;i<=n;i++)
	{
		dp[i]=INF;
	}
	dp[0]=0;
	for(map<int,int>::iterator it=tim.begin();it!=tim.end();it++)
	{
		int a=it->first;
		int b=it->second;
		while(b>0)
		{
			int tmp=(b+1)/2;
			for(int i=n;i>=tmp*a;i--)
			{
				dp[i]=min(dp[i],dp[i-(a*tmp)]+tmp);
			}
			b/=2;
		}
	}
	int ans=INF;
	for(int i=0;i<=n+1;i++)
	{
		if(lucky(i))
		{
			ans=min(ans,dp[i]);
		}
	}
	if(ans==INF)
	{
		cout<<-1;
	}
	else
	{
		cout<<ans-1;
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<deque>
#include<utility>
#include<cctype>
#include<bitset>
#include<stdio.h>
#include<time.h>
#define ll long long
#define mp make_pair
using namespace std;
const int INF=1e9;
/*--------main part---------*/

vector<int> edg[100005];
int n,m;
bool vis[100005];
vector<int> num;
int cnt=0;
int dp[100005];
map<int,int> tim;
bool lucky(int x)
{
    if(x%10!=4 and x%10!=7)
	{
		return false;
	}
    if(x<10)
	{
		return true;
	}
    return lucky(x/10);
}
void dfs(int x)
{
	if(vis[x])
		return;
	cnt++;
	vis[x]=true;
	for(int i=0;i<edg[x].size();i++)
	{
		dfs(edg[x][i]);
	}
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		edg[a].push_back(b);
		edg[b].push_back(a);
	}
	for(int i=1;i<=n;i++)
	{
		cnt=0;
		if(!vis[i])
		{
			dfs(i);
			num.push_back(cnt);
		}
	}
	for(int i=0;i<num.size();i++)
	{
		tim[num[i]]++;
	}
	for(int i=0;i<=n;i++)
	{
		dp[i]=INF;
	}
	dp[0]=0;
	for(map<int,int>::iterator it=tim.begin();it!=tim.end();it++)
	{
		int a=it->first;
		int b=it->second;
		while(b>0)
		{
			int tmp=(b+1)/2;
			for(int i=n;i>=tmp*a;i--)
			{
				dp[i]=min(dp[i],dp[i-(a*tmp)]+tmp);
			}
			b/=2;
		}
	}
	int ans=INF;
	for(int i=0;i<=n+1;i++)
	{
		if(lucky(i))
		{
			ans=min(ans,dp[i]);
		}
	}
	if(ans==INF)
	{
		cout<<-1;
	}
	else
	{
		cout<<ans-1;
	}
	return 0;
}


/*
problem's name:
statue:
writer:Chris
*/
#include <iostream>
#include <map>
#include <vector>
#include <cstring>
#include <utility>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <string>
#include <stack>
#include <set>
#include <deque>
#include <cctype>
#include <sstream>
#include <math.h>
#include <stdio.h>
#include <time.h>
#define mp make_pair
typedef long long ll;
using namespace std;
const int INF=1e9;
/*------------main part------------*/

vector<int> edg[100005];
int n,m;
bool vis[10005];
vector<int> num;
int cnt=0;
int dp[10005];
map<int,int> tim;
bool lucky(int x)
{
    if(x%10!=4 and x%10!=7)
	{
		return false;
	}
    if(x<10)
	{
		return true;
	}
    return lucky(x/10);
}
void dfs(int x)
{
	if(vis[x])
		return;
	cnt++;
	vis[x]=true;
	for(int i=0;i<edg[x].size();i++)
	{
		dfs(edg[x][i]);
	}
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		edg[a].push_back(b);
		edg[b].push_back(a);
	}
	for(int i=1;i<=n;i++)
	{
		cnt=0;
		if(!vis[i])
		{
			dfs(i);
			num.push_back(cnt);
		}
	}
	for(int i=0;i<num.size();i++)
	{
		tim[num[i]]++;
	}
	for(int i=0;i<=n;i++)
	{
		dp[i]=INF;
	}
	dp[0]=0;
	for(map<int,int>::iterator it=tim.begin();it!=tim.end();it++)
	{
		int a=it->first;
		int b=it->second;
		while(b>0)
		{
			for(int i=n;i>=(b+1)/2*a;i--)
			{
				dp[i]=min(dp[i],dp[i-a*(b+1)/2]+(b+1)/2);
			}
			b/=2;
		}
	}
	int ans=INF;
	for(int i=0;i<=n;i++)
	{
		if(lucky(i))
		{
			ans=min(ans,dp[i]);
		}
	}
	if(ans==INF)
	{
		cout<<-1;
	}
	else
	{
		cout<<ans-1;
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define ll long long int
#define pii pair<int,int>
#define mod 1000000007
#define N (int)(2e5+10)
#define mp make_pair
#define pb push_back
#define nd second
#define st first
#define endl '\n'
#define inf mod
#define sag (sol|1)
#define sol (root<<1)
#define ort ((bas+son)>>1)

int n,m,k,i,j,x,y,z;
int ata[N],S[N],H[N],A[N];
int dp[N],ans;

int atabul(int x){
	if(ata[x] == x)
		return x;
	return ata[x] = atabul(ata[x]);
}

bool islucky(int x){
	while(x){
		if(!(x%10 == 4 or x%10 == 7))
			return 0;
		x /= 10;
	}
	return 1;
}

int main(){
	cin >> n >> m;

	for(i=1 ; i<=n ; i++){
		ata[i] = i;
		S[i] = 1;
	}

	for(i=1 ; i<=m ; i++){
		cin >> x >> y;
		if(atabul(x) == atabul(y))
			continue;
		S[atabul(x)] += S[atabul(y)];
		ata[atabul(y)] = atabul(x);
	}

	for(i=1 ; i<=n ; i++){
		if(!H[atabul(i)]){
			A[S[atabul(i)]]++;
			H[atabul(i)] = 1;
		}
	}

	memset(dp,5,sizeof dp);

	dp[0] = 0;

	for(i=1 ; i<=n ; i++){

		if(!A[i])
			continue;

		int t = A[i],k=1;

		while(t){
			int p = min(k,t);
			t -= p;
			k *= 2;
			p *= i;
			for(j=n ; j>=p ; j--)
				dp[j] = min(dp[j-p]+1,dp[j]);
		}
	}

	ans = inf;

	for(i=4 ; i<=n ; i++)
		if(dp[i]<=n and islucky(i))
			ans = min(ans,dp[i]);

	if(ans <= n)
		cout << ans-1 << endl;
	else
		cout << -1 << endl;
}


#include<bits/stdc++.h>

using namespace std;

#define ll long long int
#define pii pair<int,int>
#define mod 1000000007
#define N (int)(2e5+10)
#define mp make_pair
#define pb push_back
#define nd second
#define st first
#define endl '\n'
#define inf mod
#define sag (sol|1)
#define sol (root<<1)
#define ort ((bas+son)>>1)

int n,m,k,i,j,x,y,z;
int ata[N],S[N],H[N],A[N];
int dp[N],ans;

int atabul(int x){
	if(ata[x] == x)
		return x;
	return ata[x] = atabul(ata[x]);
}

bool islucky(int x){
	while(x){
		if(!(x%10 == 4 or x%10 == 7))
			return 0;
		x /= 10;
	}
	return 1;
}

int main(){
	cin >> n >> m;

	for(i=1 ; i<=n ; i++){
		ata[i] = i;
		S[i] = 1;
	}

	for(i=1 ; i<=m ; i++){
		scanf("%d %d",&x,&y);
		if(atabul(x) == atabul(y))
			continue;
		S[atabul(x)] += S[atabul(y)];
		ata[atabul(y)] = atabul(x);
	}

	for(i=1 ; i<=n ; i++){
		if(!H[atabul(i)]){
			A[S[atabul(i)]]++;
			H[atabul(i)] = 1;
		}
	}

	memset(dp,5,sizeof dp);

	dp[0] = 0;

	for(i=1 ; i<=n ; i++){

		if(!A[i])
			continue;

		int t = A[i],k=1;

		while(t){
			int p = min(k,t);
			t -= p;
			k *= 2;
			p *= i;
			for(j=n ; j>=p ; j--)
				dp[j] = min(dp[j-p]+p/i,dp[j]);
		}
	}

	ans = inf;

	for(i=4 ; i<=n ; i++)
		if(dp[i]<=n and islucky(i))
			ans = min(ans,dp[i]);

	if(ans <= n)
		cout << ans-1 << endl;
	else
		cout << -1 << endl;
}


#include<bits/stdc++.h>

using namespace std;

#define ll long long int
#define pii pair<int,int>
#define mod 1000000007
#define N (int)(2e5+10)
#define mp make_pair
#define pb push_back
#define nd second
#define st first
#define endl '\n'
#define inf mod
#define sag (sol|1)
#define sol (root<<1)
#define ort ((bas+son)>>1)

int n,m,k,i,j,x,y,z;
int ata[N],S[N],H[N],A[N];
int dp[N],ans;

int atabul(int x){
	if(ata[x] == x)
		return x;
	return ata[x] = atabul(ata[x]);
}

bool islucky(int x){
	while(x){
		if(!(x%10 == 4 or x%10 == 7))
			return 0;
		x /= 10;
	}
	return 1;
}

int main(){
	cin >> n >> m;

	for(i=1 ; i<=n ; i++){
		ata[i] = i;
		S[i] = 1;
	}

	for(i=1 ; i<=m ; i++){
		cin >> x >> y;
		if(atabul(x) == atabul(y))
			continue;
		S[atabul(x)] += S[atabul(y)];
		ata[atabul(y)] = atabul(x);
	}

	for(i=1 ; i<=n ; i++){
		if(!H[atabul(i)]){
			A[S[atabul(i)]]++;
			H[atabul(i)] = 1;
		}
	}

	memset(dp,5,sizeof dp);

	dp[0] = 0;

	for(i=1 ; i<=n ; i++){

		if(!A[i])
			continue;

		int t = A[i],k=1;

		while(t){
			int p = min(k,t);
			t -= p;
			k *= 2;
			p *= i;
			for(j=n ; j>=p ; j--)
				dp[j] = min(dp[j-p]+p/i,dp[j]);
		}
	}

	ans = inf;

	for(i=4 ; i<=n ; i++)
		if(dp[i]<=n and islucky(i))
			ans = min(ans,dp[i]);

	if(ans <= n)
		cout << ans-1 << endl;
	else
		cout << -1 << endl;
}


//Be Name Khoda
//Ahay! Hormat ha hefz she baradare man ...
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T> using ordered_multiset =  tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long ll;
typedef long double ld;
const int MOD = (int)1e9 + 7;
const int MAXN = (int)1e5 + 7;
const int infint = (int)2e9;
const ll inf = (ll)1e18 + 7;
vector<int> G[MAXN], comps[MAXN];
int visited[MAXN];
int rec[MAXN];
int dp[350][MAXN];
int comp = 0;
bool islucky(int a)
{
	while(a)
	{
		if(a % 10 != 4 and a % 10 != 7)
			return false;
		a /= 10;
	}
	return true;
}
void dfs(int u)
{
	visited[u] = 1;
	comps[comp].push_back(u);
	for (auto v : G[u])
		if(!visited[v])
			dfs(v);

}
int fmin(int a, int b)
{
	if(a == -1)
		return b;
	if(b == -1)
		return a;
	return min(a, b);
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	for (int i = 1; i <= n; i++)
		if(!visited[i])
		{
			dfs(i);
			comp++;
		}
	set<int> S;
	for (int i = 0; i < comp; i++)
	{
		rec[comps[i].size()]++;
		S.insert((int)comps[i].size());
	}
	vector<int> v;
	for (auto u : S)
	{
		v.push_back(u);
	}
	for (int i = 0; i <= v.size(); i++)
		for (int j = 0; j <= n; j++)
			dp[i][j] = -1;
	dp[0][0] = 0;
	for (int i = 0; i < v.size(); i++)
	{
		for (int j = 0; j <= n; j++)
		{
			for (int k = 0; k <= rec[v[i]]; k++)
				if(j - k * v[i] >= 0 and dp[i][j - k * v[i]] != -1)
					dp[i + 1][j] = fmin(dp[i + 1][j], dp[i][j - k * v[i]] + k);
		}
	}
	int mn = -1;
	for (int i = 1; i <= n; i++)
		if(islucky(i) and dp[v.size()][i] != -1)
			mn = fmin(mn, dp[v.size()][i]);
	if(mn != -1)
		mn--;
	cout << mn;
}