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 E {
  int to, col, time, ind;
  E(int to, int col, int time, int ind)
      : to(to), col(col), time(time), ind(ind) {}
};
int n, m, cnt;
vector<E> g[50000];
int a[50000], b[50000], c[50000], d[50000], t[50000];
map<int, pair<int, int> > colInd;
const int INF = 1e9 + 99;
vector<int> sat[311111], rev[311111], tmp[311111], ord;
bool used[311111];
int cmp[311111], curCmp;
void dfs1(int v) {
  used[v] = true;
  for (int to : sat[v])
    if (!used[to]) {
      dfs1(to);
    }
  ord.push_back(v);
}
void dfs2(int v) {
  cmp[v] = curCmp;
  for (int to : rev[v])
    if (cmp[to] == -1) {
      dfs2(to);
    }
}
bool solve(int bound) {
  for (int i = 0; i < (int)(cnt << 1); ++i) sat[i] = tmp[i];
  for (int i = 0; i < (int)(m); ++i)
    if (t[i] > bound) {
      sat[i << 1].push_back((i << 1) | 1);
    }
  for (int i = 0; i < (int)(cnt << 1); ++i) rev[i].clear();
  for (int i = 0; i < (int)(cnt << 1); ++i)
    for (int to : sat[i]) {
      rev[to].push_back(i);
    }
  for (int i = 0; i < (int)(cnt << 1); ++i) used[i] = false;
  ord.clear();
  for (int i = 0; i < (int)(cnt << 1); ++i)
    if (!used[i]) {
      dfs1(i);
    }
  reverse(ord.begin(), ord.end());
  for (int i = 0; i < (int)(cnt << 1); ++i) cmp[i] = -1;
  curCmp = 0;
  for (int i : ord)
    if (cmp[i] == -1) {
      dfs2(i);
      ++curCmp;
    }
  for (int i = 0; i < (int)(cnt); ++i)
    if (cmp[i << 1] == cmp[(i << 1) | 1]) {
      return false;
    }
  return true;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < (int)(m); ++i) {
    int from, to, c, tt;
    scanf("%d%d%d%d", &from, &to, &c, &tt), --from, --to;
    g[from].push_back(E(to, c, tt, i));
    g[to].push_back(E(from, c, tt, i));
    t[i] = tt;
  }
  for (int i = 0; i < (int)(n); ++i) {
    a[i] = -1;
    for (E e : g[i]) {
      auto it = colInd.find(e.col);
      if (it != colInd.end()) {
        if (a[i] != -1) {
          printf("No\n");
          return 0;
        }
        a[i] = it->second.first;
        b[i] = e.ind;
        c[i] = it->second.second;
        d[i] = e.time;
      } else {
        colInd[e.col] = make_pair(e.ind, e.time);
      }
    }
    colInd.clear();
  }
  int lo = 0, hi = 0, mid;
  for (int i = 0; i < (int)(n); ++i)
    if (a[i] != -1) {
      lo = max(lo, min(c[i], d[i]));
      hi = max(hi, max(c[i], d[i]));
    }
  if (hi == 0) {
    printf("Yes\n0 0\n");
    return 0;
  }
  cnt = m;
  for (int i = 0; i < (int)(n); ++i)
    if ((int)g[i].size() > 1) {
      for (int j = 0; j < (int)((int)g[i].size() - 1); ++j) {
        tmp[g[i][j].ind << 1].push_back((cnt + j) << 1);
        tmp[((cnt + j) << 1) | 1].push_back((g[i][j].ind << 1) | 1);
      }
      for (int j = 0; j < (int)((int)g[i].size() - 2); ++j) {
        tmp[(cnt + j) << 1].push_back((cnt + j + 1) << 1);
        tmp[((cnt + j + 1) << 1) | 1].push_back(((cnt + j) << 1) | 1);
      }
      for (int j = 1; j < (int)g[i].size(); ++j) {
        tmp[g[i][j].ind << 1].push_back(((cnt + j - 1) << 1) | 1);
        tmp[(cnt + j - 1) << 1].push_back((g[i][j].ind << 1) | 1);
      }
      cnt += (int)g[i].size() - 1;
    }
  for (int i = 0; i < (int)(n); ++i)
    if (a[i] != -1) {
      tmp[(a[i] << 1) | 1].push_back(b[i] << 1);
      tmp[(b[i] << 1) | 1].push_back(a[i] << 1);
    }
  while (lo < hi) {
    mid = (lo + hi) >> 1;
    if (solve(mid)) {
      hi = mid;
    } else {
      lo = mid + 1;
    }
  }
  if (solve(lo)) {
    printf("Yes\n");
    vector<int> ans;
    for (int i = 0; i < (int)(m); ++i)
      if (cmp[(i << 1) | 1] < cmp[i << 1]) {
        ans.push_back(i);
      }
    printf("%d %d\n", lo, (int)ans.size());
    for (int x : ans) printf("%d ", x + 1);
    printf("\n");
  } else {
    printf("No\n");
  }
  return 0;
}
