//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);
	}
	//dp[i][j] = min(dp[i - 1][j - v[i]] + 1, dp[i - 1][j - 2v[i]] + 2, ..., dp[i - 1][j - rec[i] * v[i]] + rec[i]
	vector<pair<int, int> > nw;
	for (auto u : v)
	{
		int c = rec[u], now = 1;
		while(c >= now)
		{
			nw.push_back({u, now});
			c -= now;
			now *= 2;
		}
		if(c)
			nw.push_back({u, c});
	}
	for (int i = 0; i <= nw.size(); i++)
		for (int j = 1; j <= n; j++)
			dp[i][j] = -1;
	dp[0][0] = 0;
	for (int i = 0; i < nw.size(); i++)
	{
		for (int j = 0; j <= n; j++)
			if(j >= nw[i].first)
				dp[i + 1][j] = fmin(dp[i + 1][j], dp[i][j - nw[i].first] + nw[i].second);
	}
	int ans = -1;
	for (int i = 1; i <= n; i++)
		if(islucky(i))
			ans = fmin(ans, dp[nw.size()][i]);
	if(ans != -1)
		ans--;

	cout << ans;
}


//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[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);
	}
	//dp[i][j] = min(dp[i - 1][j - v[i]] + 1, dp[i - 1][j - 2v[i]] + 2, ..., dp[i - 1][j - rec[i] * v[i]] + rec[i]
	vector<pair<int, int> > nw;
	for (auto u : v)
	{
		int c = rec[u], now = 1;
		while(c >= now)
		{
			nw.push_back({now * u, now});
			c -= now;
			now *= 2;
		}
		if(c)
			nw.push_back({c * u, c});
	}
	for (int j = 0; j <= n; j++)
		dp[j] = -1;
	dp[0] = 0;
	for (int i = 0; i < nw.size(); i++)
	{
		int cmp[MAXN];
		for (int j = 0; j <= n; j++)
		{
			cmp[j] = dp[j];
			if(j >= nw[i].first and dp[j - nw[i].first] != -1)
			{
				cmp[j] = fmin(cmp[j], dp[j - nw[i].first] + nw[i].second);
			}
		}
		for (int j = 0; j <= n; j++)
			dp[j] = cmp[j];
	}
	int ans = -1;
	for (int i = 1; i <= n; i++)
		if(islucky(i))
		{
			ans = fmin(ans, dp[i]);
		}
	if(ans != -1)
		ans--;

	cout << ans;
}


//Be Name Khoda
//tan man gar tanhast    dele man ba delhast.
//doostani daram      behtar az barge derakht
//ke doayam guyand    va doashan guyam.
#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 + 3;
const ll inf = (ll)1e18;
const int infint = (int)1e9;
struct seg{
	int l, r;
};
struct edge{
	int u, v;
	seg Q;
};
vector < pair<int, seg> > G[MAXN];
int c[MAXN], parent[MAXN], subtree[MAXN]; //c[i] is number of pairs of vertices such that edge between i and his parent is in this path ...
edge e[MAXN];
int dfs(int u, int par)
{
	parent[u] = par;
	int ans = 0;
	for (auto v : G[u])
		if(v.first != par)
			ans += dfs(v.first, u);
	return subtree[u] = ans + 1;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int n, k;
	cin >> n >> k;
	for (int i = 0; i < n - 1; i++)
	{
		int u, v;
		seg C;
		cin >> u >> v >> C.l >> C.r;
		G[u].push_back({v, C});
		G[v].push_back({u, C});
		e[i].u = u, e[i].v = v, e[i].Q = C;
	}
	dfs(1, -1);

}


//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);
	}
	//dp[i][j] = min(dp[i - 1][j - v[i]] + 1, dp[i - 1][j - 2v[i]] + 2, ..., dp[i - 1][j - rec[i] * v[i]] + rec[i]
	vector<pair<int, int> > nw;
	for (auto u : v)
	{
		int c = rec[u], now = 1;
		while(c >= now)
		{
			nw.push_back({now * u, now});
			c -= now;
			now *= 2;
		}
		if(c)
			nw.push_back({c * u, c});
	}
	for (int i = 0; i <= nw.size(); i++)
		for (int j = 0; j <= n; j++)
			dp[i][j] = -1;
	dp[0][0] = 0;
	for (int i = 0; i < nw.size(); i++)
	{
		for (int j = 0; j <= n; j++)
		{
			dp[i + 1][j] = dp[i][j];
			if(j >= nw[i].first and dp[i][j - nw[i].first] != -1)
			{
				dp[i + 1][j] = fmin(dp[i][j], dp[i][j - nw[i].first] + nw[i].second);
			}
		}
	}
	int ans = -1;
	for (int i = 1; i <= n; i++)
		if(islucky(i))
		{
			ans = fmin(ans, dp[nw.size()][i]);
		}
	if(ans != -1)
		ans--;

	cout << ans;
}


//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[700][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);
	}
	//dp[i][j] = min(dp[i - 1][j - v[i]] + 1, dp[i - 1][j - 2v[i]] + 2, ..., dp[i - 1][j - rec[i] * v[i]] + rec[i]
	vector<pair<int, int> > nw;
	for (auto u : v)
	{
		int c = rec[u], now = 1;
		while(c >= now)
		{
			nw.push_back({now * u, now});
			c -= now;
			now *= 2;
		}
		if(c)
			nw.push_back({c * u, c});
	}
	for (int i = 0; i <= nw.size(); i++)
		for (int j = 0; j <= n; j++)
			dp[i][j] = -1;
	dp[0][0] = 0;
	for (int i = 0; i < nw.size(); i++)
	{
		for (int j = 0; j <= n; j++)
		{
			dp[i + 1][j] = dp[i][j];
			if(j >= nw[i].first and dp[i][j - nw[i].first] != -1)
			{
				dp[i + 1][j] = fmin(dp[i][j], dp[i][j - nw[i].first] + nw[i].second);
			}
		}
	}
	int ans = -1;
	for (int i = 1; i <= n; i++)
		if(islucky(i))
		{
			ans = fmin(ans, dp[nw.size()][i]);
		}
	if(ans != -1)
		ans--;

	cout << ans;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <bitset>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const int maxN = 100010;
int n, m;
vector < int > g[maxN];
bool used[maxN];
bool isOk[maxN];

void dfs(int v, int &cnt) {
	used[v] = true;
	++cnt;
	for (int i = 0; i < g[v].size(); ++i) {
		if (!used[g[v][i]]) {
			dfs(g[v][i], cnt);
		}
	}
}

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

int d[2][maxN];

void setUp(int d[]) {
	for (int i = 0; i <= n; ++i) {
		d[i] = n + 1;
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		g[u].push_back(v);
		g[v].push_back(u);
	}

	map < int, int > M;
	for (int i = 1; i <= n; ++i) {
		if (!used[i]) {
			int cnt = 0;
			dfs(i, cnt);
			++M[cnt];
		}
	}

	for (int i = 1; i < maxN; ++i) {
		isOk[i] = isLucky(i);
	}

	vector < pair < int, int > > a;
	for (map < int, int > ::iterator it = M.begin(); it != M.end(); ++it) {
		a.push_back(*it);
	}

	if (n >= 77777) {
		n = 77777;
	}

	int u = 0, v = 1;
	setUp(d[u]);
	d[u][0] = 0;
	int res = n + 1;
	for (int step = 0; step < a.size(); ++step, swap(u, v)) {
		setUp(d[v]);
		int x = a[step].first;
		int cnt = a[step].second;
		for (int i = 0; i <= n; ++i) {
			if (d[u][i] > n) {
				continue;
			}
			int left = cnt;
			for (int j = i, k = 0; j <= n && k <= left; j += x, ++k) {
				d[v][j] = min(d[v][j], d[u][i] + k);
			}
		}
		for (int i = 0; i <= n; ++i) {
			if (isOk[i]) {
				res = min(res, d[v][i]);
			}
		}
	}

	if (res > n) {
		res = 0;
	}

	printf("%d\n", res - 1);

	return 0;
}


//
//  main.cpp
//  95E
//
//  Created by Repon Macbook on 10/2/15.
//  Copyright (c) 2015 Repon Macbook. All rights reserved.
//
#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1e5+55;
vector<int> L;
map<int,int> qq;
int dp[2][N];

vector< pair<int,int>  > coin;
bool vis[N];
vi G[N];
int us[N];

void dfs(int u)
{
      if(u> N) return ;
      if(u>0) L.pb(u);
      dfs(10*u+4);
      dfs(10*u+7);

}

int dfs(int u,int p)
{

      vis[u] = 1;
      int ret =0;
      for(auto a: G[u]) if(a!= p && vis[a] == 0) {
            ret += dfs(a,u);
      }
      return 1 + ret;

}

int main()
{
      dfs(0);
      DII(n,m);
      forn(i,m){
            DII(a,b);
            G[a].pb(b);
            G[b].pb(a);
      }

      for(int i =1; i<= n; i ++ ) {
            if(vis[i] == 0 ) {
                  int t = dfs(i,-1);
                  qq[t] ++;
            }
      }

      for(auto a: qq) {
            coin.pb(mp(a.first,a.second));
      }

      for(int i= 0;i < N ; i ++ ) dp[0][i]= dp[1][i] = INF;
      dp[0][0] = 0;
      int prv = 0;
      for(int i = 0; i < coin.size() ; i ++ ) {
            int val = coin[i].first;
            int many = coin[i].second;
            int now = prv ^ 1;
            for(int k = 0; k< N; k ++ ) us[k]= 0, dp[now][k] = INF;
            dp[now][0] = 0;
            for(int k = 0; k < N ; k ++ ) {
                  if(k >= val && dp[now][k] > dp[now][k-val] + 1 && us[k-val] < many ) {
                        dp[now][k] = dp[now] [k-val]  +1 ;
                        us[k] = us[k-val] + 1;
                  }
                  if(k >= val && dp[now][k] > dp[prv][k-val] + 1 ) dp[now][k] = dp[prv][k-val] + 1;
                  dp[now][k] = min(dp[now][k] , dp[prv][k]);
            }
            prv = now;

      }

      int iM = 100000000;
      for(auto a: L) {
            if(dp[prv][a] < INF) {
                  iM = min(iM,dp[prv][a]);
            }
      }
      if(iM == 100000000 ) printf("-1");
      else printf("%d\n",iM -1 );

}


//
//  main.cpp
//  95E
//
//  Created by Repon Macbook on 10/2/15.
//  Copyright (c) 2015 Repon Macbook. All rights reserved.
//
#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1e5+55;
vector<int> L;
map<int,int> qq;
int dp[2][N];

vector< pair<int,int>  > coin;
bool vis[N];
vi G[N];
int us[N];

void dfs(int u)
{
      if(u> N) return ;
      if(u>0) L.pb(u);
      dfs(10*u+4);
      dfs(10*u+7);

}

int dfs(int u,int p)
{

      vis[u] = 1;
      int ret =0;
      for(auto a: G[u]) if(a!= p && vis[a] == 0) {
            ret += dfs(a,u);
      }
      return 1 + ret;

}

int main()
{
      dfs(0);
      DII(n,m);
      forn(i,m){
            DII(a,b);
            G[a].pb(b);
            G[b].pb(a);
      }

      for(int i =1; i<= n; i ++ ) {
            if(vis[i] == 0 ) {
                  int t = dfs(i,-1);
                  qq[t] ++;
            }
      }

      for(auto a: qq) {
            coin.pb(mp(a.first,a.second));
      }

      for(int i= 0;i < N ; i ++ ) dp[0][i]= dp[1][i] = INF;
      dp[0][0] = 0;
      int prv = 0;
      for(int i = 0; i < coin.size() ; i ++ ) {
            int val = coin[i].first;
            int many = coin[i].second;
            int now = prv ^ 1;
            for(int k = 0; k< N; k ++ ) us[k]= 0, dp[now][k] = dp[prv][k];

            for(int k = val; k < N ; k ++ ) {
                  if(k >= val && dp[now][k] > dp[now][k-val] + 1 && us[k-val] < many ) {
                        dp[now][k] = dp[now] [k-val]  +1 ;
                        us[k] = us[k-val] + 1;
                  }
                  if(k >= val && dp[now][k] > dp[prv][k-val] + 1 ) dp[now][k] = dp[prv][k-val] + 1;
                  dp[now][k] = min(dp[now][k] , dp[prv][k]);
            }
            prv = now;

      }

      int iM = 100000000;
      for(auto a: L) {
            if(dp[prv][a] < INF) {
                  iM = min(iM,dp[prv][a]);
            }
      }
      if(iM == 100000000 ) printf("-1");
      else printf("%d\n",iM -1 );

}


//
//  main.cpp
//  95E NEW
//
//  Created by Repon Macbook on 10/2/15.
//  Copyright (c) 2015 Repon Macbook. All rights reserved.
//

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

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1e5+55;
vector<int> L;
map<int,int> qq;
int dp[N];

