/*655.二分图-安排房间 (10分)
C时间限制:3000 毫秒 |  C内存限制:3000 Kb
题目内容:
 有一群学生,他们之间有的认识有的不认识。
现在要求把学生分成2组,其中同一个组的人相互不认识。如果你分成功了,那么就安排双人间,安排的规矩
是两个人分别属于不同的组,并且认识。
输入描述
首先输入两个整数n,m,表示有n个学生, m个认识对
随后m行表示认识的学生对。

输出描述
如果不能分组成功则输出“No”
否则输出有多少个房间安排学生配对。

输入样例
4 4
1 2
1 3
1 4
2 3
6 5
1 2
1 3
1 4
2 5
3 6

输出样例
No
3
*/

#include<iostream>
#include<stdio.h>
#include<queue>
#include<vector>
#include<string.h>
using namespace std;
const int maxn = 205;
int n,m,color[maxn];
vector<int>G[maxn];
int match[maxn];
bool used[maxn];
void addedge(int a,int b){
    G[a].push_back(b);
    G[b].push_back(a);
}

bool dfs(int v){
    used[v] = 1;
    for(int i=0;i<G[v].size();i++){
        int u = G[v][i],w = match[u];
        if(w<0||!used[w]&&dfs(w)){
            match[v] = u;
            match[u] = v;
            return 1;
        }
    }
    return 0;
}
int matching(int n){
    int res = 0;
    memset(match,-1,sizeof(match));
    for(int v = 1;v<=n;v++){
        if(match[v]<0){
            memset(used,0,sizeof(used));
            if(dfs(v))  res++;
        }
    }
    return res;
}

bool is(){
    queue<int>q;
    memset(color,0,sizeof(color));
    q.push(1);
    color[1] = 1;
    while(!q.empty()){
        int p=q.front();
        q.pop();
        for(int i=0;i<G[p].size();i++){
            if(color[G[p][i]]==color[p])
                return 0;
            else{
                if(!color[G[p][i]]){
                    color[G[p][i]] = 3-color[p];
                    q.push(G[p][i]);
                }
            }
        }
    }
    return 1;
}
int main(){
    while(cin>>n>>m){
        int a,b;
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            addedge(a,b);
        }
        if(!is()||n==1)     cout<<"No"<<endl;
        else{
            cout<<matching(n)<<endl;
        }
        for(int i=0;i<maxn;i++)
            G[i].clear();
    }
    return 0;
}
12-28 23:17