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;
const int n = 50000;
int ans = 1000001000, mainmax = 0;
int bestans[n];
class rb {
 public:
  int e, r, col, val, main, clas;
  void ini(int e1, int r1, int col1, int val1) {
    e = e1;
    r = r1;
    col = col1;
    val = val1;
    main = -1;
  }
  int next(int c) {
    if (e == c) return r;
    return e;
  }
};
class mrb {
 public:
  int e, r, t;
  bool lok[2], used;
  int *a;
};
class sp {
 public:
  int q;
  sp *w;
  sp(int q1, sp *w1) {
    q = q1;
    w = w1;
  }
};
sp *s[n];
mrb almrb[n];
rb alrb[n];
int q, numrb, nummrb = 0;
int sizea[n], *a[n];
void qsa(int q, int w, int *a) {
  int e = q, r = w, t = a[q + (rand() % (w - q + 1))], y;
  t = alrb[t].col;
  do {
    while (alrb[a[e]].col < t) e++;
    while (alrb[a[r]].col > t) r--;
    if (e <= r) {
      y = a[e];
      a[e] = a[r];
      a[r] = y;
      e++;
      r--;
    }
  } while (e <= r);
  if (q < r) qsa(q, r, a);
  if (e < w) qsa(e, w, a);
}
bool cheka(int w) {
  int q = sizea[w], e, r = 1;
  if (q > 1) qsa(0, q - 1, a[w]);
  for (e = 1; e < q; e++) {
    if (alrb[a[w][e - 1]].col == alrb[a[w][e]].col)
      r++;
    else
      r = 1;
    if (r > 2) return 1;
  }
  return 0;
}
int nexta(int w, int u) {
  int c = -1, v, col = alrb[u].col;
  for (v = 1 << 16; v; v >>= 1) {
    if ((c + v < sizea[w]) && (alrb[a[w][c + v]].col <= col)) c += v;
  }
  if ((c < 0) || (alrb[a[w][c]].col != col)) return -1;
  if (a[w][c] != u) return a[w][c];
  c--;
  if ((0 <= c) && (alrb[a[w][c]].col == col)) return a[w][c];
  return -1;
}
int mainsch, sizebyf, byf[n];
void buildway(int q, int w, int t) {
  int e, c;
  e = nexta(q, w);
  if (e < 0) {
    c = nummrb;
    almrb[c].t = t;
    almrb[c].a = new int[t];
    almrb[c].a[t - 1] = w;
    alrb[w].main = c;
    alrb[w].clas = (t - 1) % 2;
    return;
  }
  buildway(alrb[e].next(q), e, t + 1);
  c = nummrb;
  almrb[c].a[t - 1] = w;
  alrb[w].main = c;
  alrb[w].clas = (t - 1) % 2;
}
bool lok[n], minilok[n];
int mainlok[n];
int sch(int q, int w, int t) {
  if (q == mainsch) {
    if (t % 2 == 1) return -1;
    sizebyf = t;
    byf[t - 1] = w;
    alrb[w].main = -2;
    if (!lok[q]) return -1;
    lok[q] = 0;
    return 0;
  }
  int e, r, c;
  e = nexta(q, w);
  if (e < 0) {
    if (t == 1) return 100;
    buildway(alrb[w].next(q), w, 1);
    return 1;
  }
  r = sch(alrb[e].next(q), e, t + 1);
  if (r < 0) return r;
  if (r == 0) {
    byf[t - 1] = w;
    alrb[w].main = -2;
    if (!lok[q]) return -1;
    lok[q] = 0;
    return 0;
  }
  if (r == 1) return 1;
}
bool schckl() {
  int w, e, r, t, c, locmin[2];
  for (w = 0; w < q; w++) {
    mainsch = w;
    for (e = 0; e < sizea[w]; e++) {
      c = a[w][e];
      if (alrb[c].main == -1) {
        t = sch(alrb[c].next(w), c, 1);
        if (t < 0) return 1;
        if (t == 100) continue;
        if (t == 1) {
          nummrb++;
          continue;
        }
        locmin[0] = locmin[1] = 0;
        for (r = 0; r < sizebyf; r++)
          locmin[r % 2] = max(locmin[r % 2], alrb[byf[r]].val);
        if (locmin[0] < locmin[1]) {
          mainmax = max(mainmax, locmin[0]);
          for (r = 0; r < sizebyf; r++)
            if (r % 2 == 0) alrb[byf[r]].main = -10;
        } else {
          mainmax = max(mainmax, locmin[1]);
          for (r = 0; r < sizebyf; r++)
            if (r % 2 == 1) alrb[byf[r]].main = -10;
        }
      }
    }
  }
  return 0;
}
bool arrang(int q, int mnlok);
bool arrang2(int w, int q) {
  int c, v;
  if (mainlok[q] != w) {
    if (q == almrb[w].r)
      c = (almrb[w].t - 1) % 2;
    else
      c = 0;
    almrb[w].lok[c] = 0;
  }
  if ((almrb[w].lok[0] == 0) && (almrb[w].lok[1] == 0)) return 1;
  if (almrb[w].used == 0) return 0;
  almrb[w].used = 0;
  if (almrb[w].lok[0] == 1)
    if (arrang(almrb[w].e, w)) return 1;
  c = (almrb[w].t - 1) % 2;
  if (almrb[w].lok[c] == 1)
    if (arrang(almrb[w].r, w)) return 1;
  return 0;
}
bool arrang(int q, int mnlok) {
  if ((mainlok[q] != mnlok) && (minilok[q] == 0)) return 1;
  if ((mnlok >= 0) && (lok[q] == 0)) return 1;
  if (!minilok[q]) return 0;
  sp *c;
  minilok[q] = 0;
  mainlok[q] = mnlok;
  for (c = s[q]; c; c = c->w)
    if (arrang2(c->q, q)) return 1;
  return 0;
}
bool chekbp() {
  int w, e, r;
  for (w = 0; w < q; w++)
    if ((lok[w] == 0) && (minilok[w]))
      if (arrang(w, -1)) return 0;
  for (w = 0; w < nummrb; w++)
    if (almrb[w].used == 1) {
      if ((almrb[w].lok[0] == 0) && (almrb[w].lok[1] == 0)) return 0;
      if ((almrb[w].lok[0] == 1) && (almrb[w].lok[1] == 1)) continue;
      almrb[w].used = 0;
      if (almrb[w].lok[1] == 1) almrb[w].lok[0] = 0;
      e = almrb[w].e;
      r = almrb[w].r;
      if (almrb[w].lok[0] == 1)
        if (arrang(e, w)) return 0;
      if (almrb[w].lok[(almrb[w].t - 1) % 2] == 1)
        if (arrang(r, w)) return 0;
    }
  for (w = 0; w < nummrb; w++)
    if (almrb[w].used == 1) {
      if ((almrb[w].lok[0] == 0) && (almrb[w].lok[1] == 0)) return 0;
      almrb[w].used = 0;
      if (almrb[w].lok[1] == 1) almrb[w].lok[0] = 0;
      e = almrb[w].e;
      r = almrb[w].r;
      if (almrb[w].lok[0] == 1)
        if (arrang(e, w)) return 0;
      if (almrb[w].lok[(almrb[w].t - 1) % 2] == 1)
        if (arrang(r, w)) return 0;
    }
  return 1;
}
void bp() {
  int w, e, r, c, v;
  for (w = 0; w < q; w++) s[w] = 0;
  for (w = 0; w < nummrb; w++) {
    e = almrb[w].e;
    r = almrb[w].r;
    s[e] = new sp(w, s[e]);
    s[r] = new sp(w, s[r]);
  }
  for (v = 1 << 29; v; v >>= 1) {
    c = ans - v;
    if (c >= mainmax) {
      for (w = 0; w < q; w++) minilok[w] = 1;
      for (w = 0; w < nummrb; w++) {
        almrb[w].lok[0] = almrb[w].lok[1] = 1;
        almrb[w].used = 1;
      }
      for (w = 0; w < numrb; w++) {
        e = alrb[w].main;
        if (e >= 0)
          if (alrb[w].val > c) almrb[e].lok[alrb[w].clas] = 0;
      }
      if (chekbp()) {
        ans = c;
        for (w = 0; w < nummrb; w++)
          if (almrb[w].lok[0])
            bestans[w] = 0;
          else
            bestans[w] = 1;
      }
    }
  }
}
int main() {
  int w, e, r, t, c, v;
  cin >> q >> numrb;
  for (w = 0; w < q; w++) {
    sizea[w] = 0;
    lok[w] = 1;
  }
  for (w = 0; w < numrb; w++) {
    scanf("%d%d%d%d", &e, &r, &c, &v);
    e--;
    r--;
    alrb[w].ini(e, r, c, v);
    sizea[e]++;
    sizea[r]++;
  }
  for (w = 0; w < q; w++) {
    a[w] = new int[sizea[w]];
    sizea[w] = 0;
  }
  for (w = 0; w < numrb; w++) {
    e = alrb[w].e;
    r = alrb[w].r;
    a[e][sizea[e]] = w;
    sizea[e]++;
    a[r][sizea[r]] = w;
    sizea[r]++;
  }
  for (w = 0; w < q; w++)
    if (cheka(w)) {
      cout << "No";
      return 0;
    }
  if (schckl()) {
    cout << "No";
    return 0;
  }
  for (w = 0; w < nummrb; w++) {
    c = almrb[w].a[0];
    v = almrb[w].a[1];
    if ((alrb[c].e != alrb[v].r) && (alrb[c].e != alrb[v].e))
      almrb[w].e = alrb[c].e;
    else
      almrb[w].e = alrb[c].r;
    c = almrb[w].a[almrb[w].t - 1];
    v = almrb[w].a[almrb[w].t - 2];
    if ((alrb[c].e != alrb[v].r) && (alrb[c].e != alrb[v].e))
      almrb[w].r = alrb[c].e;
    else
      almrb[w].r = alrb[c].r;
    for (e = 1; e < almrb[w].t; e++) {
      c = almrb[w].a[e - 1];
      v = almrb[w].a[e];
      if ((alrb[c].e != alrb[v].e) && (alrb[c].e != alrb[v].r))
        r = alrb[c].r;
      else
        r = alrb[c].e;
      if (!lok[r]) {
        cout << "No";
        return 0;
      }
      lok[r] = 0;
    }
  }
  bp();
  if (ans == 1000001000) {
    cout << "No";
    return 0;
  }
  t = 0;
  for (w = 0; w < numrb; w++) {
    c = alrb[w].main;
    if (c == -10) {
      t++;
      continue;
    }
    if ((c >= 0) && (alrb[w].clas == bestans[c])) t++;
  }
  cout << "Yes\n";
  cout << ans << " " << t << "\n";
  for (w = 0; w < numrb; w++) {
    c = alrb[w].main;
    if (c == -10) {
      cout << w + 1 << " ";
      continue;
    }
    if ((c >= 0) && (alrb[w].clas == bestans[c])) cout << w + 1 << " ";
  }
  return 0;
}