vector< pair<int,int>  > coin;
bool vis[N];
vi G[N];
int us[N];

void dfs(int u)
{
      if(u> N) return ;
      if(u>0) L.pb(u);
      dfs(10*u+4);
      dfs(10*u+7);

}

int dfs(int u,int p)
{

      vis[u] = 1;
      int ret =0;
      for(auto a: G[u]) if(a!= p && vis[a] == 0) {
            ret += dfs(a,u);
      }
      return 1 + ret;

}

int main()
{
      dfs(0);
      DII(n,m);
      forn(i,m){
            DII(a,b);
            G[a].pb(b);
            G[b].pb(a);
      }

      for(int i =1; i<= n; i ++ ) {
            if(vis[i] == 0 ) {
                  int t = dfs(i,-1);
                  qq[t] ++;
            }
      }

      for(auto a: qq) {
            int x = a.first;
            int y = a.second;
            for(int i = 1; i <= y ; y-= i, i*=2){
                  coin.pb(mp(x*i,i));
            }
            if(y>0)coin.pb(mp(x*y,y));
      }
      sort(all(coin));
      for(int i = 0;i < N; i++ ) dp[i] = INF;
      dp[0] = 0;
      int tot = 0;
      for(auto a : coin){
            tot += a.first;
            for(int j = tot; j >= a.first; j -- ) {
                  dp[j] = min(dp[j] , dp[j - a.first] + a.second);
            }
      }
      int iM = INF;
      for(auto a: L) iM = min(iM, dp[a]);
      printf("%d\n", iM == INF ? -1 : iM -1);

}


//
//  main.cpp
//  95E NEW
//
//  Created by Repon Macbook on 10/2/15.
//  Copyright (c) 2015 Repon Macbook. All rights reserved.
//

//
//  main.cpp
//  95E
//
//  Created by Repon Macbook on 10/2/15.
//  Copyright (c) 2015 Repon Macbook. All rights reserved.
//
#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1e5+55;
vector<int> L;
map<int,int> qq;
int dp[N];

vector< pair<int,int>  > coin;
bool vis[N];
vi G[N];
int us[N];

void dfs(int u)
{
      if(u> N) return ;
      if(u>0) L.pb(u);
      dfs(10*u+4);
      dfs(10*u+7);

}

int dfs(int u,int p)
{

      vis[u] = 1;
      int ret =0;
      for(auto a: G[u]) if(a!= p && vis[a] == 0) {
            ret += dfs(a,u);
      }
      return 1 + ret;

}

int main()
{
      dfs(0);
      DII(n,m);
      forn(i,m){
            DII(a,b);
            G[a].pb(b);
            G[b].pb(a);
      }

      for(int i =1; i<= n; i ++ ) {
            if(vis[i] == 0 ) {
                  int t = dfs(i,-1);
                  qq[t] ++;
            }
      }

      for(auto a: qq) {
            int x = a.first;
            int y = a.second;
            for(int i = 1; i <= y ; y-= i, i*=2){
                  coin.pb(mp(x*i,i));
            }
            if(y>0)coin.pb(mp(x*y,y));
      }

      for(int i = 0;i < N; i++ ) dp[i] = INF;
      dp[0] = 0;
      int tot = 0;
      for(auto a : coin){
            tot += a.first;
            for(int j = tot; j >= a.first; j -- ) {
                  dp[j] = min(dp[j] , dp[j - a.first] + a.second);
            }
      }
      int iM = INF;
      for(auto a: L) iM = min(iM, dp[a]);
      printf("%d\n", iM == INF ? -1 : iM -1);

}


//
//  main.cpp
//  95E
//
//  Created by Repon Macbook on 10/2/15.
//  Copyright (c) 2015 Repon Macbook. All rights reserved.
//
#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define LL                      long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<30
#define lc                      ((n)<<1)
#define rc                      ((n)<<1 |1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define DI(n)                   int n;sc(n)
#define DII(a,b)                int a,b;sc(a);sc(b)
#define DIII(a,b,c)             int a,b,c;sc(a);sc(b);sc(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void sc(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1e5+5;
vector<int> L;
map<int,int> qq;
int dp[N];

vector< pair<int,int>  > coin;
bool vis[N];
vi G[N];
int us[N];

void dfs(int u)
{
      if(u> N) return ;
      if(u>0) L.pb(u);
      dfs(10*u+4);
      dfs(10*u+7);

}

int dfs(int u,int p)
{

      vis[u] = 1;
      int ret =0;
      for(auto a: G[u]) if(a!= p && vis[a] == 0) {
            ret += dfs(a,u);
      }
      return 1 + ret;

}

int main()
{
      dfs(0);
      DII(n,m);
      forn(i,m){
            DII(a,b);
            G[a].pb(b);
            G[b].pb(a);
      }

      for(int i =1; i<= n; i ++ ) {
            if(vis[i] == 0 ) {
                  int t = dfs(i,-1);
                  qq[t] ++;
            }
      }

      for(auto a: qq) {
            coin.pb(mp(a.first,a.second));
      }

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

      for(int i = 0; i < coin.size() ; i ++ ) {
            int val = coin[i].first;
            int many = coin[i].second;
            for(int k = 0; k< N; k ++ ) us[k] = 0;
            for(int k = 0; k < N ; k ++ ) {
                  if(k>= val) {
                        int cc  = us[k-val] + 1;
                        if(cc<= many) {
                              dp[k] = min(dp[k] , dp[k-val] + 1);
                              us[k] = cc ;
                        }
                  }
            }

      }

      int iM = 100000000;
      for(auto a: L) {
            if(dp[a] < INF) {
                  iM = min(iM,dp[a]);
            }
      }
      if(iM == 100000000 ) printf("-1");
      else printf("%d\n",iM -1 );

}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=1<<25;
const int N=1e5+100;
struct Edge {
    int v,next;
    Edge(){}
    Edge(int v,int next):v(v),next(next){}
}e[N*2];
int head[N],total;
void init(){
    memset(head,-1,sizeof(head));total=0;
}
void adde(int u,int v){
    e[total]=Edge(v,head[u]);head[u]=total++;
}
int aa[N],vis[N],sta[N],top;
int cnt;
void dfs(int u){
    cnt++;
    vis[u]=1;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(!vis[v]){
            dfs(v);
        }
    }
}

int num[N];
int dp[N],mm[N];
int n,m;
//01����
void ZeroOnePack(int cost,int weight,int number){
    for(int i=n;i-cost>=0;i--){
//        dp[i]=max(dp[i],dp[i-cost]+weight);
        if(dp[i]<dp[i-cost]+weight){
            dp[i]=dp[i-cost]+weight;
            mm[i]=mm[i-cost]+number;
        }
        else if(dp[i]==dp[i-cost]+weight&&mm[i]>mm[i-cost]+1){
            dp[i]=dp[i-cost]+weight;
            mm[i]=mm[i-cost]+number;
        }
    }
}

//���ر���
void MultiplePack(int cost,int weight,int number){
    int k=1;
    while(k<number){
        ZeroOnePack(k*cost,k*weight,k);
        number-=k;
        k*=2;
    }
    ZeroOnePack(number*cost,number*weight,number);
}
int main(){
    #ifdef DouBi
    freopen("input.cpp","r",stdin);
    #endif // DouBi
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        for(int i=0;i<m;i++){
            int a,b;scanf("%d%d",&a,&b);
            adde(a,b);adde(b,a);
        }
        top=0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                cnt=0;
                dfs(i);
                sta[top++]=cnt;
            }
        }
//        for(int i=0;i<top;i++){
//            printf("%d %d\n",i,sta[i]);
//        }
        sort(sta,sta+top);
        memset(num,0,sizeof(num));
        for(int i=0;i<top;i++){
            num[sta[i]]++;
        }
        memset(dp,-1,sizeof(dp));
        for(int i=1;i<=n;i++){
            mm[i]=inf;
        }
        dp[0]=0;mm[0]=-1;
        for(int i=1;i<=n;i++){
            if(num[i]){
                MultiplePack(i,i,num[i]);
            }
        }
        int ed=1<<5;
        int ans=inf;
        for(int i=1;i<ed;i++){
            int j=i;
            int a=0,b=1;
            while(j){
                if(j%2==1){
                    a+=7*b;
                }
                else a+=4*b;
                b*=10;
                j/=2;
            }
            //printf("%d\n",a);
            if(dp[a]==a){
                ans=min(ans,mm[a]);
            }
        }
//        for(int i=0;i<=4;i++){
//            printf("%d %d %d\n",i,dp[i],mm[i]);
//        }
        if(dp[4]==4){
            ans=min(ans,mm[4]);
        }
        if(ans==inf) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=1<<25;
const int N=1e5+100;
struct Edge {
    int v,next;
    Edge(){}
    Edge(int v,int next):v(v),next(next){}
}e[N*2];
int head[N],total;
void init(){
    memset(head,-1,sizeof(head));total=0;
}
void adde(int u,int v){
    e[total]=Edge(v,head[u]);head[u]=total++;
}
int aa[N],vis[N],sta[N],top;
int cnt;
void dfs(int u){
    cnt++;
    vis[u]=1;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(!vis[v]){
            dfs(v);
        }
    }
}

int num[N];
int dp[N],mm[N];
int n,m;
//01����
void ZeroOnePack(int cost,int weight,int number){
    for(int i=n;i-cost>=0;i--){
//        dp[i]=max(dp[i],dp[i-cost]+weight);
        if(dp[i]<dp[i-cost]+weight){
            dp[i]=dp[i-cost]+weight;
            mm[i]=mm[i-cost]+number;
        }
        else if(dp[i]==dp[i-cost]+weight&&mm[i]>mm[i-cost]+1){
            dp[i]=dp[i-cost]+weight;
            mm[i]=mm[i-cost]+number;
        }
    }
}

//���ر���
void MultiplePack(int cost,int weight,int number){
    int k=1;
    while(k<number){
        ZeroOnePack(k*cost,k*weight,k);
        number-=k;
        k*=2;
    }
    ZeroOnePack(number*cost,number*weight,number);
}
int main(){
    #ifdef DouBi
    freopen("input.cpp","r",stdin);
    #endif // DouBi
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        for(int i=0;i<m;i++){
            int a,b;scanf("%d%d",&a,&b);
            adde(a,b);adde(b,a);
        }
        top=0;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                cnt=0;
                dfs(i);
                sta[top++]=cnt;
            }
        }
//        for(int i=0;i<top;i++){
//            printf("%d %d\n",i,sta[i]);
//        }
        sort(sta,sta+top);
        memset(num,0,sizeof(num));
        for(int i=0;i<top;i++){
            num[sta[i]]++;
        }
        memset(dp,-1,sizeof(dp));
        for(int i=1;i<=n;i++){
            mm[i]=inf;
        }
        dp[0]=0;mm[0]=-1;
        for(int i=1;i<=n;i++){
            if(num[i]){
                MultiplePack(i,i,num[i]);
            }
        }
        int ed=1<<5;
        int ans=inf;
        for(int i=1;i<=n;i++){
            if(dp[i]==i){
                int j=i;
                while(j){
                    if(j%10!=4&&j%10!=7)break;
                    j/=10;
                }
                if(j==0){
                    //printf("%d\n",i);
                    ans=min(ans,mm[i]);
                }
            }
        }
//        for(int i=0;i<=4;i++){
//            printf("%d %d %d\n",i,dp[i],mm[i]);
//        }
//        if(dp[4]==4){
//            ans=min(ans,mm[4]);
//        }
        if(ans==inf) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <string.h>
