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 = 5e4 + 7;
int n, m, tot, top, num, cnt, ind;
bool instack[N * 10];
int sta[N * 10], head[N * 10], bl[N * 10], dfn[N * 10], low[N * 10],
    nxt[N * 23], to[N * 23];
vector<int> ve[N], pre[N], suf[N], Pre[N], Suf[N];
struct Edge {
  int u, v, c, w;
} e[N];
void tarjan(int x) {
  dfn[x] = low[x] = ++ind;
  sta[++top] = x;
  instack[x] = 1;
  for (int i = head[x]; i; i = nxt[i])
    if (!dfn[to[i]])
      tarjan(to[i]), low[x] = min(low[x], low[to[i]]);
    else if (instack[to[i]])
      low[x] = min(low[x], dfn[to[i]]);
  if (dfn[x] == low[x]) {
    ++num;
    int y;
    do y = sta[top--], instack[y] = 0, bl[y] = num;
    while (y != x);
  }
}
inline void link(int a, int b) {
  nxt[++tot] = head[a];
  to[head[a] = tot] = b;
}
inline bool check(int lim) {
  tot = 1;
  cnt = 2 * m;
  ind = 0;
  num = 0;
  memset(head, 0, sizeof(head));
  memset(dfn, 0, sizeof(dfn));
  for (int i = 1; i <= m; ++i)
    if (e[i].w > lim) link(i + m, i);
  for (int i = 1; i <= n; ++i)
    if (ve[i].size()) {
      pre[i].resize(ve[i].size());
      suf[i].resize(ve[i].size());
      Pre[i].resize(ve[i].size());
      Suf[i].resize(ve[i].size());
      for (int j = 0; j < ve[i].size(); ++j)
        pre[i][j] = ++cnt, link(pre[i][j], ve[i][j]);
      for (int j = 0; j < ve[i].size(); ++j)
        suf[i][j] = ++cnt, link(suf[i][j], ve[i][j]);
      for (int j = 1; j < ve[i].size(); ++j) link(pre[i][j], pre[i][j - 1]);
      for (int j = 1; j < ve[i].size(); ++j) link(suf[i][j - 1], suf[i][j]);
      for (int j = 0; j < ve[i].size(); ++j) {
        if (j) link(ve[i][j] + m, pre[i][j - 1]);
        if (j < ve[i].size() - 1) link(ve[i][j] + m, suf[i][j + 1]);
      }
      for (int j = 0; j < ve[i].size(); ++j)
        Pre[i][j] = ++cnt, link(Pre[i][j], ve[i][j] + m);
      for (int j = 0; j < ve[i].size(); ++j)
        Suf[i][j] = ++cnt, link(Suf[i][j], ve[i][j] + m);
      for (int j = 1; j < ve[i].size(); ++j)
        if (e[ve[i][j - 1]].c == e[ve[i][j]].c) link(Pre[i][j], Pre[i][j - 1]);
      for (int j = 1; j < ve[i].size(); ++j)
        if (e[ve[i][j - 1]].c == e[ve[i][j]].c) link(Suf[i][j - 1], Suf[i][j]);
      for (int j = 0; j < ve[i].size(); ++j) {
        if (j && e[ve[i][j]].c == e[ve[i][j - 1]].c)
          link(ve[i][j], Pre[i][j - 1]);
        if (j < ve[i].size() - 1 && e[ve[i][j]].c == e[ve[i][j + 1]].c)
          link(ve[i][j], Suf[i][j + 1]);
      }
    }
  for (int i = 1; i <= cnt; ++i)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= m; ++i)
    if (bl[i + m] == bl[i]) return 0;
  return 1;
}
inline int read(register int x = 0, register char ch = getchar(),
                register int f = 0) {
  for (; !isdigit(ch); ch = getchar()) f = ch == '-';
  for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
  return f ? -x : x;
}
int main() {
  n = read();
  m = read();
  for (int i = 1; i <= m; ++i)
    e[i].u = read(), e[i].v = read(), e[i].c = read(), e[i].w = read();
  for (int i = 1; i <= m; ++i) ve[e[i].u].push_back(i), ve[e[i].v].push_back(i);
  for (int i = 1; i <= n; ++i)
    sort(ve[i].begin(), ve[i].end(),
         [](int a, int b) { return e[a].c < e[b].c; });
  if (!check(1e9)) return puts("No"), 0;
  puts("Yes");
  int l = 0, r = 1e9;
  while (l < r) {
    const int mid = l + r >> 1;
    if (check(mid))
      r = mid;
    else
      l = mid + 1;
  }
  check(l);
  tot = 0;
  for (int i = 1; i <= m; ++i)
    if (bl[i + m] < bl[i]) ++tot;
  printf("%d %d\n", l, tot);
  for (int i = 1; i <= m; ++i)
    if (bl[i + m] < bl[i]) printf("%d ", i);
  return 0;
}
