3 5
2 1 608591421 720962564
3 2 608591421 641991574
3 2 718110706 353409763
2 3 482786015 858341723
3 2 825397574 357507279
 2 1
2 1 317425595 636156322
 50000 1
20845 28516 904146168 997637433

Yes
641991574 1
2 
 Yes
0 0

 Yes
0 0


#include <bits/stdc++.h>
using namespace std;
int read() {
  char c = getchar();
  while (!isdigit(c)) c = getchar();
  int num = 0;
  while (isdigit(c)) num = num * 10 + c - '0', c = getchar();
  return num;
}
void write(int num) {
  if (num >= 10) write(num / 10);
  putchar(num % 10 + '0');
}
int u[50001], v[50001], c[50001], t[50001];
vector<int> e[50001];
bool cmp(int a, int b) { return c[a] < c[b]; }
int head[500001], ver[1000001], nxt[1000001], sz;
void addedge(int u, int v) { ver[++sz] = v, nxt[sz] = head[u], head[u] = sz; }
int dfn[500001], low[500001];
int vis[500001], stk[500001];
int now, top, cnt, scc[500001];
void tarjan(int x) {
  dfn[x] = low[x] = ++now;
  stk[++top] = x, vis[x] = 1;
  for (int i = head[x]; i; i = nxt[i]) {
    if (!vis[ver[i]])
      tarjan(ver[i]), low[x] = min(low[x], low[ver[i]]);
    else
      low[x] = min(low[x], dfn[ver[i]]);
    scc[x] = ++cnt;
    while (stk[top] != x) {
      scc[stk[top]] = cnt;
      vis[stk[top]] = 2;
      --top;
    }
  }
}
bool _2sat(int n) {
  now = cnt = 0;
  for (int i = 1; i <= n * 2; i++) vis[i] = 0;
  for (int i = 1; i <= n * 2; i++)
    if (!vis[i]) tarjan(i);
  for (int i = 1; i <= n; i++)
    if (scc[i] == scc[i + n]) return 0;
  return 1;
}
int main() {
  int n, m;
  n = read(), m = read();
  for (int i = 1; i <= m; i++) {
    u[i] = read(), v[i] = read(), c[i] = read(), t[i] = read();
    e[u[i]].push_back(i), e[v[i]].push_back(i);
  }
  int tot = m;
  for (int i = 1; i <= n; i++) {
    int tmp = 0;
    sort(e[i].begin(), e[i].end());
    for (int j = 1; j < e[i].size(); j++)
      if (c[e[i][j]] == c[e[i][j - 1]]) {
        if (tmp) {
          puts("No");
          return 0;
        }
        tmp = j;
      }
    if (tmp) {
      addedge(e[i][tmp], m * 5 + e[i][tmp - 1]);
      addedge(e[i][tmp - 1], m * 5 + e[i][tmp]);
      addedge(m * 5 + e[i][tmp - 1], e[i][tmp]);
      addedge(m * 5 + e[i][tmp], e[i][tmp - 1]);
      for (int j = 0; j < e[i].size(); j++)
        if (j != tmp && j != tmp - 1) addedge(e[i][j], m * 5 + e[i][j]);
    } else {
      for (int j = 1; j < e[i].size(); j++) {
        addedge(e[i][j - 1] + tot, e[i][j] + tot);
        addedge(e[i][j] + tot + e[i].size(), e[i][j - 1] + tot + e[i].size());
        addedge(e[i][j] + tot + m * 5, e[i][j - 1] + tot + m * 5);
        addedge(e[i][j - 1] + tot + e[i].size() + m * 5,
                e[i][j] + tot + e[i].size() + m * 5);
      }
      for (int j = 0; j < e[i].size(); j++) {
        addedge(e[i][j], e[i][j] + tot);
        addedge(e[i][j], e[i][j] + tot + e[i].size());
        addedge(e[i][j] + tot + m * 5, e[i][j] + m * 5);
        addedge(e[i][j] + tot + e[i].size() + m * 5, e[i][j] + m * 5);
      }
      for (int j = 1; j < e[i].size(); j++) {
        addedge(e[i][j], e[i][j - 1] + tot + m * 5);
        addedge(e[i][j - 1], e[i][j] + tot + e[i].size() + m * 5);
        addedge(e[i][j - 1] + tot, e[i][j] + m * 5);
        addedge(e[i][j] + tot + e[i].size(), e[i][j - 1] + m * 5);
      }
    }
    tot += e[i].size() * 2;
  }
  int tmp = sz;
  int l = 0, r = 1000000000;
  while (l < r) {
    int mid = (l + r) / 2;
    for (int i = 1; i <= m * 10; i++)
      while (head[i] > tmp) head[i] = nxt[head[i]];
    sz = tmp;
    for (int i = 1; i <= m; i++)
      if (t[i] > mid) addedge(i, i + m * 5);
    if (_2sat(m * 5))
      r = mid;
    else
      l = mid + 1;
  }
  puts("Yes");
  for (int i = 1; i <= m; i++)
    if (scc[i] < scc[i + m * 5])
      write(u[i]), putchar(' '), write(v[i]), putchar('\n');
}