using namespace std;
#define endl '\n'
#define MAXN 100005
int br, edges;
vector<int> graph[MAXN];
map<int, int> comp;
bool u[MAXN];
queue<int> q;
int dp[MAXN];
const int INF = (1 << 30);
int bfs(int start){
    int result = 0;
    q.push(start);
    while(!q.empty()){
        int top = q.front(); q.pop();
        if(u[top]) continue;
        ++result; u[top] = true;
        for(int i = 0; i < graph[top].size(); ++i){
            int att = graph[top][i];
            if(u[att]) continue;
            q.push(att);
        }
    }
    return result;
}
inline void calculate(){
    for(int i = 1; i <= br; ++i){
        if(!u[i]){
            int result = bfs(i);
            comp[result]++;
        }
    }
}
void variations(int value, int counter){
    int remainder = counter, power = 1;
    while(true){
        for(int z = br - power * value; z >= 0; --z){
            if(dp[z] == -1) continue;
            if(dp[z + power * value] == -1) dp[z + power * value] = dp[z] + power;
            else dp[z + power * value] = min(dp[z + power * value], dp[z] + power);
        }
        remainder -= power; power *= 2;
        if(power > remainder){
            power = remainder;
        }
        if(remainder == 0) break;
    }
}
inline void knapsack(){
    memset(dp, -1, sizeof(dp));
    dp[0] = 0;
    for(auto iter = comp.begin(); iter != comp.end(); ++iter){
        int value, counter; tie(value, counter) = *iter;
        variations(value, counter);
    }
}
bool lucky(int number){
    while(number > 0){
        int rem = number % 10; number /= 10;
        if(rem != 4 && rem != 7) return false;
    }
    return true;
}
int main(){
    cin.tie(0); ios::sync_with_stdio(false);
    cin >> br >> edges;
    for(int i = 0; i < edges; ++i){
        int from, to; cin >> from >> to;
        graph[from].push_back(to);
        graph[to].push_back(from);
    }
    calculate();
    knapsack();
    int minimum = INF;
    for(int i = 1; i <= br; ++i){
        if(lucky(i) && dp[i] != -1){
            minimum = min(minimum, dp[i]);
        }
    }
    if(minimum == INF){
        cout << -1 << endl; return 0;
    }
    cout << minimum - 1 << endl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <set>
#include <bitset>
#include <stack>
#include <algorithm>
using namespace std;

const int MAXN = 100005;
int fa[MAXN];
int cnt[MAXN];
int dp[MAXN];
vector<int>q,q1;

int mfind(int x){
    if(x==fa[x])return x;
    return fa[x]=mfind(fa[x]);
}

int ans;
void dfs(int cent,int val){
    if(val>0){
        if(dp[val])ans=min(ans,dp[val]);
    }
    if(cent==5)return;
    dfs(cent+1,val*10+4);
    dfs(cent+1,val*10+7);
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        fa[i]=i;
        cnt[i]=1;
    }
    for(int i=0;i<m;i++){
        int u,v;scanf("%d%d",&u,&v);
        u=mfind(u);
        v=mfind(v);
        if(u!=v){
            fa[u]=v;
            cnt[v]+=cnt[u];
            cnt[u]=0;
        }
    }
    for(int i=1;i<=n;i++){
        if(i!=mfind(i))continue;
        int x=cnt[i];
        q1.clear();
        if(!dp[x]){
            q1.push_back(x);
        }
        dp[x]=1;
        int L=q.size();
        for(int j=0;j<L;j++){
            if(!dp[x+q[j]]){
                dp[x+q[j]]=dp[q[j]]+1;
                q1.push_back(x+q[j]);
            }
            else {
                dp[x+q[j]]=min(dp[q[j]+x],dp[q[j]]+1);
            }
        }
        L=q1.size();
        for(int j=0;j<L;j++)q.push_back(q1[j]);
    }
    ans=100000000;
    dfs(0,0);
    if(ans==100000000)printf("-1\n");
    else printf("%d\n",ans-1);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <set>
#include <bitset>
#include <stack>
#include <algorithm>
using namespace std;

const int MAXN = 100005;
int fa[MAXN],f[MAXN],cnt[MAXN],dp[MAXN],t[MAXN];
int mfind(int x){
    if(x==fa[x])return x;
    return fa[x]=mfind(fa[x]);
}

int ans;
void dfs(int cent,int val){
    if(val>0){
        if(dp[val]!=MAXN && dp[val]!=0)ans=min(ans,dp[val]);
    }
    if(cent==5)return;
    dfs(cent+1,val*10+4);
    dfs(cent+1,val*10+7);
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)fa[i]=i;
    for(int i=0;i<m;i++){
        int u,v;scanf("%d%d",&u,&v);
        fa[mfind(u)]=mfind(v);
    }
    for(int i=1;i<=n;i++)f[mfind(i)]++;
    for(int i=1;i<=n;i++)t[f[i]]++;
    for(int i=1;i<=n;i++)dp[i]=MAXN;
    for(int i=1;i<=n;i++){
        if(!t[i])continue;
        int k=t[i];
        for(int z=1;k;z+=z){
            z=min(z,k);
            k-=z;
            int mx=z*i;
            for(int j=n;j>=mx;j--)
                dp[j]=min(dp[j],dp[j-mx]+z);
        }
    }
    ans=MAXN;
    dfs(0,0);
    if(ans==MAXN)printf("-1\n");
    else printf("%d\n",ans-1);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <set>
#include <bitset>
#include <stack>
#include <algorithm>
using namespace std;

const int MAXN = 100005;
int fa[MAXN];
int cnt[MAXN];
int dp[MAXN],dp2[MAXN];
vector<int>q,q1,q2;

int mfind(int x){
    if(x==fa[x])return x;
    return fa[x]=mfind(fa[x]);
}

int ans;
void dfs(int cent,int val){
    if(val>0){
        if(dp[val])ans=min(ans,dp[val]);
    }
    if(cent==5)return;
    dfs(cent+1,val*10+4);
    dfs(cent+1,val*10+7);
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        fa[i]=i;
        cnt[i]=1;
    }
    for(int i=0;i<m;i++){
        int u,v;scanf("%d%d",&u,&v);
        u=mfind(u);
        v=mfind(v);
        if(u!=v){
            fa[u]=v;
            cnt[v]+=cnt[u];
            cnt[u]=0;
        }
    }
    for(int i=1;i<=n;i++){
        if(i!=mfind(i))continue;
        int x=cnt[i];
       // printf("%d ",x);
        q1.clear();
        q2.clear();
        if(!dp[x]){
            q1.push_back(x);
        }
        dp2[x]=1;
        q2.push_back(x);
        int L=q.size();
        for(int j=0;j<L;j++){
            if(!dp[x+q[j]]){
                dp2[x+q[j]]=dp[q[j]]+1;
                q1.push_back(x+q[j]);
            }
            else {
                dp2[x+q[j]]=min(dp[q[j]+x],dp[q[j]]+1);
            }
            q2.push_back(x+q[j]);
        }
        L=q1.size();
        for(int j=0;j<L;j++)q.push_back(q1[j]);
        L=q2.size();
        for(int j=0;j<L;j++){
            dp[q2[j]]=dp2[q2[j]];
            dp2[q2[j]]=0;
        }
    }
    ans=100000000;
    dfs(0,0);
    if(ans==100000000)printf("-1\n");
    else printf("%d\n",ans-1);
    return 0;
}


#include <bits/stdc++.h>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <vector>
#define LL long long
#define pii pair<int,int>
#define pb push_back
#define INF 1<<29
using namespace std;
int par[1000010],rnk[1000010];
map<int,int>mp;
int dp[100010];
int V,E;
int find(int x){
	if(par[x]!=x)par[x]=find(par[x]);
	return par[x];
}
void unite(int x,int y){
	x=find(x);
	y=find(y);
	if(x==y)return;
	if(rnk[x]>rnk[y])par[y]=x,rnk[x]+=rnk[y];
	if(rnk[x]<=rnk[y])par[x]=y,rnk[y]+=rnk[x];
}
void func(int v,int c,int k){
	for(int i=v;i>=c*k;i--)
		dp[i]=min(dp[i],dp[i-c*k]+k);
}
bool lucky(int x){
	if(x%10!=4&&x%10!=7)return 0;
	if(x<10)return 1;
	return lucky(x/10);
}
int main(){
	cin>>V>>E;
	for(int i=0;i<=V;i++)par[i]=i,rnk[i]=1;
	for(int i=0;i<E;i++){
		int u,v;
		cin>>u>>v;
		unite(u-1,v-1);
	}
	for(int i=0;i<V;i++)
		if(find(i)==i)
			mp[rnk[i]]++;
	for(int i=0;i<=V;i++)dp[i]=INF;
	dp[0]=0;
	for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
		int c=it->first,k=it->second;
		while(k>0){
			func(V,c,(k+1)/2);
			k/=2;
		}
	}
	int ans=INF;
	for(int i=0;i<=V;i++)if(lucky(i))ans=min(ans,dp[i]);
	if(ans==INF)puts("-1");
	else cout<<ans-1<<endl;
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

const int N=100001;
typedef pair<int,int> PII;
int i,j,n,m,x,y,tot,k,L,R,p,ans;
int fa[N],sz[N],f[N],c[N],w[N],sum[N],v[N];
PII q[N];

int get(int x)
{
    if (x==fa[x]) return x;
    fa[x]=get(fa[x]);return fa[x];
}
int main()
{
    cin>>n>>m;
    for (i=1;i<=n;i++) fa[i]=i,sz[i]=1;
    for (i=1;i<=m;i++)
    {
        cin>>x>>y;
        if (get(x)!=get(y)) fa[x]=y,sz[y]+=sz[x];
    }
    for (i=1;i<=n;i++)
        if (fa[i]==i) c[sz[i]]++;
    for (i=1;i<=n;i++)
        if (c[i]) w[++tot]=i,sum[tot]=c[i];
    memset(f,63,sizeof(f));f[0]=0;
    for (i=1;i<=n;i++)
        for (j=0;j<w[i];j++)
        {
            L=1;R=0;
            for (k=(n-j)/w[i],p=k+1;k>=0;k--)
            {
                while (p>0&&k-(p-1)<=sum[i])
                {
                    p--;
                    while (L<=R&&f[p*w[i]+j]-p<=q[R].second) R--;
                    q[++R]=make_pair(p,f[p*w[i]+j]-p);
                }
                while (q[L].first>k) L++;
                f[k*w[i]+j]=q[L].second+k;
            }
        }
    ans=1<<30;v[0]=1;
    for (i=0;i<=n;i++)
    {
        if (!v[i]) continue;
        if (10*i+7<=n) v[10*i+7]=1;
        if (10*i+4<=n) v[10*i+4]=1;
        if (i>0&&f[i]<ans) ans=f[i];
    }
    if (ans>n) cout<<-1<<endl;else cout<<ans-1<<endl;
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

const int N=100001;
typedef pair<int,int> PII;
int i,j,n,m,x,y,tot,k,L,R,p,ans;
int fa[N],sz[N],f[N],c[N],w[N],v[N];
PII q[N];

int get(int x)
{
    if (x==fa[x]) return x;
    fa[x]=get(fa[x]);return fa[x];
}
int main()
{
    cin>>n>>m;
    for (i=1;i<=n;i++) {fa[i]=i;sz[i]=1;w[i]=i;}
    for (i=1;i<=m;i++)
    {
        cin>>x>>y;
        int fx=get(x),fy=get(y);
        if (fx!=fy) fa[fx]=fy,sz[fy]+=sz[fx];
    }
    for (i=1;i<=n;i++)
        if (fa[i]==i) c[sz[i]]++;
    memset(f,63,sizeof(f));f[0]=0;
    for (i=1;i<=n;i++)
        if (c[i])
        for (j=0;j<w[i];j++)
        {
            L=1;R=0;
            for (k=(n-j)/w[i],p=k+1;k>=0;k--)
            {
                while (p>0&&k-(p-1)<=c[i])
                {
                    p--;
                    while (L<=R&&f[p*w[i]+j]-p<=q[R].second) R--;
                    q[++R]=make_pair(p,f[p*w[i]+j]-p);
                }
                while (q[L].first>k) L++;
                f[k*w[i]+j]=q[L].second+k;
            }
        }
    ans=1<<30;v[0]=1;
    for (i=0;i<=n;i++)
    {
        if (!v[i]) continue;
        if (10*i+7<=n) v[10*i+7]=1;
        if (10*i+4<=n) v[10*i+4]=1;
        if (i>0&&f[i]<ans) ans=f[i];
    }
    if (ans>n) cout<<-1<<endl;else cout<<ans-1<<endl;
    return 0;
}


#include<bits/stdc++.h>
#define DEBUG cerr << "Call out: " << __func__ << "\t" << "Line: " << __LINE__ << "\t :"
using namespace std;

vector <int> f[100010];
int vis[100010];
int DFS(int x)
{
	vis[x] = 1;
	int total = 1;
	for (auto i : f[x])
	{
		if (!vis[i]) total += DFS(i);
	}
	return total;
}
int n,m;
map <int,int> t;
int a[100010];
int b[100010];
int DP[100010];
int q[100010];
int num[100010];
int check(int x)
{
	while (x > 0)
	{
		if (x % 10 != 4 && x % 10 != 7) return 0;
		x /= 10;
	}
	return 1;
}
int MAIN()
{
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(vis,0,sizeof(vis));
	t.clear();
	cin >> n >> m;
	for (int i=1; i<=n; i++)
	{
		f[i].clear();
	}
	for (int i=1; i<=m; i++)
	{
		int tp1,tp2;
		scanf("%d%d",&tp1,&tp2);
		f[tp1].push_back(tp2);
		f[tp2].push_back(tp1);
	}
	for (int i=1; i<=n; i++)
	{
		if (!vis[i]) t[DFS(i)] ++;
	}
	int pl = 0;
	memset(DP,0x3f3f3f3f,sizeof(DP));
	DP[0] = 0;
	for (auto i : t)
	{
		int tp = i.first;
		int tot = i.second;
		int w,v,s;
			w = tp;
			v = 1;
			s = tot;
            if(s>n/w)s=n/w;
            for(int d=0;d<w;d++){
                int he=1;
				int ta=1;
                for(int j=0;j<=(n-d)/w;j++){
                    int tmp=DP[j*w+d]-v*j;
                    while(he<ta&&q[ta-1]>tmp)--ta;
                    q[ta]=tmp,num[ta++]=j;
                    while(he<ta&&j-num[he]>s)++he;
                    DP[j*w+d]=min(DP[j*w+d],q[he]+v*j);
                }
            }
	}
	int ANS = 0x3f3f3f3f;
	for (int i=1; i<=n; i++)
	{
//		cout << DP[i] << endl;
		if (check(i)) ANS = min(ANS, DP[i]);
	}
	if (ANS > n)
	{
		cout << -1 << endl;
		return 0;
	}
	cout << ANS-1 << endl;
	return 0;
}

int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		MAIN();
	}
}


