#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 100;
const int sq = 316;
const long long int mod = 998244353;
const int inf = 1e9 + 100;
int n, m, com = 0;
int c[N], t[N], bl[N];
bool mark[N];
vector<int> in[N], out[N], adj[N], tp, ans;
vector<pair<int, int>> e, edge, tmp;
inline void cl() {
  tp.clear();
  com = 0;
  for (int i = 0; i < N; i++) {
    bl[i] = mark[i] = 0;
    out[i].clear();
    in[i].clear();
  }
}
void dfs(int u) {
  mark[u] = true;
  for (auto x : out[u]) {
    if (!mark[x]) dfs(x);
  }
  tp.push_back(u);
}
void rdfs(int u) {
  mark[u] = true;
  bl[u] = com;
  for (auto x : in[u]) {
    if (!mark[x]) rdfs(x);
  }
}
void add(int x, int y) {
  out[x].push_back(y);
  in[y].push_back(x);
}
bool check(int mid) {
  cl();
  for (int i = 0; i < m; i++) {
    if (t[i] > mid) add(2 * i + 1, 2 * i);
  }
  for (auto it : e) {
    int x = it.first, y = it.second;
    add(2 * x, 2 * y + 1);
    add(2 * y, 2 * x + 1);
  }
  int pt = m;
  for (int u = 0; u < n; u++) {
    if (adj[u].size() == 0) continue;
    int x = adj[u][0];
    for (int i = 1; i < adj[u].size(); i++) {
      int y = adj[u][i];
      add(pt * 2, x * 2);
      add(x * 2 + 1, pt * 2 + 1);
      add(y * 2 + 1, x * 2);
      add(x * 2 + 1, y * 2);
      add(y * 2 + 1, pt * 2 + 1);
      add(pt * 2, y * 2);
      x = pt++;
    }
  }
  pt *= 2;
  for (int i = 0; i < pt; i++) {
    if (!mark[i]) dfs(i);
  }
  for (int i = 0; i < N; i++) mark[i] = 0;
  for (int i = tp.size() - 1; i >= 0; i--) {
    int u = tp[i];
    if (!mark[u]) {
      com++;
      rdfs(u);
    }
  }
  for (int i = 0; i < pt / 2; i++) {
    if (bl[i * 2 + 1] == bl[i * 2]) return 0;
  }
  return 1;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y >> c[i] >> t[i];
    x--;
    y--;
    edge.push_back({x, y});
    adj[x].push_back(i);
    adj[y].push_back(i);
  }
  bool fl = true;
  for (int u = 0; u < n; u++) {
    tmp.clear();
    for (auto it : adj[u]) tmp.push_back({c[it], it});
    sort(tmp.begin(), tmp.end());
    adj[u].clear();
    for (auto it : tmp) adj[u].push_back(it.second);
    int sztmp = int(tmp.size());
    int k = 0;
    for (int i = 0; i < sztmp;) {
      int cnt = 0, cl = tmp[i].first;
      while (i < sztmp && tmp[i].first == cl) {
        cnt++;
        i++;
      }
      if (cnt > 2) {
        cout << "No" << endl;
        return 0;
      }
      if (cnt == 2) {
        e.push_back({tmp[i - 2].second, tmp[i - 1].second});
        k++;
      }
    }
    if (k > 1) {
      cout << "No" << endl;
      return 0;
    }
  }
  int l = -1, r = inf;
  while (l + 1 < r) {
    int mid = (l + r) / 2;
    if (check(mid)) {
      r = mid;
    } else {
      l = mid;
    }
  }
  if (r >= inf) {
    cout << "No" << endl;
    return 0;
  }
  cout << "Yes" << endl << r << ' ';
  check(r);
  for (int i = 0; i < m; i++) {
    if (bl[i * 2] < bl[i * 2 + 1]) {
      ans.push_back(i + 1);
    }
  }
  cout << ans.size() << endl;
  for (auto it : ans) cout << it << ' ';
  cout << endl;
  return 0;
}
