#include<bits/stdc++.h>
using namespace std;
const int N = 110;
bool g[N][N];
//q[n]中每个元素又包含一个int型数组
//这里可以表示为第N个考场中有多少个人
vector<int>q[N];
//ans有几间考场
int ans = 99999999999999;
//n个人 m组关系
int n,m;
//i为考场编号,b为check人编号
bool check(int i, int b){
//拿到该考场的人数
int s = q[i].size();
for(int j = 0; j < s; j++)
if(g[b][q[i][j]]) return false;
return true;
}
//now当前人编号,cnt当前考场数
void dfs(int now, int cnt){
//剪枝,若当前方案考场数比之前的方案考场数还要大,则没必要继续了
if(cnt >= ans) return ;
//结束 -读到的人编号超过总人数
if(now==n+1){
ans = min(ans,cnt);
return;
}
//遍历每一个考场
for(int p = 1; p <= cnt; p++){
if(check(p,now)){
//若now可插入p考场
q[p].push_back(now);
//继续深度搜索,now+1个人开始,考场数没变
dfs(now+1,cnt);
//弹出以便考虑now可能进入其他考场的情况
q[p].pop_back();
}
}
//否则开辟新考场
if(cnt+1 <= n){
//同理上一个if
q[cnt+1].push_back(now);
dfs(now+1,cnt+1);
q[cnt+1].pop_back();
}
}
int main(){
cin>>n>>m;
for(int i = 0;i < m; i++){
int a,b;
cin>>a>>b;
//两个认识的人建立边
g[a][b]=1;
g[b][a]=1;
}
//第一个人开始,默认先有一个考场
dfs(1,1);
cout<<ans<<endl;
return 0;
}
/*
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
*/