#include <bits/stdc++.h>
using namespace std;
const int N=100005;
const int M=400005;
int type, n, m;
int head[N], E=1; // 边的编号从1开始
struct Edge{
int v, ne;
}e[M];
int din[N], dout[N]; // 记录点的度数
bool vis[M]; // 记录边的访问情况
vector<int> ans;
inline void add(int a, int b){
++E;
e[E].v=b;
e[E].ne=head[a];
head[a]=E;
}
void dfs(int x){ // find Euler loop
for(int &i=head[x], v; v=e[i].v, i; i=e[i].ne){
int c=(type==1?i/2:i-1);
int sgn=i&0x01;
if(!vis[c]){
vis[c]=true;
dfs(v);
if(type==1) ans.push_back(sgn? -c: c);
else ans.push_back(c);
}
}
}
int main(){
memset(head, 0x00, sizeof head);
memset(vis, 0x00, sizeof vis);
memset(din, 0x00, sizeof din);
memset(dout, 0x00, sizeof dout);
cin>>type>>n>>m;
for(int i=1; i<=m; ++i){
int x, y;
cin>>x>>y;
add(x, y); // x->y的边
if(type==1) add(y, x); // 如果是无向边需要添加反向边
din[y]++; dout[x]++;
}
if(type==1){ // 无向图判断: 如果存在点的度数为奇数则不存在Euler loop
for(int i=1; i<=n; ++i){
if((din[i]+dout[i])%2){
cout<<"NO"<<endl;
return 0;
}
}
}
else{ // 有向图判断: 如果存在点的出度!=入度则不存在Euler loop
for(int i=1; i<=n; ++i){
if(din[i]!=dout[i]){
cout<<"NO"<<endl;
return 0;
}
}
}
// 存在Euler loop的情况
for(int i=1; i<=n; ++i){
if(head[i]){dfs(i); break;}
}
if(ans.size()!=m){ // 要求整个G是一个Euler loop
cout<<"NO"<<endl;
return 0;
}
cout<<"YES"<<endl;
for(int i=m-1; i>=0; --i) cout<<ans[i]<<" "; // 逆序输出元素
return 0;
}