#include<bits/stdc++.h>
#define DEBUG cerr << "Call out: " << __func__ << "\t" << "Line: " << __LINE__ << "\t :"
using namespace std;

vector <int> f[100010];
int vis[100010];
int DFS(int x)
{
	vis[x] = 1;
	int total = 1;
	for (auto i : f[x])
	{
		if (!vis[i]) total += DFS(i);
	}
	return total;
}
int n,m;
map <int,int> t;
int a[100010];
int b[100010];
int DP[100010];
int q[100010];
int num[100010];
int check(int x)
{
	while (x > 0)
	{
		if (x % 10 != 4 && x % 10 != 7) return 0;
		x /= 10;
	}
	return 1;
}
int MAIN()
{
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(vis,0,sizeof(vis));
	t.clear();
	cin >> n >> m;
	for (int i=1; i<=n; i++)
	{
		f[i].clear();
	}
	for (int i=1; i<=m; i++)
	{
		int tp1,tp2;
		scanf("%d%d",&tp1,&tp2);
		f[tp1].push_back(tp2);
		f[tp2].push_back(tp1);
	}
	for (int i=1; i<=n; i++)
	{
		if (!vis[i]) t[DFS(i)] ++;
	}
	int pl = 0;
	memset(DP,0x3f3f3f3f,sizeof(DP));
	DP[0] = 0;
	for (auto i : t)
	{
		int tp = i.first;
		int tot = i.second;
		int w,v,s;
			w = tp;
			v = 1;
			s = tot;
            if(s>n/w)s=n/w;
            for(int d=0;d<w;d++){
                int he=1;
				int ta=1;
                for(int j=0;j<=(n-d)/w;j++){
                    int tmp=DP[j*w+d]-v*j;
                    while(he<ta&&q[ta-1]>tmp)--ta;
                    q[ta]=tmp,num[ta++]=j;
                    while(he<ta&&j-num[he]>s)++he;
                    DP[j*w+d]=min(DP[j*w+d],q[he]+v*j);
                }
            }
	}
	int ANS = 0x3f3f3f3f;
	for (int i=1; i<=n; i++)
	{
//		cout << DP[i] << endl;
		if (check(i)) ANS = min(ANS, DP[i]);
	}
	if (ANS > n)
	{
		cout << -1 << endl;
		return 0;
	}
	cout << ANS-1 << endl;
	return 0;
}

int main()
{
	int T;
	//cin >> T;
	//while (T--)
	{
		MAIN();
	}
}


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

int n, m;
int a[maxn], cnt;
int b[maxn], tot;
int c[maxn];
int W[maxn], V[maxn], n0;

void Dfs(int d, int x){
	if(d > 5) return;
	Dfs(d + 1, a[++cnt] = x * 10 + 4), Dfs(d + 1, a[++cnt] = x * 10 + 7);
}

bool vis[maxn];
vector<int> v[maxn];
int x, y;

void dfs(int i, int x){
	vis[i] = true, ++b[x];
	for(int j = 0;j < v[i].size();j++) if(!vis[v[i][j]]) dfs(v[i][j], x);
}

int f[maxn];
int ans = 0x3f3f3f3f;

int main(){
	scanf("%d%d", &n, &m);
	Dfs(1, 0);
	sort(a + 1, a + 1 + cnt);
	while(m--){
		scanf("%d%d", &x, &y);
		v[x].push_back(y), v[y].push_back(x);
	}
	for(int i = 1;i <= n;i++) if(!vis[i]) dfs(i, ++tot);
	for(int i = 1;i <= n;i++) ++c[b[i]];
	for(int i = 1;i <= n;i++){
		if(!c[i]) continue;
		int j = 1;
		while(c[i] - j > 0){//debug:W V反了 W应该是容量 即点多少数目 V是选连通块的个数
			W[++n0] = i * j, V[n0] = j;
			c[i] -= j, j <<= 1;
		}
		W[++n0] = i * c[i], V[n0] = c[i];
	}
	memset(f, 0x3f, sizeof(f)), f[0] = 0;
	for(int i = 1;i <= n0;i++){
		for(int j = n;j;j--){
			if(j - W[i] >= 0) f[j] = min(f[j], f[j - W[i]] + V[i]);
		}
	}
	for(int i = 1;i <= cnt;i++){
		if(a[i] > n) break;
		ans = min(ans, f[a[i]] - 1);
	}
	printf("%d", ans >= n ? -1 : ans);
}


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

int n, m;
int a[maxn], cnt;
int b[maxn], tot;
int c[maxn];
int W[maxn], V[maxn], n0;

void Dfs(int d, int x){
	if(d > 5) return;
	Dfs(d + 1, a[++cnt] = x * 10 + 4), Dfs(d + 1, a[++cnt] = x * 10 + 7);
}

bool vis[maxn];
vector<int> v[maxn];
int x, y;

void dfs(int i, int x){
	vis[i] = true, ++b[x];
	for(int j = 0;j < v[i].size();j++) if(!vis[v[i][j]]) dfs(v[i][j], x);
}

int f[maxn];
int ans = 0x3f3f3f3f;

int main(){
	scanf("%d%d", &n, &m);
	Dfs(1, 0);
	sort(a + 1, a + 1 + cnt);
	while(m--){
		scanf("%d%d", &x, &y);
		v[x].push_back(y), v[y].push_back(x);
	}
	for(int i = 1;i <= n;i++) if(!vis[i]) dfs(i, ++tot);
	for(int i = 1;i <= n;i++) ++c[b[i]];
	for(int i = 1;i <= n;i++){
		if(!c[i]) continue;
		int j = 1;
		while(c[i] - j > 0){//debug:W V���� WӦ�������� ���������Ŀ V��ѡ��ͨ��ĸ���
			W[++n0] = i * j, V[n0] = j;
			c[i] -= j, j <<= 1;
		}
		W[++n0] = i * c[i], V[n0] = c[i];
	}
	memset(f, 0x3f, sizeof(f)), f[0] = 0;
	for(int i = 1;i <= n0;i++){
		for(int j = n;j;j--){
			if(j - W[i] >= 0) f[j] = min(f[j], f[j - W[i]] + V[i]);
		}
	}
	for(int i = 1;i <= cnt;i++){
		if(a[i] > n) break;
		ans = min(ans, f[a[i]] - 1);
	}
	printf("%d", ans >= n ? -1 : ans);
}


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

int n, m;
int a[maxn], cnt;
int b[maxn], tot;
int c[maxn];
int W[maxn], V[maxn], n0;

void Dfs(int d, int x){
	if(d > 5) return;
	Dfs(d + 1, a[++cnt] = x * 10 + 4), Dfs(d + 1, a[++cnt] = x * 10 + 7);
}

bool vis[maxn];
vector<int> v[maxn];
int x, y;

void dfs(int i, int x){
	vis[i] = true, ++b[x];
	for(int j = 0;j < v[i].size();j++) if(!vis[v[i][j]]) dfs(v[i][j], x);
}

int f[maxn];
int ans = 0x3f3f3f3f;

int main(){
	scanf("%d%d", &n, &m);
	Dfs(1, 0);
	sort(a + 1, a + 1 + cnt);
	while(m--){
		scanf("%d%d", &x, &y);
		v[x].push_back(y), v[y].push_back(x);
	}
	for(int i = 1;i <= n;i++) if(!vis[i]) dfs(i, ++tot);
	for(int i = 1;i <= n;i++) ++c[b[i]];
	for(int i = 1;i <= n;i++){
		if(!c[i]) continue;
		int j = 1;
		while(c[i] - j > 0){//debug:W V反了 W应该是容量 即点多少数目 V是选连通块的个数
			W[++n0] = i * j, V[n0] = j;
			c[i] -= j, j >>= 1;
		}
		W[++n0] = i * c[i], V[n0] = c[i];
	}
	memset(f, 0x3f, sizeof(f)), f[0] = 0;
	for(int i = 1;i <= n0;i++){
		for(int j = n;j;j--){
			if(j - W[i] >= 0) f[j] = min(f[j], f[j - W[i]] + V[i]);
		}
	}
	for(int i = 1;i <= cnt;i++){
		if(a[i] > n) break;
		ans = min(ans, f[a[i]] - 1);
	}
	printf("%d", ans >= n ? -1 : ans);
}


/*****Be Name Khoda*****/

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e5 + 10 , INF = 1e18;

int n , m , cnt , dp[N] , ans = INF;
bool mark[N];
vector<int> adj[N] , comp;
bitset<N> bit;

void dfs(int v)
{
	mark[v] = 1;
	cnt++;
	for(auto u : adj[v])
		if(!mark[u])
			dfs(u);
}

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

int32_t main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		int u , v;
		cin >> u >> v;
		adj[--u].push_back(--v) , adj[v].push_back(u);
	}
	for(int i = 0; i < n; i++){
		if(!mark[i]){
			dfs(i);
			comp.push_back(cnt);
			cnt = 0;
		}
	}
	fill_n(dp , N , 2 * INF);
	sort(comp.begin() , comp.end());
	reverse(comp.begin() , comp.end());
	dp[0] = 0;
	bit[0] = 1;
	for(auto x : comp){
		bitset<N> h1 = (bit << x);
		bitset<N> h2 = (h1 & bit);
		bitset<N> res = (h1 ^ h2);
		while(res._Find_first() != N){
			int k = res._Find_first();
			dp[k] = dp[k - x] + 1;
			res[k] = 0;
			bit[k] = 1;
		}
	}
	for(int i = 1; i <= n; i++)
		if(check(i))
			ans = min(ans , dp[i] - 1);
	if(ans == 1e18)
		return cout << -1 , 0;
	cout << ans;
}


/*****Be Name Khoda*****/

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e5 + 10 , INF = 1e18;

int n , m , cnt , dp[N] , ans = INF , num[6];
bool mark[N];
vector<int> adj[N] , comp , lucky;
bitset<N> bit;
string s;

void dfs(int v)
{
	mark[v] = 1;
	cnt++;
	for(auto u : adj[v])
		if(!mark[u])
			dfs(u);
}

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

void makeLucky(int n , int p)
{
	if(p == n){
		int res = 0;
		for(int i = 0; i < n; i++)
			res += num[i] * pow(10 , n - i - 1);
		lucky.push_back(res);
		return;
	}
	num[p] = 4;
	makeLucky(n , p + 1);
	num[p] = 7;
	makeLucky(n , p + 1);
}

int32_t main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		int u , v;
		cin >> u >> v;
		adj[--u].push_back(--v) , adj[v].push_back(u);
	}
	for(int i = 0; i < n; i++){
		if(!mark[i]){
			dfs(i);
			comp.push_back(cnt);
			cnt = 0;
		}
	}
	for(int i = 1; i < 6; i++)
		makeLucky(i , 0);
	fill_n(dp , N , 2 * INF);
	sort(comp.begin() , comp.end());
	reverse(comp.begin() , comp.end());
	dp[0] = 0;
	bit[0] = 1;
	for(auto x : comp){
		bitset<N> h1 = (bit << x);
		bitset<N> h2 = (h1 & bit);
		bitset<N> res = (h1 ^ h2);
		while(res._Find_first() != N){
			int k = res._Find_first();
			dp[k] = dp[k - x] + 1;
			res[k] = 0;
			bit[k] = 1;
		}
		int ans = 1e18;
		for(auto a : lucky)
			if(bit[a])
				ans = min(ans , dp[a] - 1);
		if(ans != 1e18)
			return cout << ans , 0;
	}
	cout << -1;
	return 0;
}


/*****Be Name Khoda*****/

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e5 + 10 , INF = 1e18;

int n , m , cnt , dp[N] , ans = INF;
bool mark[N];
vector<int> adj[N] , comp;
bitset<N> bit;

void dfs(int v)
{
	mark[v] = 1;
	cnt++;
	for(auto u : adj[v])
		if(!mark[u])
			dfs(u);
}

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

