#include <bits/stdc++.h>
using namespace std;
int const maxn = 1e5 + 10;
int const maxm = 1e5 + 10;
int head[maxn], tot;
struct Edg {
  int to, next, dis;
} edg[maxm * 2];
void inint() {
  memset(head, -1, sizeof head);
  tot = 0;
}
void add(int u, int v, int dis) {
  edg[tot].to = v;
  edg[tot].dis = dis;
  edg[tot].next = head[u];
  head[u] = tot++;
}
int n, m;
int dis[maxn];
int vis[maxn];
int cnt[maxn];
int st[maxn], st2[maxn];
int spfa() {
  queue<int> q;
  for (int i = 1; i <= n; i++) {
    dis[i] = 0;
  }
  vis[1] = 1;
  q.push(1);
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    vis[x] = 0;
    for (int i = head[x]; ~i; i = edg[i].next) {
      int y = edg[i].to;
      if (!st2[y]) continue;
      if (dis[y] < dis[x] + edg[i].dis) {
        cnt[y] = cnt[x] + 1;
        dis[y] = dis[x] + edg[i].dis;
        if (cnt[y] >= n) return 1;
        if (!vis[y]) {
          vis[y] = 1;
          q.push(y);
        }
      }
    }
  }
  return 0;
}
vector<pair<int, int> > tmp;
void dfs(int x) {
  st[x] = 1;
  if (x == n) {
    st2[x] = 1;
    return;
  }
  for (int i = head[x]; ~i; i = edg[i].next) {
    int y = edg[i].to;
    if (edg[i].dis == -2) continue;
    if (!st[y]) dfs(y);
    if (st2[y]) st2[x] = 1;
  }
}
int main() {
  scanf("%d%d", &n, &m);
  inint();
  for (int i = 1; i <= m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    tmp.push_back({a, b});
    add(a, b, 1);
    add(b, a, -2);
  }
  dfs(1);
  if (spfa())
    cout << "No\n";
  else {
    cout << "Yes\n";
    for (auto x : tmp) {
      if (dis[x.second] - dis[x.first] == 1)
        printf("1\n");
      else
        printf("2\n");
    }
  }
  return 0;
}
