#include <bits/stdc++.h>
using namespace std;
const int maxin = 5e4 + 10, maxn = 3e5 + 10, inf = 1e9 + 1;
int n, m, l, col[maxn], pos, comp[maxn], size[maxn], size2[maxn], ntscc[maxn],
    ans[maxin], answer;
vector<int> vec[maxn], adj[maxn], adj2[maxn], scc;
bitset<maxn> mark;
pair<int, int> e[maxin];
int nt(int v) { return v < l ? v + l : v - l; }
void cnd(int v, int u) {
  adj[nt(v)].push_back(u);
  adj[nt(u)].push_back(v);
  adj2[u].push_back(nt(v));
  adj2[v].push_back(nt(u));
  return;
}
void dfs(int v) {
  mark[v] = true;
  for (auto u : adj[v])
    if (!mark[u]) dfs(u);
  scc.push_back(v);
  return;
}
void dfs2(int v, int color) {
  col[v] = color;
  for (auto u : adj2[v])
    if (col[u] == -1) dfs2(u, color);
  return;
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  l = 3 * m;
  for (int i = 0, v, u, c, t; i < m; ++i) {
    cin >> v >> u >> c >> t;
    comp[pos++] = c;
    vec[--v].push_back(i);
    vec[--u].push_back(i);
    e[i] = {c, t};
  }
  sort(comp, comp + pos);
  pos = unique(comp, comp + pos) - comp;
  for (int i = 0; i < m; ++i)
    e[i].first = lower_bound(comp, comp + pos, e[i].first) - comp;
  pos = m;
  for (int i = 0, se, cnt, myc; i < n; ++i) {
    se = vec[i].size(), cnt = 0, myc = 0;
    for (int j = 0; j < se; ++j, ++pos) {
      cnd(nt(vec[i][j]), pos);
      if (j) cnd(nt(pos - 1), pos), cnd(nt(vec[i][j]), nt(pos - 1));
    }
    for (auto j : vec[i])
      if (!mark[e[j].first]) {
        cnt++;
        mark[e[j].first] = true;
      } else
        myc = e[j].first;
    if (se - cnt >= 2) return cout << "No\n", 0;
    for (auto j : vec[i]) mark[e[j].first] = false;
    if (se == cnt) continue;
    int v = -1, u = -1;
    for (auto j : vec[i])
      if (e[j].first == myc) {
        if (~v)
          u = j;
        else
          v = j;
      }
    cnd(v, u);
  }
  for (int i = 0; i < (l << 1); ++i)
    size[i] = adj[i].size(), size2[i] = adj2[i].size();
  int begin = -1, end = inf, mid;
  while (end - begin > 1) {
    bool flag = true;
    mid = (begin + end) >> 1;
    for (int i = 0; i < (l << 1); ++i)
      adj[i].resize(size[i]), adj2[i].resize(size2[i]);
    for (int i = 0; i < m; ++i)
      if (e[i].second > mid) cnd(i + l, i + l);
    scc.clear();
    for (int i = 0; i < (l << 1); ++i)
      if (!mark[i]) dfs(i);
    mark.reset();
    reverse(scc.begin(), scc.end());
    memset(col, -1, sizeof(col));
    int color = 0;
    for (auto i : scc)
      if (col[i] == -1) dfs2(i, color++);
    for (int i = 0; i < l; ++i)
      if (col[i] == col[i + l]) flag = false;
    if (flag) {
      for (int i = 0; i < (l << 1); ++i) ntscc[col[i]] = col[nt(i)];
      for (int i = color - 1; ~i; --i)
        if (!mark[ntscc[i]]) mark[i] = true;
      answer = 0;
      for (int i = 0; i < m; ++i)
        if (mark[col[i]]) ans[answer++] = i + 1;
      mark.reset();
    }
    if (flag)
      end = mid;
    else
      begin = mid;
  }
  if (end == inf) return cout << "No\n", 0;
  cout << "Yes\n" << end << ' ' << answer << '\n';
  for (int i = 0; i < answer; ++i) cout << ans[i] << ' ';
  cout << '\n';
  return 0;
}
