#define RED -1 // First set of vertices
#define BLUE 1 // Second set of vertices
#define WHITE 0 // Not processed vertices
#include <queue>
#include <vector>
#include <iostream>
using namespace std;
bool isBipartite(vector<int> *listOfVertices, int *colorOfVertices, int sourceVertex, int quantityOfVertex) {
bool isBipartite = true;
colorOfVertices[sourceVertex] = RED; // Color vertex which we started
queue <int> orderOfBypassing; // Stores order of bypassing with queue
orderOfBypassing.push(sourceVertex); // Remember the initial vertex
while (!orderOfBypassing.empty()) { // Process until we bypass all connected vertices
int currentVertex = orderOfBypassing.front(); // Remember vertex that came first in queue
orderOfBypassing.pop(); // Remove it
for (auto adjacentVertex : listOfVertices[currentVertex]) { // Process all adjacent with current and not processed earlier vertices
if (colorOfVertices[adjacentVertex] == WHITE) {
colorOfVertices[adjacentVertex] = -colorOfVertices[currentVertex]; // Color adjacent vertex with inverse color
orderOfBypassing.push(adjacentVertex); // Add this vertex to the order of bypass
}
else if (colorOfVertices[adjacentVertex] == colorOfVertices[currentVertex]) { // If two adjacent vertices in one set are the same color
isBipartite = false; // Graph isn't bipartite
break; // We can stop processing
}
}
}
return isBipartite;
}
int main() {
bool answer = true;
int quantityOfVertex, quantityOfConnections;
cin >> quantityOfVertex >> quantityOfConnections;
vector<int> *listOfVertices = new vector<int>[quantityOfVertex]; // Stores for the each vertex adjacent vertices
while (quantityOfConnections--) { // Read all given connections
int firstVertex, secondVertex;
cin >> firstVertex >> secondVertex;
firstVertex--; // We store it numbering from zero, so decrement index of vertices
secondVertex--;
listOfVertices[firstVertex].push_back(secondVertex); // Add vertex to the vector of adjacent vertex
listOfVertices[secondVertex].push_back(firstVertex); // Do it symmetrically
}
int *colorOfVertices = new int[quantityOfVertex]; // For each vertex stores its color
for (int indexOfVertex = 0; indexOfVertex < quantityOfVertex; indexOfVertex++) {
colorOfVertices[indexOfVertex] = WHITE; // Intially, all vetices are white (not processed)
}
for (int indexOfVertex = 0; indexOfVertex < quantityOfVertex && answer; indexOfVertex++) { // Process to the end or until we recognize, that graph isn't bipartite
if (colorOfVertices[indexOfVertex] == WHITE) { // Process only white vertices
answer &= isBipartite(listOfVertices, colorOfVertices, indexOfVertex, quantityOfVertex); // Logical conjunction of answers for all graph component
}
}
cout << (answer ? "YES" : "NO");
return 0;
}