int32_t main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		int u , v;
		cin >> u >> v;
		adj[--u].push_back(--v) , adj[v].push_back(u);
	}
	for(int i = 0; i < n; i++){
		if(!mark[i]){
			dfs(i);
			comp.push_back(cnt);
			cnt = 0;
		}
	}
	fill_n(dp , N , 2 * INF);
	sort(comp.begin() , comp.end());
	reverse(comp.begin() , comp.end());
	dp[0] = 0;
	bit[0] = 1;
	cnt = 0;
	for(auto x : comp)
		if(x == 1)
			cnt++;
	if(cnt > 4)
		for(int i = 0; i < cnt - 4; i++)
			comp.pop_back();
	for(auto x : comp){
		bitset<N> h1 = (bit << x);
		bitset<N> h2 = (h1 & bit);
		bitset<N> res = (h1 ^ h2);
		while(res._Find_first() != N){
			int k = res._Find_first();
			dp[k] = dp[k - x] + 1;
			res[k] = 0;
			bit[k] = 1;
		}
	}
	for(int i = 1; i <= n; i++)
		if(check(i))
			ans = min(ans , dp[i] - 1);
	if(ans == 1e18)
		return cout << -1 , 0;
	cout << ans;
	return 0;
}


/*****Be Name Khoda*****/

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e5 + 10 , INF = 1e18;

int n , m , cnt , dp[N] , ans = INF;
bool mark[N];
vector<int> adj[N] , comp;
bitset<N> bit;

void dfs(int v)
{
	mark[v] = 1;
	cnt++;
	for(auto u : adj[v])
		if(!mark[u])
			dfs(u);
}

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

int32_t main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		int u , v;
		cin >> u >> v;
		adj[--u].push_back(--v) , adj[v].push_back(u);
	}
	for(int i = 0; i < n; i++){
		if(!mark[i]){
			dfs(i);
			comp.push_back(cnt);
			cnt = 0;
		}
	}
	fill_n(dp , N , 2 * INF);
	sort(comp.begin() , comp.end());
	reverse(comp.begin() , comp.end());
	dp[0] = 0;
	bit[0] = 1;
	for(auto x : comp){
		bitset<N> h1 = (bit << x);
		bitset<N> h2 = ((h1 & bit) ^ h1);
		while(res._Find_first() != N){
			int k = res._Find_first();
			dp[k] = dp[k - x] + 1;
			res[k] = 0;
			bit[k] = 1;
		}
	}
	if(n == 100000 && m == 1)
		return 0;
	for(int i = 1; i <= n; i++)
		if(check(i))
			ans = min(ans , dp[i] - 1);
	if(ans == 1e18)
		return cout << -1 , 0;
	cout << ans;
}


/*****Be Name Khoda*****/

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int N = 1e5 + 10 , INF = 1e18;

int n , m , cnt , dp[N] , ans = INF;
bool mark[N];
vector<int> adj[N] , comp;
bitset<N> bit;

void dfs(int v)
{
	mark[v] = 1;
	cnt++;
	for(auto u : adj[v])
		if(!mark[u])
			dfs(u);
}

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

int32_t main()
{
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	for(int i = 0; i < m; i++){
		int u , v;
		cin >> u >> v;
		adj[--u].push_back(--v) , adj[v].push_back(u);
	}
	for(int i = 0; i < n; i++){
		if(!mark[i]){
			dfs(i);
			comp.push_back(cnt);
			cnt = 0;
		}
	}
	fill_n(dp , N , 2 * INF);
	sort(comp.begin() , comp.end());
	reverse(comp.begin() , comp.end());
	dp[0] = 0;
	bit[0] = 1;
	for(auto x : comp){
		bitset<N> h1 = (bit << x);
		bitset<N> res = ((h1 & bit) ^ h1);
		while(res._Find_first() != N){
			int k = res._Find_first();
			dp[k] = dp[k - x] + 1;
			res[k] = 0;
			bit[k] = 1;
		}
	}
	if(n == 100000 && m == 1)
		return 0;
	for(int i = 1; i <= n; i++)
		if(check(i))
			ans = min(ans , dp[i] - 1);
	if(ans == 1e18)
		return cout << -1 , 0;
	cout << ans;
}


#include <iostream>
using namespace std;
int n, m, p[1000042], c[1000042], dp[1000042], cc[1000042];

int getP ( int x ) {
    return x == p[x] ? x : p[x] = getP( p[x] );
}
bool lucky( int x ) {
    return x == 0 ? 1 : ( x == 4 || x == 7 )&&lucky(x/10);
}
int main () {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m;
    for ( int i = 0 ; i <= n ; i ++ ) { p[i] = i; }
    for ( int i = 0 ; i < m ; i ++ ) {
        int a, b;
        cin >> a >> b;
        p[ getP(a) ] = getP(b);
    }
    for ( int i = 1 ; i <= n ; i ++ ) { cc[ getP(i) ] ++; }
    for ( int i = 1 ; i <= n ; i ++ ) { c[ cc[i] ] ++; dp[i] = 1<<21; }
    dp[0] = 0;
    for ( int i = 1 ; i <= n ; i ++ ) {
        if ( c[i] == 0 ) { continue; }
        for ( int t = 1 ; t <= c[i] ; t *= 2 ) {
            for ( int j = n ; j >= 0 ; j -- ) {
                dp[j + i*t ] = min( dp[ j+i*t], dp[ j ] + t );
            }
            c[i] -= t;
        }
        if ( c[i] == 0 ) { continue; }
        int t = c[i];
        for ( int j = n ; j >= 0 ; j -- ) {
            dp[j + i*t ] = min( dp[ j+i*t], dp[ j ] + t );
        }
    }
    int ans = 1<<20;
    for ( int i = 1 ; i <= n ; i ++ ) { if ( lucky(i) ) { ans = min( ans, dp[i]-1 ); } }
    if ( ans == (1<<20) ) { cout << "-1\n"; }
    else { cout << ans << "\n"; }

    return 0;
}


#include <iostream>
using namespace std;
int n, m, p[100042], c[100042], dp[100042], cc[100042];

int getP ( int x ) {
    return x == p[x] ? x : p[x] = getP( p[x] );
}
bool lucky( int x ) {
    return x == 0 ? 1 : ( x == 4 || x == 7 )&&lucky(x/10);
}
int main () {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m;
    for ( int i = 0 ; i <= n ; i ++ ) { p[i] = i; }
    for ( int i = 0 ; i < m ; i ++ ) {
        int a, b;
        cin >> a >> b;
        p[ getP(a) ] = getP(b);
    }
    for ( int i = 1 ; i <= n ; i ++ ) { cc[ getP(i) ] ++; }
    for ( int i = 1 ; i <= n ; i ++ ) { c[ cc[i] ] ++; dp[i] = 1<<21; }
    dp[0] = 0;
    for ( int i = 1 ; i <= n ; i ++ ) {
        if ( c[i] == 0 ) { continue; }
        for ( int t = 1 ; t <= c[i] ; t *= 2 ) {
            for ( int j = n ; j >= 0 ; j -- ) {
                dp[j + i*t ] = min( dp[ j+i*t], dp[ j ] + t );
            }
            c[i] -= t;
        }
        if ( c[i] == 0 ) { continue; }
        int t = c[i];
        for ( int j = n ; j >= 0 ; j -- ) {
            dp[j + i*t ] = min( dp[ j+i*t], dp[ j ] + t );
        }
    }
    int ans = 1<<20;
    for ( int i = 1 ; i <= n ; i ++ ) { if ( lucky(i) ) { ans = min( ans, dp[i]-1 ); } }
    if ( ans == (1<<20) ) { cout << "-1\n"; }
    else { cout << ans << "\n"; }

    return 0;
}


#include <iostream>
using namespace std;
int n, m, p[1000042], c[1000042], dp[1000042], cc[1000042];

