#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <string>
using namespace std;
//全局变量
int n, m;
vector<int>v;//记录每个节点被染黑还是染白或是没有染色,分别标记为1,2,0
unordered_map<int, vector<int>> um;//记录每个节点与哪些节点连接
unordered_set<int> visited;//记录已经访问的节点
string res = "YES";//结果字符串
//节点处理函数,对邻接节点染色
void process(int i) {
vector<int>::iterator it;
if (v.at(i) == 1) { //邻接节点染白
for (it = um[i].begin(); it < um[i].end(); it++) {
if (v.at(*it) == 1) {
res = "NO";
return;
} else {
v.at(*it) = 2;
}
}
} else { //邻接点染黑
for (it = um[i].begin(); it < um[i].end(); it++) {
if (v.at(*it) == 2) {
res = "NO";
return;
} else {
v.at(*it) = 1;
}
}
}
}
//深度优先遍历图
void dye(int i) {
if (visited.count(i) ||
res == "NO") { //已经访问或已经出现冲突发现不是二分图,返回
return;
}
visited.insert(i);//访问标记
process(i);//处理节点
//递归遍历
vector<int>::iterator it;
for (it = um[i].begin(); it < um[i].end(); it++) {
if (!visited.count(*it)) {
dye(*it);
}
}
}
int main() {
//输入数据
cin >> n >> m;
v.resize(n + 1, 0);
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
if (um.count(u)) {
um[u].push_back(v);
} else {
um[u] = {v};
}
if (um.count(v)) {
um[v].push_back(u);
} else {
um[v] = {u};
}
}
//从节点1开始对其它节点进行深度优先遍历以及染色,如果出现染色冲突则不是二分图
v.at(1) = 1;//节点1染黑
//深度优先遍历并染色
dye(1);
//打印结果
cout << res << endl;
return 0;
}
// 64 位输出请用 printf("%lld