#include<bits/stdc++.h>
using namespace std;
int read(){
int x = 0,f = 0;char ch=getchar();
while(!isdigit(ch)){if(ch=='0')f=1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return f?-x:x;
}
const int N = 101010;
struct Edge{int to,nxt,flow,cap;}e[N<<1];
int head[N],cur[N],S,T,n,m,dis[N],cnt = 1;
queue<int> Q;
void add(int x,int y,int cap)
{
e[++cnt].cap = cap;e[cnt].flow = 0;e[cnt].nxt = head[x];e[cnt].to = y;head[x] = cnt;
e[++cnt].cap = 0; e[cnt].flow = 0;e[cnt].nxt = head[y];e[cnt].to = x;head[y] = cnt;
}
bool Bfs(int s,int t)
{
while(Q.size()) Q.pop();
memset(dis,0,sizeof(dis));
dis[s] = 1;Q.push(s);
while(Q.size())
{
int x = Q.front();Q.pop();
for(int i = head[x];i;i = e[i].nxt)
{
int y = e[i].to;
if(!dis[y] && e[i].cap > e[i].flow)
{
dis[y] = dis[x] + 1;
Q.push(y);
if(dis[t]){
return true;
}
}
}
}
return false;
}
int Dfs(int x,int a,int t)
{
if(x == t || a == 0) return a;
int flow = 0,f = 0;
for(int i = cur[x];i;i = e[i].nxt)
{
int y = e[i].to;
if(dis[y] == dis[x] + 1 && ((f = (Dfs(y,min(a,e[i].cap - e[i].flow),t))) > 0))
{
a -= f;
flow += f;
e[i].flow += f;
e[i^1].flow -= f;
if(a == 0) break;
cur[x] = e[i].nxt;
}
}
return flow;
}
int Ans = 0,col[N];
vector<int> G[N];
void dfs(int x,int Col)
{
col[x] = Col;
for(int i = 0;i < G[x].size();i++)
{
if(!col[G[x][i]]) dfs(G[x][i],3 - col[x]);
}
}
signed main()
{
n = read();m = read();
Ans = n;S = 0;T = n+1;
for(int i = 1;i <= m;i++)
{
int a = read()+1,b = read()+1;
G[a].push_back(b);G[b].push_back(a);
add(a,b,1);
add(b,a,1);
}
for(int i = 1;i <= n;i++) {
if(!col[i]) dfs(i,1);
}
for(int i = 1;i <= n;i++)
{
if(col[i] == 1) add(S,i,1);
if(col[i] == 2) add(i,T,1);
}
int maxflow = 0;
while(Bfs(S,T))
{
for(int i = 0;i <= n+1;i++) cur[i] = head[i];
maxflow += Dfs(S,0x3f3f3f3f,T);
}
cout<<Ans-maxflow<<endl;
return 0;
}