#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
const int M = 5e3 + 10;
const int INF = 2e9;
int n, m, A[M], B[M], head[N], cnt, num[N], f[N], stan;
bool vis[2][N], inq[N];
struct edge {
  int nxt, to, val;
} ed[M << 1];
vector<int> g[2][N];
queue<int> q;
inline void addedge(int x, int y, int w) {
  ed[++cnt].to = y;
  ed[cnt].nxt = head[x];
  ed[cnt].val = w;
  head[x] = cnt;
}
inline void Check(int u, int num) {
  vis[num][u] = true;
  for (register int i = 0; i < (int)g[num][u].size(); i++)
    if (!vis[num][g[num][u][i]]) Check(g[num][u][i], num);
}
inline bool SPFA() {
  for (register int i = 1; i <= n; i++) f[i] = INF;
  f[1] = 0;
  q.push(1);
  inq[1] = true;
  num[1] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    inq[u] = false;
    for (register int i = head[u]; i; i = ed[i].nxt) {
      int v = ed[i].to;
      if (f[v] > f[u] + ed[i].val) {
        f[v] = f[u] + ed[i].val;
        num[v] = num[u] + 1;
        if (num[v] > n) return false;
        if (!inq[v]) q.push(v), inq[v] = true;
      }
    }
  }
  return true;
}
int main() {
  scanf("%d%d", &n, &m);
  for (register int i = 1; i <= m; i++)
    scanf("%d%d", &A[i], &B[i]), g[0][A[i]].push_back(B[i]),
        g[1][B[i]].push_back(A[i]);
  Check(1, 0);
  Check(n, 1);
  for (register int i = 1; i <= m; i++)
    if (vis[0][A[i]] && vis[0][B[i]] && vis[1][A[i]] && vis[1][B[i]])
      addedge(A[i], B[i], -1), addedge(B[i], A[i], 2);
  if (!SPFA()) {
    puts("No");
    return 0;
  }
  puts("Yes");
  stan = -f[n];
  for (register int i = 1; i <= n; i++) f[i] += stan;
  for (register int i = 1; i <= m; i++)
    if (vis[0][A[i]] && vis[0][B[i]] && vis[1][A[i]] && vis[1][B[i]])
      printf("%d\n", f[A[i]] - f[B[i]]);
    else
      printf("1\n");
  return 0;
}
