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;
inline int getid(int x, int p) { return (x << 1) - p; }
int n, m, dfn[500010], tim, low[500010], bcccnt, bel[500010];
bool vis[500010];
int stk[500010], tp;
vector<int> v[500010];
inline void addedge(int s, int e) { v[s].push_back(e); }
void dfs(int np) {
  low[np] = dfn[np] = ++tim;
  stk[++tp] = np;
  vis[np] = 1;
  for (auto &x : v[np]) {
    if (!dfn[x]) {
      dfs(x);
      low[np] = min(low[np], low[x]);
    } else if (vis[x])
      low[np] = min(low[np], dfn[x]);
  }
  if (low[np] == dfn[np]) {
    int tmp;
    bcccnt++;
    while ((tmp = stk[tp--])) {
      bel[tmp] = bcccnt;
      vis[tmp] = 0;
      if (tmp == np) break;
    }
  }
}
int s[50010], e[50010], w[50010], c[50010];
vector<int> edg[50010];
inline bool check(int mid) {
  for (int i = 1; i <= m; i++)
    if (!v[getid(i, 0)].empty() && v[getid(i, 0)].back() == getid(i, 1))
      v[getid(i, 0)].pop_back();
  memset(vis, 0, sizeof(vis));
  memset(dfn, 0, sizeof(dfn));
  memset(low, 0, sizeof(low));
  memset(bel, 0, sizeof(bel));
  bcccnt = tp = tim = 0;
  for (int i = 1; i <= m; i++)
    if (w[i] > mid) v[getid(i, 0)].push_back(getid(i, 1));
  for (int i = 1; i <= m * 10; i++)
    if (!dfn[i]) dfs(i);
  for (int i = 1; i <= m; i++)
    if (bel[getid(i, 0)] == bel[getid(i, 1)]) return 0;
  return 1;
}
int lsc[50010], pre[50010];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d%d", &s[i], &e[i], &c[i], &w[i]);
    lsc[i] = c[i];
    edg[s[i]].push_back(i);
    edg[e[i]].push_back(i);
  }
  sort(lsc + 1, lsc + n + 1);
  int E = unique(lsc + 1, lsc + n + 1) - lsc - 1;
  for (int i = 1; i <= m; i++)
    c[i] = lower_bound(lsc + 1, lsc + E + 1, c[i]) - lsc;
  int idcnt = m * 2 + 1;
  memset(pre, 255, sizeof(pre));
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < edg[i].size(); j++) {
      int pos = edg[i][j];
      if (j) {
        addedge(idcnt + j * 4 + 2, idcnt + (j - 1) * 4 + 2);
        addedge(idcnt + (j - 1) * 4 + 3, idcnt + j * 4 + 3);
        addedge(getid(pos, 0), idcnt + (j - 1) * 4 + 2);
      }
      if (pre[c[pos]] != -1) {
        addedge(idcnt + j * 4, idcnt + pre[c[pos]] * 4);
        addedge(getid(pos, 1), idcnt + pre[c[pos]] * 4);
      }
      if (j != edg[i].size() - 1) {
        addedge(getid(pos, 0), idcnt + (j + 1) * 4 + 3);
      }
      addedge(idcnt + j * 4, getid(pos, 0));
      addedge(idcnt + j * 4 + 1, getid(pos, 0));
      addedge(idcnt + j * 4 + 2, getid(pos, 1));
      addedge(idcnt + j * 4 + 3, getid(pos, 1));
      pre[c[pos]] = j;
    }
    for (auto &x : edg[i]) pre[c[x]] = -1;
    for (int j = edg[i].size() - 1; j >= 0; j--) {
      int pos = edg[i][j];
      if (pre[c[pos]] != -1)
        addedge(getid(pos, 1), idcnt + pre[c[pos]] * 4 + 1),
            addedge(idcnt + j * 4 + 1, idcnt + pre[j] * 4 + 1);
      pre[c[pos]] = j;
    }
    for (auto &x : edg[i]) pre[c[x]] = -1;
    idcnt += edg[i].size() * 4;
  }
  int L = 1, R = 1000000000, ret = -1;
  while (L <= R) {
    int mid = (L + R) >> 1;
    if (check(mid))
      ret = mid, R = mid - 1;
    else
      L = mid + 1;
  }
  if (ret == -1) {
    puts("No");
    return 0;
  }
  puts("Yes");
  check(ret);
  for (int i = 1; i <= m; i++)
    if (bel[getid(i, 0)] < bel[getid(i, 1)]) printf("%d %d\n", s[i], e[i]);
  return 0;
}
