#include <bits/stdc++.h>
using namespace std;
int n, m, head[2][5005], cnt[2], dis[5005], u[5005], v[5005], num[5005];
struct edge {
  int to, next, cost;
} e[2][5005];
bool vis[3][5005];
queue<int> q;
template <typename T>
inline T read() {
  T x = 0, w = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') w = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  return x * w;
}
inline void adde(int u, int v, int w, int opt) {
  e[opt][++cnt[opt]] = (edge){v, head[opt][u], w};
  head[opt][u] = cnt[opt];
}
void bfs(int S, int op) {
  q.push(S), vis[op][S] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int v, i = head[op][u]; i; i = e[op][i].next) {
      v = e[op][i].to;
      if (vis[op][v]) continue;
      q.push(v), vis[op][v] = 1;
    }
  }
}
void SPFA() {
  memset(vis[0], 0, sizeof(vis[0]));
  memset(dis, -0x3f, sizeof(dis));
  q.push(1);
  dis[1] = 0;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    vis[0][u] = 0;
    for (int v, i = head[0][u]; i; i = e[0][i].next) {
      v = e[0][i].to;
      if (dis[v] < dis[u] + e[0][i].cost) {
        dis[v] = dis[u] + e[0][i].cost;
        if (!vis[0][v]) {
          vis[0][v] = 1, num[v]++, q.push(v);
        }
      }
      if (num[v] >= n) {
        puts("No");
        exit(0);
      }
    }
  }
}
int main() {
  n = read<int>(), m = read<int>();
  for (int i = 1; i <= m; i++)
    u[i] = read<int>(), v[i] = read<int>(), adde(u[i], v[i], 0, 0),
    adde(v[i], u[i], 0, 1);
  bfs(1, 0), bfs(n, 1);
  memset(head, 0, sizeof(head)), cnt[0] = 0;
  for (int i = 1; i <= n; i++)
    if (vis[0][i] && vis[1][i]) vis[2][i] = 1;
  for (int i = 1; i <= m; i++)
    if (vis[2][u[i]] && vis[2][v[i]])
      adde(u[i], v[i], 1, 0), adde(v[i], u[i], -2, 0);
  SPFA();
  puts("Yes");
  for (int i = 1; i <= m; i++)
    if (vis[2][u[i]] && vis[2][v[i]])
      printf("%d\n", dis[v[i]] - dis[u[i]]);
    else
      printf("%d\n", 1);
  return 0;
}
