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;
struct Edge {
  int to, c, t, id;
};
int n, m;
vector<Edge> E[50004];
vector<Edge> E2[50004];
vector<int> E3[200025];
int p;
int V[200025], low[200025], ts;
int stack[200025], top;
bool instack[200025];
int scc[200025];
int scchead[200025], htop = 0;
short sat[200025];
void dfs(int i) {
  V[i] = low[i] = ++ts;
  stack[top++] = i;
  instack[i] = 1;
  for (auto x : E3[i]) {
    if (!V[x])
      dfs(x), low[i] = min(low[i], low[x]);
    else if (instack[x])
      low[i] = min(low[i], V[x]);
  }
  if (V[i] == low[i]) {
    int j;
    do {
      j = stack[--top];
      instack[j] = 0;
      scc[j] = i;
    } while (j != i);
    scchead[htop++] = i;
  }
}
bool twoSAT() {
  ts = 0, top = 0, htop = 0;
  fill(V, V + 2 * p, 0);
  for (int i = 0; i < 2 * p; ++i)
    if (!V[i]) dfs(i);
  for (int i = 0; i < p; ++i)
    if (scc[2 * i] == scc[2 * i + 1]) return 0;
  return 1;
}
bool build() {
  p = m;
  for (int i = 1; i <= n; ++i) {
    int vcnt = 0;
    for (auto &&x : E[i]) {
      for (auto &&k : E2[i])
        if (x.c == k.c) {
          ++vcnt;
          if (vcnt >= 2) return 0;
          E3[2 * x.id].push_back(2 * k.id + 1);
          E3[2 * k.id].push_back(2 * x.id + 1);
        }
      E3[2 * x.id + 1].push_back(2 * p + 1);
      E3[2 * p].push_back(2 * x.id);
      if (!E2[i].empty()) {
        E3[2 * (p - 1) + 1].push_back(2 * p + 1);
        E3[2 * p].push_back(2 * (p - 1));
        E3[2 * (p - 1) + 1].push_back(2 * x.id);
        E3[2 * x.id + 1].push_back(2 * (p - 1));
      }
      ++p;
      E2[i].push_back({x.to, x.c, x.t, x.id});
    }
  }
  return 1;
}
bool check(int d, bool findsol) {
  for (int i = 1; i <= n; ++i)
    for (auto &&x : E[i])
      if (x.c > d) E3[2 * x.id].push_back(2 * x.id + 1);
  bool feasible = twoSAT();
  for (int i = 1; i <= n; ++i)
    for (auto &&x : E[i])
      if (x.c > d) E3[2 * x.id].pop_back();
  if (!feasible) return 0;
  if (findsol) {
    fill(sat, sat + htop, 0);
    for (int i = 0; i < htop; ++i)
      if (!sat[scc[scchead[i]]])
        sat[scc[scchead[i]]] = 1, sat[scc[scchead[i] ^ 1]] = 2;
  }
  return 1;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  int maxt = 0;
  for (int i = 0, v, u, c, t; i < m; ++i) {
    cin >> v >> u >> c >> t;
    E[v].push_back({u, c, t, i});
    E[u].push_back({v, c, t, i});
    maxt = max(maxt, t);
  }
  if (!build()) {
    cout << "No\n";
    return 0;
  }
  int l = 0, r = maxt;
  while (l < r) {
    int mid = (l + r) / 2;
    if (check(mid, 0))
      r = mid;
    else
      l = mid + 1;
  }
  if (check(l, 1)) {
    cout << "Yes\n" << l << ' ';
    vector<int> sol;
    for (int i = 0; i < m; ++i)
      if (sat[scc[2 * i + 1]] == 1) sol.push_back(i + 1);
    cout << sol.size() << '\n';
    for (auto x : sol) cout << x << ' ';
    cout << endl;
  } else
    cout << "No\n";
  return 0;
}
