// Traversal algorithms for graphs
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6;
vector<bool> vis(N+1,false);
vector<int> adjlist[N+1];
// DFS using recursion
void DFS(int vertex) {
vis[vertex] = true;
cout << vertex << "\n";
for(int child : adjlist[vertex]) {
if(!vis[child]) {
DFS(child);
}
}
}
// DFS using stack
void DFS_stack(int vertex) {
stack<int> s;
[Link](vertex);
vis[vertex] = true;
while(![Link]()) {
int current = [Link]();
[Link]();
cout << current << "\n";
for(int child : adjlist[current]) {
if(!vis[child]) {
vis[child] = true;
[Link](child);
}
}
}
}
// BFS using queue
void BFS(int vertex) {
queue<int> q;
[Link](vertex);
vis[vertex] = true;
while(![Link]()) {
int current = [Link]();
[Link]();
cout << current << "\n";
for(int child : adjlist[current]) {
if(!vis[child]) {
vis[child] = true;
[Link](child);
}
}
}
}
// Finding if graph is bipartite or not using BFS
bool isBipartiteCheck(int vertex) {
vector<int> color(N+1, -1);
queue<int> q;
[Link](vertex);
color[vertex] = 0;
while(![Link]()) {
int current = [Link]();
[Link]();
for(int child : adjlist[current]) {
if(color[child] == -1) {
color[child] = 1 - color[current];
[Link](child);
} else if(color[child] == color[current]) {
return false;
}
}
}
return true;
}
int main() {
[Link](0)->sync_with_stdio(0);
int n, m;
cin >> n >> m;
for(int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
adjlist[u].push_back(v);
adjlist[v].push_back(u);
}
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
DFS(i);
}
}
fill([Link](), [Link](), false);
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
BFS(i);
}
}
fill([Link](), [Link](), false);
bool isBipartite = true;
for(int i = 1; i <= n; i++) {
if(!vis[i]) {
if(!isBipartiteCheck(i)) {
isBipartite = false;
break;
}
}
}
if(isBipartite) cout << "Graph is Bipartite\n";
else cout << "Graph is Not Bipartite\n";
return 0;
}