int getP ( int x ) {
    return x == p[x] ? x : p[x] = getP( p[x] );
}
bool lucky( int x ) {
    return x == 0 ? 1 : ( x%10 == 4 || x%10 == 7 )&& lucky(x/10);
}
int main () {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> m;
    for ( int i = 0 ; i <= n ; i ++ ) { p[i] = i; }
    for ( int i = 0 ; i < m ; i ++ ) {
        int a, b;
        cin >> a >> b;
        p[ getP(a) ] = getP(b);
    }
    for ( int i = 1 ; i <= n ; i ++ ) { cc[ getP(i) ] ++; }
    for ( int i = 1 ; i <= n ; i ++ ) { c[ cc[i] ] ++; dp[i] = 1<<21; }
    dp[0] = 0;
    for ( int i = 1 ; i <= n ; i ++ ) {
        if ( c[i] == 0 ) { continue; }
        for ( int t = 1 ; t <= c[i] ; t *= 2 ) {
            for ( int j = n ; j >= 0 ; j -- ) {
                dp[j + i*t ] = min( dp[ j+i*t], dp[ j ] + t );
            }
            c[i] -= t;
        }
        if ( c[i] == 0 ) { continue; }
        int t = c[i];
        for ( int j = n ; j >= 0 ; j -- ) {
            dp[j + i*t ] = min( dp[ j+i*t], dp[ j ] + t );
        }
    }
    int ans = 1<<20;
    for ( int i = 1 ; i <= n ; i ++ ) { if ( lucky(i) ) { ans = min( ans, dp[i]-1 ); } }
    if ( ans == (1<<20) ) { cout << "-1\n"; }
    else { cout << ans << "\n"; }

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define Nmax 100005
#define inf 1e9

using namespace std;

int n, m, a, b, r[Nmax], nr[Nmax], bun[Nmax], rsp[Nmax], ans = inf, l, viz[Nmax], fr[Nmax];
vector<int>g[Nmax];
void dfs(int nod)
{
    nr[l]++;
    viz[nod] = 1;
    for(int i = 0; i < g[nod].size(); i++)
    {
        int next = g[nod][i];
        if(!viz[next])
            dfs(next);
    }
}
int ok(int numar)
{
    while(numar)
    {
        if(numar % 10 != 4 && numar % 10 != 7)return 0;
        numar /= 10;
    }
    return 1;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> a >> b;
        g[a].pb(b);
        g[b].pb(a);
    }

    for(int i = 1; i <= n; i++)
    {
        if(!viz[i])
        {
            ++l;
            dfs(i);
            fr[nr[l]]++;
        }
    }
    for(int i = 1; i <= n; i++)
    {
        rsp[i] = inf;
        if(ok(i))
            bun[i] = 1;
    }
    ans = inf;
    for(int i = 1; i <= l; i++)
    {
        if(fr[nr[i]])
        {
            for(int q = 1; q <= fr[nr[i]]; q *= 2)
                for(int j = n; j >= nr[i] * q; j--)
                    if(rsp[j - nr[i] * q] != inf)
                        rsp[j] = min(rsp[j], rsp[j - nr[i] * q] + q);
            fr[nr[i]] = 0;
        }
    }

    for(int i = 1; i <= n; i++)
        if(bun[i] && ans > rsp[i] - 1)ans = rsp[i] - 1;
    if(ans == inf - 1 || ans == inf)cout << -1;
    else cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define Nmax 100005
#define inf 1e9

using namespace std;

int n, m, a, b, r[Nmax], nr[Nmax], bun[Nmax], rsp[Nmax], ans = inf, l, viz[Nmax];
vector<int>g[Nmax];
void dfs(int nod)
{
    nr[l]++;
    viz[nod] = 1;
    for(int i = 0; i < g[nod].size(); i++)
    {
        int next = g[nod][i];
        if(!viz[next])
            dfs(next);
    }
}
int ok(int numar)
{
    while(numar)
    {
        if(numar % 10 != 4 && numar % 10 != 7)return 0;
        numar /= 10;
    }
    return 1;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> a >> b;
        g[a].pb(b);
        g[b].pb(a);
    }

    for(int i = 1; i <= n; i++)
    {
        if(!viz[i])
        {
            r[++l] = i;
            dfs(i);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        rsp[i] = inf;
        if(ok(i))
            bun[i] = 1;
    }
    ans = inf;
    for(int i = 1; i <= l; i++)
        for(int j = n; j >= nr[i]; j--)
            if(rsp[j - nr[i]] != inf)
                rsp[j] = min(rsp[j], rsp[j - nr[i]] + 1);

    for(int i = 1; i <= n; i++)
        if(bun[i] && ans > rsp[i] - 1)ans = rsp[i] - 1;
    if(ans == inf - 1)cout << -1;
    else cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define Nmax 100005
#define inf 1e9

using namespace std;

int n, m, a, b, r[Nmax], nr[Nmax], bun[Nmax], rsp[Nmax], ans = inf, l, viz[Nmax];
vector<int>g[Nmax];
void dfs(int nod)
{
    nr[l]++;
    viz[nod] = 1;
    for(int i = 0; i < g[nod].size(); i++)
    {
        int next = g[nod][i];
        if(!viz[next])
            dfs(next);
    }
}
int ok(int numar)
{
    while(numar)
    {
        if(numar % 10 != 4 && numar % 10 != 7)return 0;
        numar /= 10;
    }
    return 1;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> a >> b;
        g[a].pb(b);
        g[b].pb(a);
    }

    for(int i = 1; i <= n; i++)
    {
        if(!viz[i])
        {
            r[++l] = i;
            dfs(i);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        rsp[i] = inf;
        if(ok(i))
            bun[i] = 1;
    }
    ans = inf;
    for(int i = 1; i <= l; i++)
        for(int j = n; j >= nr[i]; j--)
            if(rsp[j - nr[i]] != inf)
                rsp[j] = min(rsp[j], rsp[j - nr[i]] + 1);

    for(int i = 1; i <= n; i++)
        if(bun[i] && ans > rsp[i] - 1)ans = rsp[i] - 1;
    if(ans == inf - 1 && ans != inf)cout << -1;
    else cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define Nmax 100005
#define inf 1e9

using namespace std;

int n, m, a, b, r[Nmax], nr[Nmax], bun[Nmax], rsp[Nmax], ans = inf, l, viz[Nmax];
vector<int>g[Nmax];
void dfs(int nod)
{
    nr[l]++;
    viz[nod] = 1;
    for(int i = 0; i < g[nod].size(); i++)
    {
        int next = g[nod][i];
        if(!viz[next])
            dfs(next);
    }
}
int ok(int numar)
{
    while(numar)
    {
        if(numar % 10 != 4 && numar % 10 != 7)return 0;
        numar /= 10;
    }
    return 1;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> a >> b;
        g[a].pb(b);
        g[b].pb(a);
    }

    for(int i = 1; i <= n; i++)
    {
        if(!viz[i])
        {
            r[++l] = i;
            dfs(i);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        rsp[i] = inf;
        if(ok(i))
            bun[i] = 1;
    }
    ans = inf;
    for(int i = 1; i <= l; i++)
        for(int j = n; j >= nr[i]; j--)
            if(rsp[j - nr[i]] != inf)
                rsp[j] = min(rsp[j], rsp[j - nr[i]] + 1);

    for(int i = 1; i <= n; i++)
        if(bun[i] && ans > rsp[i] - 1)ans = rsp[i] - 1;
    if(ans == inf - 1 || ans == inf)cout << -1;
    else cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define Nmax 100005
#define inf 1 << 30

using namespace std;

int n, m, a, b, r[Nmax], nr[Nmax], bun[Nmax], rsp[Nmax], ans = inf, l, viz[Nmax];
vector<int>g[Nmax];
void dfs(int nod)
{
    nr[l]++;
    viz[nod] = 1;
    for(int i = 0; i < g[nod].size(); i++)
    {
        int next = g[nod][i];
        if(!viz[next])
            dfs(next);
    }
}
int ok(int numar)
{
    while(numar)
    {
        if(numar % 10 != 4 && numar % 10 != 7)return 0;
        numar /= 10;
    }
    return 1;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> a >> b;
        g[a].pb(b);
        g[b].pb(a);
    }

    for(int i = 1; i <= n; i++)
    {
        if(!viz[i])
        {
            r[++l] = i;
            dfs(i);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        rsp[i] = inf;
        if(ok(i))
            bun[i] = 1;
    }

    for(int i = 1; i <= l; i++)
        for(int j = n; j >= nr[i]; j--)
            rsp[j] = min(rsp[j], rsp[j - nr[i]] + 1);

    for(int i = 1; i <= n; i++)
        if(bun[i] && ans > rsp[i] - 1)ans = rsp[i] - 1;
    if(ans == inf)cout << -1;
    else cout << ans;

    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define Nmax 100005
#define inf 1e9

using namespace std;

int n, m, a, b, r[Nmax], nr[Nmax], bun[Nmax], rsp[Nmax], ans = inf, l, viz[Nmax], fr[Nmax];
vector<int>g[Nmax];
void dfs(int nod)
{
    nr[l]++;
    viz[nod] = 1;
    for(int i = 0; i < g[nod].size(); i++)
    {
        int next = g[nod][i];
        if(!viz[next])
            dfs(next);
    }
}
int ok(int numar)
{
    while(numar)
    {
        if(numar % 10 != 4 && numar % 10 != 7)return 0;
        numar /= 10;
    }
    return 1;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        cin >> a >> b;
        g[a].pb(b);
        g[b].pb(a);
    }

    for(int i = 1; i <= n; i++)
    {
        if(!viz[i])
        {
            ++l;
            dfs(i);
            fr[nr[l]]++;
        }
    }
    for(int i = 1; i <= n; i++)
    {
        rsp[i] = inf;
        if(ok(i))
            bun[i] = 1;
    }
    ans = inf;
    for(int i = 1; i <= l; i++)
    {
        if(fr[nr[i]])
        {
            for(int q = 1; q <= fr[nr[i]]; q *= 2)
                for(int j = n; j >= nr[i] * q; j--)
                    if(rsp[j - nr[i] * q] != inf)
                        rsp[j] = min(rsp[j], rsp[j - nr[i] * q] + q);
        }
    }

    for(int i = 1; i <= n; i++)
        if(bun[i] && ans > rsp[i] - 1)ans = rsp[i] - 1;
    if(ans == inf - 1 || ans == inf)cout << -1;
    else cout << ans;

    return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 100001
using namespace std;
const int maxn=100010;
int n,kl,islucky[maxn],tot,ans,v[maxn],m,T,head[maxn],indec,mo=1e9+7,b[maxn],a[maxn],f[maxn],x,y,z;
struct line{int fr,to,next;}q[4*maxn];
void pushline(int f,int t){q[++kl].next=head[f];q[kl].to=t;q[kl].fr=f,head[f]=kl;}
bool check(int x)
{
	while(x){if(x%10!=4&&x%10!=7)return 0;x/=10;}return 1;
}
int dfs(int x)
{
	b[x]=1;int ans=0;
	for(int p=head[x];p;p=q[p].next)
	if(!b[q[p].to])ans+=dfs(q[p].to);
	return ans+1;
}
void init()
{
	memset(head,0,sizeof(head));
	memset(b,0,sizeof(b));
	memset(f,127/3,sizeof(f));
	kl=0;indec=0;
}
int main()
{
	cin>>T;
	for(int i=1;i<=INF;i++)islucky[i]=check(i);
	while(T--)
	{
		init();
		cin>>n>>m;
		for(int i=1;i<=m;i++){cin>>x>>y;pushline(x,y);pushline(y,x);}
		for(int i=1;i<=n;i++)
			if(!b[i])a[++indec]=dfs(i),v[indec]=1;
		sort(a+1,a+1+indec);
		for(int i=1;i<=indec;i++)
		{
		//	cout<<a[i]<<" ";
			if(a[i]==a[i+1])v[i+1]+=v[i],a[i]=INF;
		}
		//cout<<endl<<"d";
		for(int i=1;i<=indec;i++)
		//	cout<<a[i]<<" "<<v[i]<<endl;

		ans=INF;
		f[0]=0;
		for(int i=1;i<=indec;i++)
		{
			if(a[i]==INF)continue;
			for(int k=1;k<=v[i];k=k<<1)
			{
				for(int j=n;j>=a[i]*k;j--)
				{
					f[j]=min(f[j],f[j-k*a[i]]+k);
					if(islucky[j])ans=min(ans,f[j]);
				}
			}

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

}


/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . ___
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         ¡¤e¡Á?¡À¡ê¨®¨®       ¨®¨¤?TBUG
*/
//use readint!
#pragma GCC optimize(3)
#pragma G++ optimize(3)
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-falign-functions")
#include<map>
#include<iostream>
#include<iomanip>
//#include<conio.h>
#include<algorithm>
#include<bits/stdc++.h>
#include<vector>
#include<cmath>
#include<stdio.h>
#include<fstream>
#include<map>
#include<assert.h>
#include<time.h>
#include<queue>
#include<deque>
#include<stack>
#include<list>
#include<sstream>
#include<string.h>
#define mp make_pair
#define ll long long
#define all(v) v.begin(),v.end()
#define memset(a,b) memset(a,b,sizeof(a))
using namespace std;
const int INF=1e9;
const int maxn=10005;
struct bign{
    int d[maxn], len;
    inline void clean() { while(len > 1 && !d[len-1]) len--; }
    inline bign()          { memset(d, 0); len=1; }
    inline bign(int num)   { *this=num; }
    inline bign(char* num) { *this=num; }
    inline bign operator=(const char* num){
        memset(d, 0); len=strlen(num);
        for(int i=0; i<len; i++) d[i]=num[len-1-i] - '0';
        clean();
        return *this;
    }
    inline bign operator=(int num){
        char s[20]; sprintf(s, "%d", num);
        *this=s;
        return *this;
    }
    inline bign operator + (const bign& b){
        bign c=*this; int i;
        for (i=0; i<b.len; i++){
            c.d[i] +=b.d[i];
            if (c.d[i] > 9) c.d[i]%=10, c.d[i+1]++;
        }
        while (c.d[i] > 9) c.d[i++]%=10, c.d[i]++;
        c.len=max(len, b.len);
        if (c.d[i] && c.len<=i) c.len=i+1;
        return c;
    }
	inline bign operator - (const bign& b){
        bign c=*this; int i;
        for (i=0; i<b.len; i++){
            c.d[i] -=b.d[i];
            if (c.d[i]<0) c.d[i]+=10, c.d[i+1]--;
        }
        while (c.d[i]<0) c.d[i++]+=10, c.d[i]--;
        for(i=c.len-1;i>0;i--) if(c.d[i]!=0) break;
        c.len=i+1;
//      c.clean();
        return c;
    }
    inline bign operator * (const bign& b)const{
        int i, j; bign c; c.len=len + b.len;
        for(j=0; j<b.len; j++) for(i=0; i<len; i++)
            c.d[i+j] +=d[i] * b.d[j];
        for(i=0; i<c.len-1; i++)
            c.d[i+1] +=c.d[i]/10, c.d[i] %=10;
        c.clean();
        return c;
    }
    inline bign operator / (const bign& b){
        int i, j;
        bign c=*this, a=0;
        for (i=len - 1; i >=0; i--)
        {
            a=a*10 + d[i];
            for (j=0; j<10; j++) if (a<b*(j+1)) break;
            c.d[i]=j;
            a=a - b*j;
        }
        c.clean();
        return c;
    }
    inline bign operator % (const bign& b){
        int i, j;
        bign a=0;
        for (i=len-1;i>=0;i--){
            a=a*10 + d[i];
            for (j=0; j<10; j++) if (a<b*(j+1)) break;
            a=a - b*j;
        }
        return a;
    }
    inline bign operator += (const bign& b){
        *this=*this + b;
        return *this;
    }
    inline bign operator *= (const bign& b){
    	*this=*this * b;
    	return *this;
	}
	inline bign operator -= (const bign& b){
		*this=*this - b;
		return *this;
	}
	inline bign operator /= (const bign& b){
		*this=*this / b;
		return *this;
	}
    inline bool operator < (const bign& b) const{
        if(len !=b.len) return len<b.len;
        for(int i=len-1; i >=0; i--)
            if(d[i] !=b.d[i]) return d[i]<b.d[i];
        return false;
    }
    inline bool operator >(const bign& b) const{return b<*this;}
    inline bool operator<=(const bign& b) const{return !(b<*this);}
    inline bool operator>=(const bign& b) const{return !(*this<b);}
    inline bool operator!=(const bign& b) const{return b<*this || *this<b;}
    inline bool operator==(const bign& b) const{return !(b<*this) && !(b > *this);}
    inline string str() const{
        char s[maxn]={};
        for(int i=0; i<len; i++) s[len-1-i]=d[i]+'0';
        return s;
    }
};

inline istream& operator >>(istream& in, bign& x)
{
    string s;
    in>>s;
    x=s.c_str();
    return in;
}

inline ostream& operator << (ostream& out, const bign& x)
{
    out<<x.str();
    return out;
}
inline void write(ll x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
inline int pt(int a[],int l,int r){
	int p,i,j;
	p=a[l];
	i=l;
	j=r+1;
	for(;;){
		while(a[++i]<p) if(i>=r) break;
		while(a[--j]>p) if(j<=l) break;
		if(i>=j) break;
		else swap(a[i],a[j]);
	}
	if(j==l) return j;
	swap(a[l],a[j]);
	return j;
}
inline void q_sort(int a[],int l,int r){
	int q;
	if(r>l){
		q=pt(a,l,r);
		q_sort(a,l,q-1);
		q_sort(a,q+1,r);
	}
}
inline void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
inline void rd(long long &val){
    long long x=0;
    int f=1;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if(ch=='-'){
		f=-1;
		ch=getchar();
	}
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    val=x*f;
}
inline void rd(int &val){
    int x=0;
    int f=1;
    char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if(ch=='-'){
		f=-1;
		ch=getchar();
	}
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    val=x*f;
}
inline void print(int x){
	write(x);
	putchar('\n');
}
bool vis[100005];
int n,m,col;
vector<int> have[100005];
int cnt[100005];
vector<int> v[100005];
int Cnt[100005];
int bad[]={10,100,1000,10000,100000};
int badcnt[5];
unordered_map<int,int> ma;
unordered_map<int,bool> lu;
vector<int> lucks;
inline void dfs(int x){
	if(vis[x]) return;
	vis[x]=1;
	have[col].push_back(x);
	cnt[col]++;
	for(int i=0;i<v[x].size();i++) dfs(v[x][i]);
}
inline void search(int x,int y){
	if(x==7) return;
	if(y) lu[y]=1,lucks.push_back(y);
	search(x+1,y*10+4);
	search(x+1,y*10+7);
}
inline int fd(int x){
	int t=lower_bound(lucks.begin(),lucks.end(),x)-lucks.begin();
	return lucks[t];
}
int main(){
	ios_base::sync_with_stdio(false);
	int i,j,x,y;
	search(0,0);
//	for(map<int,bool>::iterator  it=lu.begin();it!=lu.end();it++) cout<<it->first<<" ";
//	cout<<endl;
	rd(n);
	rd(m);
	for(i=1;i<=m;i++){
		rd(x);
		rd(y);
		if(x==y) continue;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for(i=1;i<=n;i++)
		if(!vis[i]){
			++col;
			dfs(i);
		}
	int now=1,lst=0;
	ma[0]=0;
	int ans=INF;
	bool ne=0;
	sort(cnt+1,cnt+1+col);
	int cnt1=0;
	for(i=1;i<=col;i++)
		if(cnt[i]==1)
			cnt1++;
	for(i=1;i<=col;i++)
		if(cnt[i]!=1&&fd(cnt[i])-cnt[i]<=cnt1)
			ans=min(ans,fd(cnt[i])-cnt[i]);
	for(i=1;i<=col;i++) Cnt[cnt[i]]++;
	int badgs=0;
	for(i=0;i<5;i++) if(Cnt[bad[i]]==col) badgs++;
	if(badgs==1){
		cout<<-1<<endl;
		return 0;
	}
	for(i=1;i<=col;i++){
		if(lu[cnt[i]]){
			print(0);
			return 0;
		}
		unordered_map<int,int> ma2;
		for(unordered_map<int,int>::iterator it=ma.begin();it!=ma.end();it++){
			if(it->second>ans) continue;
			int tt=cnt[i]+it->first,t2=it->second+1;
			ma2[it->first]=t2-1;
			if(lu[tt]) ans=min(ans,t2-1);
			else{
				if(!ma2.count(tt)) ma2[tt]=t2;
				else ma2[tt]=min(ma2[tt],t2);
			}
		}
		ma=ma2;
	}
	if(ans==INF) ans=-1;
	print(ans);
	return 0;
}


#include<bits/stdc++.h>
//#define int long long
using namespace std;
//<fastIO>
inline int read(){int sum=0,fushu=1;char c=getchar();while(!isdigit(c)){if(c=='-') fushu=-fushu;c=getchar();}while(isdigit(c)){sum=sum*10+(c^48);c=getchar();}return sum*fushu;}
void write(int x){if(x<0) putchar('-'),x=-x;if(x>=10) write(x/10);putchar(x%10+48);}
inline void writeln(int x){write(x);putchar('\n');}
//</fastIO>
int const maxn=1e5+5;
int n,m,top,w[maxn],c[maxn],father[maxn],size[maxn],num[maxn],f[maxn];
inline bool check(int x){
	for(;x;x/=10)
	  if(x%10!=4 && x%10!=7) return false;
	return true;
}
int find(int x){
	if(father[x]!=x) father[x]=find(father[x]);
	return father[x];
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)
	  father[i]=i,size[i]=1;
	for(int i=1;i<=m;i++){
		int x=read(),y=read();
		int r1=find(x),r2=find(y);
		if(r1!=r2){
			father[r1]=r2;
			size[r2]+=size[r1];
			size[r1]=0;
		}
	}
	for(int i=1;i<=n;i++)
	  if(find(i)==i) num[size[i]]++;
	for(int i=1;i<=n;i++){
		int now=1,rest=num[i];
		while(now<=rest){
			w[++top]=now*i;
			c[top]=now;
		    rest-=now;
		    now<<=1;
		}
		if(rest) w[++top]=rest*i,c[top]=rest;
	}
	memset(f,0x3f,sizeof(f));
	f[0]=0;
	for(int i=1;i<=top;i++)
	  for(int j=n;j>=w[i];j--)
	    f[j]=min(f[j],f[j-w[i]]+c[i]);
	int ans=1e8;
	for(int i=1;i<=n;i++)
	  if(f[i] && check(i))
	    ans=min(ans,f[i]);
	if(ans>=1e8) ans=0;
	writeln(ans-1);
	return 0;
}


#include<bits/stdc++.h>
//#define int long long
using namespace std;
//<fastIO>
inline int read(){int sum=0,fushu=1;char c=getchar();while(!isdigit(c)){if(c=='-') fushu=-fushu;c=getchar();}while(isdigit(c)){sum=sum*10+(c^48);c=getchar();}return sum*fushu;}
void write(int x){if(x<0) putchar('-'),x=-x;if(x>=10) write(x/10);putchar(x%10+48);}
inline void writeln(int x){write(x);putchar('\n');}
//</fastIO>
int const maxn=1e5+5;
int n,m,top,w[maxn],father[maxn],size[maxn],num[maxn],f[maxn];
inline bool check(int x){
	for(;x;x/=10)
	  if(x%10!=4 && x%10!=7) return false;
	return true;
}
int find(int x){
	if(father[x]!=x) father[x]=find(father[x]);
	return father[x];
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)
	  father[i]=i,size[i]=1;
	for(int i=1;i<=m;i++){
		int x=read(),y=read();
		int r1=find(x),r2=find(y);
		if(r1!=r2){
			father[r1]=r2;
			size[r2]+=size[r1];
			size[r1]=0;
		}
	}
	for(int i=1;i<=n;i++)
	  if(find(i)==i) num[size[i]]++;
	for(int i=1;i<=n;i++){
		int now=1,rest=num[i];
		while(now<=rest){
			w[++top]=now*i;
		    rest-=now;
		    now<<=1;
		}
		if(rest) w[++top]=rest*i;
	}
	memset(f,0x3f,sizeof(f));
	f[0]=0;
	for(int i=1;i<=top;i++)
	  for(int j=n;j>=w[i];j--)
	    f[j]=min(f[j],f[j-w[i]]+1);
	int ans=1e8;
	for(int i=1;i<=n;i++)
	  if(f[i] && check(i))
	    ans=min(ans,f[i]);
	if(ans>=1e8) ans=0;
	writeln(ans-1);
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cassert>
#include<cmath>
#include<sstream>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
using namespace std;
int lucky[105],lcnt;
void init()
{
	queue<string> q;
	q.push("4");q.push("7");
	while(!q.empty())
	{
		string tmp=q.front();
		q.pop();
		stringstream ss;
		ss<<tmp;
		int x;
		ss>>x;
		lucky[lcnt++]=x;
		if(x>10005)continue;
		q.push(tmp+"4");
		q.push(tmp+"7");
	}
}

vector<int> nei[100005];
int gro;
int siz[100005];
bool vis[100005];
void dfs(int v)
{
	if(vis[v]) return;
	vis[v]=1;
	siz[gro]++;
	for(int i=0;i<nei[v].size();i++)
	{
		int u=nei[v][i];
		dfs(u);
	}
}
int n,m;
int dp[500005];
void solve(int x,int y)
{
	for(int i=n;i>=x;i--)
	{
		if(dp[i-x]!=-1)
		{
			if(dp[i]!=-1)dp[i]=min(dp[i-x]+y,dp[i]); else dp[i]=dp[i-x]+y;
//			cout<<i<<" "<<dp[i]<<endl;
		}
	}
}
int main()
{
	init();
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		x--,y--;
		nei[x].push_back(y);
		nei[y].push_back(x);
	}
	map<int,int> num;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])
		{
			dfs(i);
			num[siz[gro]]++;
			gro++;
		}
	}
	memset(dp,-1,sizeof dp);
	dp[0]=0;
	map<int,int>::iterator it=num.begin();
	for(;it!=num.end();it++)
	{
		int x=it->first,y=it->second;
		while(y)
		{
			solve((((y+1)>>1))*x,((y+1)>>1));
			y>>=1;
		}
	}
	int mi=1e9;
	for(int i=0;i<lcnt;i++)
	{
		if(dp[lucky[i]]!=-1)mi=min(dp[lucky[i]],mi);
	}
	if(mi!=1e9)cout<<mi-1; else cout<<-1;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cassert>
#include<cmath>
#include<sstream>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
using namespace std;
int lucky[105],lcnt;
void init()
{
	queue<string> q;
	q.push("4");q.push("7");
	while(!q.empty())
	{
		string tmp=q.front();
		q.pop();
		stringstream ss;
		ss<<tmp;
		int x;
		ss>>x;
		lucky[lcnt++]=x;
		if(x>10005)continue;
		q.push(tmp+"4");
		q.push(tmp+"7");
	}
}

vector<int> nei[100005];
int gro;
int siz[100005];
bool vis[100005];
void dfs(int v)
{
	if(vis[v]) return;
	vis[v]=1;
	siz[gro]++;
	for(int i=0;i<nei[v].size();i++)
	{
		int u=nei[v][i];
		dfs(u);
	}
}
int n,m;
int dp[500005];
void solve(int x,int y)
{
	for(int i=n;i>=x;i--)
	{
		if(dp[i-x]!=-1)
		{
			if(dp[i]!=-1)dp[i]=min(dp[i-x]+y,dp[i]); else dp[i]=dp[i-x]+y;
//			cout<<i<<" "<<dp[i]<<endl;
		}
	}
}
int main()
{
	init();
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		x--,y--;
		nei[x].push_back(y);
		nei[y].push_back(x);
	}
	map<int,int> num;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])
		{
			dfs(i);
			num[siz[gro]]++;
			gro++;
		}
	}
	memset(dp,-1,sizeof dp);
	dp[0]=0;
	map<int,int>::iterator it=num.begin();
	for(;it!=num.end();it++)
	{
		int x=it->first,y=it->second;
//		cout<<x<<" "<<y<<"haha"<<endl;
		for(int j=1;j<y;j<<=1)
		{
			solve(j*x,j);
			y-=j;
		}
		solve(y*x,y);
	}
	int mi=1e9;
	for(int i=0;i<lcnt;i++)
	{
		if(dp[lucky[i]]!=-1)mi=min(dp[lucky[i]],mi);
	}
	if(mi!=1e9)cout<<mi-1; else cout<<-1;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cassert>
#include<cmath>
#include<sstream>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
using namespace std;
int lucky[105],lcnt;
void init()
{
	queue<string> q;
	q.push("4");q.push("7");
	while(!q.empty())
	{
		string tmp=q.front();
		q.pop();
		stringstream ss;
		ss<<tmp;
		int x;
		ss>>x;
		lucky[lcnt++]=x;
		if(x>10005)continue;
		q.push(tmp+"4");
		q.push(tmp+"7");
	}
}

vector<int> nei[100005];
int gro;
int siz[100005];
bool vis[100005];
void dfs(int v)
{
	if(vis[v]) return;
	vis[v]=1;
	siz[gro]++;
	for(int i=0;i<nei[v].size();i++)
	{
		int u=nei[v][i];
		dfs(u);
	}
}
int n,m;
int dp[500005];
void solve(int x,int y)
{
	for(int i=n;i>=x;i--)
	{
		if(dp[i-x]!=-1)
		{
			if(dp[i]!=-1)dp[i]=min(dp[i-x]+y,dp[i]); else dp[i]=dp[i-x]+y;
//			cout<<i<<" "<<dp[i]<<endl;
		}
	}
}
int main()
{
	init();
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		x--,y--;
		nei[x].push_back(y);
		nei[y].push_back(x);
	}
	map<int,int> num;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])
		{
			dfs(i);
			num[siz[gro]]++;
			gro++;
		}
	}
	memset(dp,-1,sizeof dp);
	dp[0]=0;
	map<int,int>::iterator it=num.begin();
	for(;it!=num.end();it++)
	{
		int x=it->first,y=it->second;
		while(y)
		{
			solve((((y+1)>>1))*x,((y+1)>>1));
			y>>=1;
		}
	}
	int mi=1e9;
	for(int i=0;i<lcnt;i++)
	{
		if(dp[lucky[i]]!=-1)mi=min(dp[lucky[i]],mi);
	}
	if(mi!=1e9)cout<<mi-1; else cout<<-1;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cassert>
