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;
int from[50005], to[50005], color[50005], cost[50005];
vector<int> aristas[50005];
vector<int> auxGraph[8 * 50005], temp[8 * 50005];
vector<int> Cvals;
vector<pair<int, int>> toFix;
vector<int> answer;
bool marks[8 * 50005];
int scc[8 * 50005];
vector<int> tp;
int sz, n, m;
bool cmp(int x, int y) { return (color[x] < color[y]); }
void init();
bool check(int lim);
void sfd(int v, int col);
void dfs(int v);
int main() {
  cin >> n >> m;
  Cvals.push_back(0);
  for (int i = 0; i < m; i++) {
    cin >> from[i] >> to[i] >> color[i] >> cost[i];
    Cvals.push_back(cost[i]);
    from[i]--;
    to[i]--;
    aristas[from[i]].push_back(i);
    aristas[to[i]].push_back(i);
  }
  for (int i = 0; i < n; i++) {
    sort(aristas[i].begin(), aristas[i].end(), cmp);
    int cant = 0;
    for (int j = 0; j < (int)aristas[i].size(); j++) {
      int pos = j + 1;
      while (pos < (int)aristas[i].size() &&
             color[aristas[i][pos - 1]] == color[aristas[i][pos]])
        pos++;
      if (pos - j > 2) {
        cout << "No\n";
        return 0;
      }
      if (pos - j == 2) {
        cant++;
        if (cant == 2) {
          cout << "No\n";
          return 0;
        }
        toFix.push_back(make_pair(aristas[i][j], aristas[i][j + 1]));
        j++;
      }
    }
  }
  sort(Cvals.begin(), Cvals.end());
  Cvals.resize(unique(Cvals.begin(), Cvals.end()) - Cvals.begin());
  int left = -1, right = (int)Cvals.size();
  while (right - left > 1) {
    int medio = (left + right) / 2;
    if (check(Cvals[medio]))
      right = medio;
    else
      left = medio;
  }
  if (right == (int)Cvals.size()) {
    cout << "No\n";
    return 0;
  }
  check(Cvals[right]);
  cout << "Yes\n";
  cout << Cvals[right] << " " << (int)answer.size() << endl;
  for (int i = 0; i < (int)answer.size(); i++) printf("%d ", answer[i] + 1);
  printf("\n");
  return 0;
}
bool check(int lim) {
  init();
  sz *= 2;
  for (int i = 0; i < m; i++)
    if (cost[i] > lim) auxGraph[2 * i + 1].push_back(2 * i);
  memset(marks, false, sizeof(marks));
  tp.clear();
  for (int i = 0; i < sz; i++)
    if (!marks[i]) dfs(i);
  reverse(tp.begin(), tp.end());
  for (int i = 0; i < sz; i++) temp[i].clear();
  for (int v = 0; v < sz; v++)
    for (int i = 0; i < (int)auxGraph[v].size(); i++)
      temp[auxGraph[v][i]].push_back(v);
  for (int i = 0; i < sz; i++) auxGraph[i] = temp[i];
  int cnt = 0;
  memset(marks, false, sizeof(marks));
  for (int i = 0; i < (int)tp.size(); i++)
    if (!marks[tp[i]]) sfd(tp[i], cnt++);
  answer.clear();
  for (int i = 0; i < sz / 2; i++) {
    if (scc[2 * i] == scc[2 * i + 1]) return false;
    if (i < m && scc[2 * i] < scc[2 * i + 1]) answer.push_back(i);
  }
  return true;
}
void init() {
  for (int i = 0; i < 50005 * 8; i++) auxGraph[i].clear();
  int tfFrom, tfTo;
  for (int i = 0; i < (int)toFix.size(); i++) {
    tfFrom = toFix[i].first;
    tfTo = toFix[i].second;
    auxGraph[2 * tfFrom].push_back(2 * tfTo + 1);
    auxGraph[2 * tfTo].push_back(2 * tfFrom + 1);
  }
  sz = m;
  for (int i = 0; i < n; i++) {
    if (!aristas[i].empty()) {
      int last = aristas[i][0];
      for (int j = 1; j < (int)aristas[i].size(); j++) {
        int id = aristas[i][j];
        auxGraph[2 * last + 1].push_back(2 * id);
        auxGraph[2 * id + 1].push_back(2 * last);
        auxGraph[2 * id + 1].push_back(2 * sz + 1);
        auxGraph[2 * sz].push_back(2 * id);
        auxGraph[2 * last + 1].push_back(2 * sz + 1);
        auxGraph[2 * sz].push_back(2 * last);
        last = sz++;
      }
    }
  }
}
void sfd(int v, int col) {
  marks[v] = true;
  scc[v] = col;
  for (int i = 0; i < (int)auxGraph[v].size(); i++) {
    int u = auxGraph[v][i];
    if (!marks[u]) sfd(u, col);
  }
}
void dfs(int v) {
  marks[v] = true;
  for (int i = 0; i < (int)auxGraph[v].size(); i++) {
    int u = auxGraph[v][i];
    if (!marks[u]) dfs(u);
  }
  tp.push_back(v);
}
