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>
#pragma GCC optimize("Ofast", "inline")
using namespace std;
template <class T>
inline void read(T &x) {
  int ch = 0, f = 0;
  x = 0;
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = 1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
  if (f) x = -x;
}
const int N = 500005;
vector<int> g[N], d[N], Ans1, Ans2;
int dfn[N], low[N], id[N], st[N], ins[N], Index, nowID, top;
int w[N], c[N], n, m, cnt;
inline void tarjan(int u) {
  dfn[u] = low[u] = ++Index, st[++top] = u, ins[u] = 1;
  for (int i = 0; i < (int)g[u].size(); i++) {
    int v = g[u][i];
    if (!dfn[v])
      tarjan(v), low[u] = min(low[u], low[v]);
    else if (ins[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    ++nowID;
    while (st[top] != u) ins[st[top]] = 0, id[st[top]] = nowID, top--;
    ins[u] = 0, id[u] = nowID, top--;
  }
}
inline int check(int mid) {
  for (int i = 1; i <= cnt; i++) g[i].clear();
  cnt = m + m;
  for (int i = 1; i <= m; i++)
    if (w[i] > mid) g[i].push_back(i + m);
  for (int i = 1; i <= n; i++) {
    int l = 0, r = cnt, sz = (int)d[i].size();
    for (int j = 0; j < sz; j++) {
      g[r = ++cnt].push_back(d[i][j] + m);
      if (j) {
        g[r].push_back(r - 1);
        g[d[i][j]].push_back(r - 1);
      }
    }
    for (int j = sz - 1; ~j; j--) {
      g[r = ++cnt].push_back(d[i][j] + m);
      if (j < sz - 1) {
        g[r].push_back(r - 1);
        g[d[i][j]].push_back(r - 1);
      }
    }
    for (int j = 0; j <= sz; j++)
      if ((j && j < sz && c[d[i][j]] != c[d[i][j - 1]]) || j == sz) {
        for (int k = l; k <= j - 1; k++) {
          g[r = ++cnt].push_back(d[i][k]);
          if (k > l) {
            g[r].push_back(r - 1);
            g[d[i][k] + m].push_back(r - 1);
          }
        }
        for (int k = j - 1; k >= l; k--) {
          g[r = ++cnt].push_back(d[i][k]);
          if (k < j - 1) {
            g[r].push_back(r - 1);
            g[d[i][k] + m].push_back(r - 1);
          }
        }
        l = j;
      }
  }
  Index = 0, nowID = 0;
  for (int i = 1; i <= cnt; i++) dfn[i] = low[i] = id[i] = 0;
  for (int i = 1; i <= cnt; i++)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= m; i++)
    if (id[i] == id[i + m]) return 0;
  Ans1.clear(), Ans2.clear();
  for (int i = 1; i <= m; i++)
    if (id[i] < id[i + m])
      Ans1.push_back(i);
    else
      Ans2.push_back(i);
  return 1;
}
inline bool cmp(int x, int y) { return c[x] < c[y]; }
int main() {
  read(n), read(m);
  for (int i = 1, x, y; i <= m; i++) {
    read(x), read(y), read(c[i]), read(w[i]);
    d[x].push_back(i), d[y].push_back(i);
  }
  for (int i = 1; i <= n; i++) sort(d[i].begin(), d[i].end(), cmp);
  int l = 0, r = (0x3f3f3f3f), ans = (0x3f3f3f3f);
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      ans = mid, r = mid - 1;
    else
      l = mid + 1;
  }
  if (ans == (0x3f3f3f3f)) return puts("No"), 0;
  puts("Yes");
  cout << ans << " " << Ans1.size() << endl;
  for (int i = 0; i < (int)Ans1.size(); i++) printf("%d ", Ans1[i]);
  return 0;
}