#include<cmath>
#include<sstream>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
using namespace std;
int lucky[105],lcnt;
void init()
{
	queue<string> q;
	q.push("4");q.push("7");
	while(!q.empty())
	{
		string tmp=q.front();
		q.pop();
		stringstream ss;
		ss<<tmp;
		int x;
		ss>>x;
		lucky[lcnt++]=x;
		if(x>10005)continue;
		q.push(tmp+"4");
		q.push(tmp+"7");
	}
}

vector<int> nei[100005];
int gro;
int siz[100005];
bool vis[100005];
void dfs(int v)
{
	if(vis[v]) return;
	vis[v]=1;
	siz[gro]++;
	for(int i=0;i<nei[v].size();i++)
	{
		int u=nei[v][i];
		dfs(u);
	}
}
int n,m;
int dp[500005];
void solve(int x)
{
	for(int i=n;i>=x;i--)
	{
		if(dp[i-x]!=-1)
		{
			if(dp[i]!=-1)dp[i]=min(dp[i-x]+1,dp[i]); else dp[i]=dp[i-x]+1;
//			cout<<i<<" "<<dp[i]<<endl;
		}
	}
}
int main()
{
	init();
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		cin>>x>>y;
		x--,y--;
		nei[x].push_back(y);
		nei[y].push_back(x);
	}
	map<int,int> num;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])
		{
			dfs(i);
			num[siz[gro]]++;
			gro++;
		}
	}
	memset(dp,-1,sizeof dp);
	dp[0]=0;
	map<int,int>::iterator it=num.begin();
	for(;it!=num.end();it++)
	{
		int x=it->first,y=it->second;
	//	cout<<x<<" "<<y<<"haha"<<endl;
		for(int j=1;j<y;j<<=1)
		{
			solve(j*x);
			y-=j;
		}
		solve(y*x);
	}
	int mi=1e9;
	for(int i=0;i<lcnt;i++)
	{
		if(dp[lucky[i]]!=-1)mi=min(dp[lucky[i]],mi);
	}
	if(mi!=1e9)cout<<mi-1; else cout<<-1;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cassert>
