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 = 50 * 1000 + 3;
int n, m, u[N], v[N], c[N], t[N], sz, col[N << 3];
vector<int> edg[N], tim, g[N << 3], tmp[N << 3], ans, vec;
vector<pair<int, int> > bad;
bool mark[N << 3];
bool cmp(int a, int b) { return c[a] < c[b]; }
void _dfs(int v) {
  mark[v] = 1;
  for (auto u : g[v])
    if (!mark[u]) _dfs(u);
  vec.push_back(v);
  return;
}
void dfs(int v, int C) {
  mark[v] = 1;
  col[v] = C;
  for (auto u : g[v])
    if (!mark[u]) dfs(u, C);
  return;
}
bool check(int x) {
  for (int i = 0; i < (N << 3); i++) g[i].clear();
  for (auto p : bad) {
    int a = p.first, b = p.second;
    g[a * 2].push_back(b * 2 + 1);
    g[b * 2].push_back(a * 2 + 1);
  }
  sz = m;
  for (int i = 0; i < n; i++)
    if (!edg[i].empty()) {
      int cur = edg[i][0];
      for (int j = 1; j < (int)edg[i].size(); j++) {
        int a = edg[i][j];
        g[cur * 2 + 1].push_back(a * 2);
        g[a * 2 + 1].push_back(cur * 2);
        g[a * 2 + 1].push_back(sz * 2 + 1);
        g[sz * 2].push_back(a * 2);
        g[cur * 2 + 1].push_back(sz * 2 + 1);
        g[sz * 2].push_back(cur * 2);
        cur = sz++;
      }
    }
  sz *= 2;
  for (int i = 0; i < m; i++)
    if (t[i] > x) g[i * 2 + 1].push_back(i * 2);
  memset(mark, 0, sizeof mark);
  vec.clear();
  for (int i = 0; i < sz; i++)
    if (!mark[i]) _dfs(i);
  for (int i = 0; i < sz; i++) tmp[i].clear();
  for (int i = 0; i < sz; i++)
    for (int j = 0; j < int(g[i].size()); j++) tmp[g[i][j]].push_back(i);
  for (int i = 0; i < sz; i++) g[i] = tmp[i];
  int cl = 0;
  memset(mark, 0, sizeof mark);
  for (int i = int(vec.size()) - 1; i > -1; i--)
    if (!mark[vec[i]]) dfs(vec[i], cl++);
  ans.clear();
  sz /= 2;
  for (int i = 0; i < sz; i++) {
    if (col[i * 2] == col[i * 2 + 1]) return 0;
    if (i < m && col[i * 2] < col[i * 2 + 1]) ans.push_back(i);
  }
  return 1;
}
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(nullptr);
  cout.tie(nullptr);
  ;
  tim.push_back(0);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    cin >> u[i] >> v[i] >> c[i] >> t[i];
    u[i]--;
    v[i]--;
    edg[v[i]].push_back(i);
    edg[u[i]].push_back(i);
    tim.push_back(t[i]);
  }
  for (int i = 0; i < n; i++) {
    sort(edg[i].begin(), edg[i].end(), cmp);
    int num = 0;
    for (int e = 0; e < int(edg[i].size()); e++) {
      int pt = e + 1;
      while (pt < int(edg[i].size()) && c[edg[i][pt - 1]] == c[edg[i][pt]])
        pt++;
      if (pt - e > 2) return cout << "No\n", 0;
      if (pt - e == 2) {
        num++;
        if (num == 2) return cout << "No\n", 0;
        bad.push_back({edg[i][e], edg[i][e + 1]});
        e++;
      }
    }
  }
  sort(tim.begin(), tim.end());
  tim.resize(unique(tim.begin(), tim.end()) - tim.begin());
  int l = -1, r = int(tim.size());
  while (l + 1 < r) {
    int mid = (l + r) / 2;
    if (check(tim[mid]))
      r = mid;
    else
      l = mid;
  }
  if (r == int(tim.size())) return cout << "No\n", 0;
  check(tim[r]);
  cout << "Yes\n" << tim[r] << ' ' << ans.size() << '\n';
  for (auto a : ans) cout << a + 1 << ' ';
  return 0;
}
