#include <bits/stdc++.h>
using namespace std;
queue<int> que;
int n, m, dist[10010], u[10010], v[10010], Inque[10010], q[10010];
bool vis[10010], Can[10010];
struct Graph {
  int val[20010], cnt, Next[20010], head[20010], dis[20010];
  void add(int a, int b) {
    val[++cnt] = b;
    Next[cnt] = head[a];
    head[a] = cnt;
  }
  void ADD(int a, int b, int c) {
    val[++cnt] = b;
    Next[cnt] = head[a];
    head[a] = cnt;
    dis[cnt] = c;
  }
} Forward, Reverse;
void dfs(int u) {
  vis[u] = true;
  if (u == n) {
    Can[u] = true;
    return;
  }
  for (int i = Reverse.head[u]; i; i = Reverse.Next[i]) {
    int v = Reverse.val[i];
    if (!vis[v]) dfs(v);
    if (Can[v]) Can[u] = true;
  }
}
bool spfa() {
  que.push(1);
  Inque[1] = 1;
  vis[1] = true;
  for (int i = 2; i <= n; i++) dist[i] = -1e9;
  while (!que.empty()) {
    int u = que.front();
    vis[u] = false;
    que.pop();
    for (int i = Forward.head[u]; i; i = Forward.Next[i]) {
      int v = Forward.val[i], c = Forward.dis[i];
      if (dist[u] + c > dist[v]) {
        dist[v] = dist[u] + c;
        if (!vis[v]) {
          vis[v] = true;
          Inque[v]++;
          if (Inque[v] > n) return false;
          que.push(v);
        }
      }
    }
  }
  return true;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &u[i], &v[i]);
    Reverse.add(u[i], v[i]);
  }
  dfs(1);
  for (int i = 1; i <= m; i++)
    if (Can[u[i]] && Can[v[i]]) {
      Forward.ADD(u[i], v[i], 1);
      Forward.ADD(v[i], u[i], -2);
    }
  memset(vis, 0, sizeof(vis));
  bool flag = spfa();
  if (!flag)
    printf("No\n");
  else {
    printf("Yes\n");
    for (int i = 1; i <= m; i++)
      if (Can[u[i]] && Can[v[i]])
        printf("%d\n", dist[v[i]] - dist[u[i]]);
      else
        printf("1\n");
  }
  return 0;
}
