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 char nc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline void Read(int& x) {
  char c = nc();
  for (; c < '0' || c > '9'; c = nc())
    ;
  for (x = 0; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - 48, c = nc())
    ;
}
inline void Read(long long& x) {
  char c = nc();
  for (; c < '0' || c > '9'; c = nc())
    ;
  for (x = 0; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - 48, c = nc())
    ;
}
struct Edge {
  int x, y, c, f;
} e[50010 << 1];
vector<int> g[2000000];
int i, j, k, n, m, p, T, cnt, c[50010];
int num, pr[2000000], sf[2000000];
int dfn[2000000], low[2000000], f[2000000], st[2000000], top;
int l, r, t[50010];
inline bool Cmp(Edge a, Edge b) {
  if (a.x == b.x) return a.c < b.c;
  return a.x < b.x;
}
inline void Dfs(int x) {
  dfn[x] = low[x] = ++T;
  st[++top] = x;
  for (int i = 0; i < g[x].size(); i++) {
    int v = g[x][i];
    if (!dfn[v])
      Dfs(v), low[x] = min(low[x], low[v]);
    else if (!f[v])
      low[x] = min(low[x], dfn[v]);
  }
  if (low[x] == dfn[x]) {
    cnt++;
    while (st[top] != x) f[st[top--]] = cnt;
    f[st[top--]] = cnt;
  }
}
inline bool Check(int x) {
  for (int i = 1; i <= m / 2; i++)
    if (t[i] > x) g[i * 2 - 1].push_back(i * 2);
  bool F = 1;
  memset(dfn, 0, sizeof(dfn));
  memset(f, 0, sizeof(f));
  T = cnt = 0;
  for (int i = 1; i <= num; i++)
    if (!dfn[i]) Dfs(i);
  for (int i = 1; i <= m / 2; i++)
    if (f[i * 2] == f[i * 2 - 1]) {
      F = 0;
      break;
    }
  for (int i = 1; i <= m / 2; i++)
    if (t[i] > x) g[i * 2 - 1].pop_back();
  return F;
}
int main() {
  Read(n);
  Read(m);
  for (i = 1; i <= m; i++)
    Read(e[i].x), Read(e[i].y), Read(e[i].c), Read(t[i]),
        e[i].f = i, e[i + m] = e[i], swap(e[i + m].x, e[i + m].y),
        r = max(r, t[i]);
  m <<= 1;
  sort(e + 1, e + m + 1, Cmp);
  num = m;
  for (i = 1; i <= m; i = j + 1) {
    pr[i] = ++num;
    sf[i] = ++num;
    for (j = i; j <= m && e[j + 1].x == e[j].x && e[j + 1].c == e[j].c;)
      pr[++j] = ++num, sf[j] = ++num;
    for (p = i; p <= j; p++) {
      if (p > i)
        g[e[p].f * 2].push_back(pr[p - 1]), g[pr[p]].push_back(pr[p - 1]);
      if (p < j)
        g[e[p].f * 2].push_back(sf[p + 1]), g[sf[p]].push_back(sf[p + 1]);
      g[pr[p]].push_back(e[p].f * 2 - 1);
      g[sf[p]].push_back(e[p].f * 2 - 1);
    }
  }
  for (i = 1; i <= m; i = j + 1) {
    pr[i] = ++num;
    sf[i] = ++num;
    for (j = i; j <= m && e[j + 1].x == e[j].x;) pr[++j] = ++num, sf[j] = ++num;
    for (p = i; p <= j; p++) {
      if (p > i)
        g[e[p].f * 2 - 1].push_back(pr[p - 1]), g[pr[p]].push_back(pr[p - 1]);
      if (p < j)
        g[e[p].f * 2 - 1].push_back(sf[p + 1]), g[sf[p]].push_back(sf[p + 1]);
      g[pr[p]].push_back(e[p].f * 2);
      g[sf[p]].push_back(e[p].f * 2);
    }
  }
  if (!Check(r)) {
    puts("No");
    return 0;
  }
  while (l <= r) {
    int Mid = l + r >> 1;
    if (Check(Mid))
      r = Mid - 1;
    else
      l = Mid + 1;
  }
  puts("Yes");
  Check(l);
  k = 0;
  for (i = 1; i <= m / 2; i++)
    if (f[i * 2 - 1] < f[i * 2]) c[++k] = i;
  printf("%d %d\n", l, k);
  for (i = 1; i <= k; i++) printf("%d ", c[i]);
  return 0;
}
