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 = 5e5 + 5;
struct edge {
  int c, t;
} e[N];
int n, m, tot, dfn[N << 2], low[N << 2], bel[N << 2], idx, cnt, tp, st[N << 2],
    in[N << 2];
vector<int> cur, v[N];
vector<int> to[N << 2];
void build1() {
  for (int i = 0, S, _S; i < cur.size(); ++i) {
    int x = cur[i], _x = x + m, s = ++tot, _s = ++tot;
    to[x].push_back(s);
    to[_s].push_back(_x);
    if (i)
      to[S].push_back(s), to[S].push_back(_x), to[x].push_back(_S),
          to[_s].push_back(_S);
    S = s, _S = _s;
  }
  cur.clear();
}
void build2() {
  for (int i = 0, S, _S; i < cur.size(); ++i) {
    int x = cur[i], _x = x + m, s = ++tot, _s = ++tot;
    to[s].push_back(x);
    to[_x].push_back(_s);
    if (i)
      to[s].push_back(S), to[_x].push_back(S), to[_S].push_back(x),
          to[_S].push_back(_s);
    S = s, _S = _s;
  }
  cur.clear();
}
void tarjan(int x) {
  dfn[x] = low[x] = ++idx;
  st[++tp] = x;
  in[x] = 1;
  for (auto y : to[x])
    if (!dfn[y])
      tarjan(y), low[x] = min(low[x], low[y]);
    else if (in[y])
      low[x] = min(low[x], dfn[y]);
  if (dfn[x] == low[x]) {
    ++cnt;
    while (st[tp] != x) bel[st[tp]] = cnt, in[st[tp]] = 0, --tp;
    bel[st[tp]] = cnt, in[st[tp]] = 0, --tp;
  }
}
bool check(int key) {
  for (int i = 1; i <= m; ++i)
    if (e[i].t > key) to[i].push_back(i + m);
  idx = cnt = 0;
  memset(dfn, 0, sizeof dfn);
  for (int i = 1; i <= tot; ++i)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= m; ++i)
    if (e[i].t > key) to[i].pop_back();
  for (int i = 1; i <= m; ++i)
    if (bel[i] == bel[i + m]) return 0;
  return 1;
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  tot = m << 1;
  int l = 0, r = 0;
  for (int i = 1; i <= m; ++i) {
    int x, y;
    cin >> x >> y >> e[i].c >> e[i].t;
    v[x].push_back(i), v[y].push_back(i);
    r = max(r, e[i].t);
  }
  for (int i = 1; i <= n; ++i) {
    sort(v[i].begin(), v[i].end(),
         [&](int x, int y) { return e[x].c < e[y].c; });
    cur = v[i];
    build1();
    for (int l = 0, r; l < v[i].size(); l = r + 1) {
      r = l;
      cur.push_back(v[i][l]);
      while (r + 1 < v[i].size() && e[v[i][r + 1]].c == e[v[i][l]].c)
        ++r, cur.push_back(v[i][r]);
      build2();
    }
  }
  if (!check(r))
    cout << "No" << endl;
  else {
    cout << "Yes" << endl;
    while (l < r) {
      int mid = (l + r) >> 1;
      if (check(mid))
        r = mid;
      else
        l = mid + 1;
    }
    check(l);
    vector<int> ans;
    for (int i = 1; i <= m; ++i)
      if (bel[i] < bel[i + m]) ans.push_back(i);
    cout << l << ' ' << ans.size() << endl;
    for (auto x : ans) cout << x << ' ';
    cout << endl;
  }
  return 0;
}