#include<cmath>
#include<sstream>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<tr1/unordered_map>
using namespace std;
using namespace std::tr1;
int lucky[105],lcnt;
void init()
{
	queue<string> q;
	q.push("4");q.push("7");
	while(!q.empty())
	{
		string tmp=q.front();
		q.pop();
		stringstream ss;
		ss<<tmp;
		int x;
		ss>>x;
		lucky[lcnt++]=x;
		if(x>10005)continue;
		q.push(tmp+"4");
		q.push(tmp+"7");
	}
}

vector<int> nei[100005];
int gro;
int siz[100005];
bool vis[100005];
void dfs(int v)
{
	if(vis[v]) return;
	vis[v]=1;
	siz[gro]++;
	for(int i=0;i<nei[v].size();i++)
	{
		int u=nei[v][i];
		dfs(u);
	}
}
int n,m;
int dp[500005];
void solve(int x,int y)
{
	for(int i=n;i>=x;i--)
	{
		if(dp[i-x]!=-1)
		{
			if(dp[i]!=-1)dp[i]=min(dp[i-x]+y,dp[i]); else dp[i]=dp[i-x]+y;
//			cout<<i<<" "<<dp[i]<<endl;
		}
	}
}
int main()
{
	init();
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		x--,y--;
		nei[x].push_back(y);
		nei[y].push_back(x);
	}
	unordered_map<int,int> num;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])
		{
			dfs(i);
			num[siz[gro]]++;
			gro++;
		}
	}
	memset(dp,-1,sizeof dp);
	dp[0]=0;
	unordered_map<int,int>::iterator it=num.begin();
	for(;it!=num.end();it++)
	{
		int x=it->first,y=it->second;
		while(y)
		{
			solve((((y+1)>>1))*x,((y+1)>>1));
			y>>=1;
		}
	}
	int mi=1e9;
	for(int i=0;i<lcnt;i++)
	{
		if(dp[lucky[i]]!=-1)mi=min(dp[lucky[i]],mi);
	}
	if(mi!=1e9)cout<<mi-1; else cout<<-1;
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cassert>
#include<cmath>
#include<sstream>
#include<fstream>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<tr1/unordered_map>
using namespace std;
using namespace std::tr1;
int lucky[105],lcnt;
void init()
{
	queue<string> q;
	q.push("4");q.push("7");
	while(!q.empty())
	{
		string tmp=q.front();
		q.pop();
		stringstream ss;
		ss<<tmp;
		int x;
		ss>>x;
		lucky[lcnt++]=x;
		if(x>10005)continue;
		q.push(tmp+"4");
		q.push(tmp+"7");
	}
}

vector<int> nei[100005];
int gro;
int siz[100005];
bool vis[100005];
void dfs(int v)
{
	if(vis[v]) return;
	vis[v]=1;
	siz[gro]++;
	for(int i=0;i<nei[v].size();i++)
	{
		int u=nei[v][i];
		dfs(u);
	}
}
int n,m;
int dp[500005];
void solve(int x,int y)
{
	for(int i=n;i>=x;i--)
	{
		if(dp[i-x]!=-1)
		{
			if(dp[i]!=-1)dp[i]=min(dp[i-x]+y,dp[i]); else dp[i]=dp[i-x]+y;
//			cout<<i<<" "<<dp[i]<<endl;
		}
	}
}
int main()
{
	init();
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int x,y;
		scanf("%d %d",&x,&y);
		x--,y--;
		nei[x].push_back(y);
		nei[y].push_back(x);
	}
	map<int,int> num;
	for(int i=0;i<n;i++)
	{
		if(!vis[i])
		{
			dfs(i);
			num[siz[gro]]++;
			gro++;
		}
	}
	memset(dp,-1,sizeof dp);
	dp[0]=0;
	map<int,int>::iterator it=num.begin();
	for(;it!=num.end();it++)
	{
		int x=it->first,y=it->second;
		while(y)
		{
			solve((((y+1)>>1))*x,((y+1)>>1));
			y>>=1;
		}
	}
	int mi=1e9;
	for(int i=0;i<lcnt;i++)
	{
		if(dp[lucky[i]]!=-1)mi=min(dp[lucky[i]],mi);
	}
	if(mi!=1e9)cout<<mi-1; else cout<<-1;
	return 0;
}


#include<iostream>
using namespace std;

int sama(string a, string b){
	if(a.length()%2==1) return a==b;
	int i=a.length()/2;
	string a1=a.substr(0, i);
	string a2=a.substr(i, a.length());
	string b1=b.substr(0, i);
	string b2=b.substr(i, b.length());

	return sama(a1, b1) && sama(a2, b2);
	return sama(a1, b2) && sama(a2, b1);
}

int main(){
	string a, b;
	cin >> a >> b;
	if(sama(a,b)) printf("YES\n");
	else printf("NO\n");
	return 0;
}


#include<iostream>
using namespace std;

int sama(string a, string b){
	if(a.length()%2==1) return a==b;
	int i=a.length()/2;
	string a1=a.substr(0, i);
	string a2=a.substr(i, a.length());
	string b1=b.substr(0, i);
	string b2=b.substr(i, b.length());

	return ((sama(a1, b1) && sama(a2, b2)) || (sama(a1, b2)&&sama(a2, b1)));
}

int main(){
	string a, b;
	cin >> a >> b;
	if(sama(a,b)) printf("YES\n");
	else printf("NO\n");
	return 0;
}


#include<iostream>
#include<string>
using namespace std;

bool sama(string a, string b){
	bool x=a.compare(b)==0;
	if(a.length()%2==1 || x) return x;
	int i=a.length()/2;
	string a1=a.substr(0, i);
	string a2=a.substr(i);
	string b1=b.substr(0, i);
	string b2=b.substr(i);

	if(sama(a1, b2) && sama(a2, b1)) return true;
	else return (sama(a1, b1) && sama(a2, b2));
}

int main(){
	string a, b;
	cin >> a >> b;
	if(sama(a,b)) cout << "YES\n";
	else cout << "NO\n";
	return 0;
}


#include<iostream>
#include<vector>
using namespace std;

int main(){
	string a, b;
	cin >> a >> b;
	int x=a.length();
	while(x%2==0) x/=2;
	vector<string> s;
	vector<string> k;
	int flag=0;
	for(int i=0; i<a.length(); i+=x){
		s.push_back(a.substr(i, x));
		k.push_back(b.substr(i, x));
	}
	if(a.length()%2!=0 || a.length()!=b.length())
	{
		if(a.compare(b)) flag=1;
	}
	else if(a.length()>=4){
		int j=0;
		while(s.size()!=0){
			string a1=s[j];
			string c1=k[j];
			string a2=s[j+1];
			string c2=k[j+1];
			string b1=k[j+2];
			string d1=s[j+2];
			string b2=k[j+3];
			string d2=s[j+3];
			s.erase(s.begin(), s.begin()+4);
			k.erase(k.begin(), k.begin()+4);

			if((a1.compare(b1)==0 && a2.compare(b2)==0) && (c1.compare(d1)==0 && c2.compare(d2)==0) || (a1.compare(b2)==0 && a2.compare(b1)==0) && (c1.compare(d2)==0 && c2.compare(d1)==0))  {}
			else flag=1;
		}
	}
		if(flag==1) cout << "NO" << endl;
		else cout << "YES" << endl;
	return 0;
}


#include<iostream>
#include<string>
using namespace std;

bool sama(string a, string b){
	bool x=a.compare(b)==0;
	if(a.length()%2==1 || x) return x;
	int i=a.length()/2;
	string a1=a.substr(0, i);
	string a2=a.substr(i);
	string b1=b.substr(0, i);
	string b2=b.substr(i);

	if(sama(a1, b2) && sama(a2, b1)) return true;
	else return (sama(a1, b2) && sama(a2, b1));
}

int main(){
	string a, b;
	cin >> a >> b;
	if(sama(a,b)) cout << "YES\n";
	else cout << "NO\n";
	return 0;
}


#include<iostream>
using namespace std;

int sama(string a, string b){
	if(a.length()%2==1) return a==b;
	int i=a.length()/2;
	string a1=a.substr(0, i);
	string a2=a.substr(i, a.length());
	string b1=b.substr(0, i);
	string b2=b.substr(i, b.length());

	if(sama(a1, b1) && sama(a2, b2)) return 1;
	else return sama(a1, b2) && sama(a2, b1);
}

int main(){
	string a, b;
	cin >> a >> b;
	if(sama(a,b)) printf("YES\n");
	else printf("NO\n");
	return 0;
}


#include<iostream>
#include<vector>
using namespace std;

int main(){
	string a, b;
	cin >> a >> b;
	int x=a.length();
	while(x%2==0) x/=2;
	vector<string> s;
	vector<string> k;
	int flag=0;
	for(int i=0; i<a.length(); i+=x){
		s.push_back(a.substr(i, x));
		k.push_back(b.substr(i, x));
	}
		int j=0;
		while(s.size()!=0){
			string a1=s[j];
			string c1=k[j];
			string a2=s[j+1];
			string c2=k[j+1];
			string b1=k[j+2];
			string d1=s[j+2];
			string b2=k[j+3];
			string d2=s[j+3];
			s.erase(s.begin(), s.begin()+4);
			k.erase(k.begin(), k.begin()+4);

			if(a1.compare(b1)==0 && a2.compare(b2)==0) {}
			else if(a1.compare(b2)==0 && a2.compare(b1)==0) {
			}
			else flag=1;
			if(c1.compare(d1)==0 && c2.compare(d2)==0){
			}
			else if(c1.compare(d2)==0 && c2.compare(d1)==0) {
			}
			else flag=1;
		}
	if(flag==1) cout << "NO" << endl;
	else cout << "YES" << endl;
	return 0;
}


#include <bits/stdc++.h>
#define MAX 100000000000000000

using namespace std;

bool check(string a,string b)
{
    for(int i=0;i<a.length();i++){
        if(a[i]!=b[i]) return false;
    }
    return true;
}

int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    string s1,s2;
    cin>>s1>>s2;
    if(check(s1,s2)) printf("YES");
    else if(s1.size()%2){
        printf("NO");
    }else{
        int mid1=s1.size()/2,mid2=s2.size()/2;
        string t11,t12,t21,t22;
        t11=s1.substr(0,mid1);
        t12=s1.substr(mid1,mid1);
        t21=s2.substr(0,mid2);
        t22=s2.substr(mid2,mid2);
//        cout<<t11<<" "<<t12<<" "<<t21<<" "<<t22<<endl;

        if(check(t12,t21) || check(t12,t22)) cout<<"YES";
        else cout<<"NO";
    }

}