/*
折半搜索 降低次数 k^n-> k^n/2 * 2
从 始末状态取搜索 相遇就是答案
因为牵一发而动全身 所以-》 ^ 加上位运算
与相连的边 ^(1<<b)
因为 ans<=n 因为重复更改不如不更改
每次搜索都可以选或不选
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
//#include<queue>
//#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e2+10 ;
const int inf=0x3f3f3f3f;
const int mod=2003;
map<ll,int> mp;
ll v[maxn],sta;
int n,m,ans=inf;
void dfs(int pos,int lim,ll val,int dis)
{
if(mp[val]) mp[val]=min(mp[val],dis);
else mp[val]=dis;
if(mp[val^sta]){
ans=min(ans,mp[val^sta]+dis);
return;
}
if(pos<=lim){
dfs(pos+1,lim,val^v[pos],dis+1);
dfs(pos+1,lim,val,dis);
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b;cin>>a>>b;
v[a]^=(1<<b);
v[b]^=(1<<a);
}
for(int i=1;i<=n;i++){
v[i]^=(1<<i);
sta^=(1<<i);
}
dfs(1,n/2,0,0);
dfs(n/2+1,n,0,0);
cout<<ans<<'\n';
return 0;
}