#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 10;
const int MN = 5e4 + 10, MS = 10 * MN;
int n, m;
vector<pair<int, int> > adj[MN];
vector<int> adj_sat[MS], rev_sat[MS];
bool mk[MS], seen[MS], is[MS];
int es[MN], ee[MN], et[MN], ec[MN];
int topol[MS], tp_sz, col[MS];
bool cmp(const pair<int, int> &a, const pair<int, int> &b) {
  return ec[a.second] < ec[b.second];
}
int Not(const int &x) { return x >= (5 * m) ? x - (5 * m) : x + (5 * m); }
void add_clause(int x, int y) {
  adj_sat[Not(x)].push_back(y), adj_sat[Not(y)].push_back(x);
  rev_sat[y].push_back(Not(x)), rev_sat[x].push_back(Not(y));
}
int calc(int v, int ind, bool f) {
  int e = adj[v][ind].second;
  if (es[e] == v)
    e *= 2;
  else
    e = 2 * e + 1;
  if (f)
    e += 3 * m;
  else
    e += m;
  return e;
}
void dfs(int s) {
  mk[s] = true;
  for (auto v : adj_sat[s])
    if (!mk[v]) dfs(v);
  topol[tp_sz++] = s;
}
void sfd(int s, int c) {
  mk[s] = true, col[s] = c;
  for (auto v : rev_sat[s])
    if (!mk[v]) sfd(v, c);
}
bool check(int val) {
  for (int i = 0; i < MS; ++i) adj_sat[i].clear(), rev_sat[i].clear();
  for (int i = 0; i < m; ++i)
    if (et[i] > val) add_clause(Not(i), Not(i));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < ((int)(adj[i]).size()); ++j) {
      int v = adj[i][j].first, e = adj[i][j].second;
      add_clause(Not(e), Not(calc(i, j, 0)));
      if (j == 0) continue;
      int e1 = adj[i][j - 1].second;
      add_clause(calc(i, j, 0), Not(e1));
      add_clause(calc(i, j, 0), Not(calc(i, j - 1, 0)));
    }
    vector<int> tmp;
    for (int j = 0; j < ((int)(adj[i]).size()); ++j) {
      int v = adj[i][j].first, e = adj[i][j].second;
      if (j && ec[e] != ec[adj[i][j - 1].second]) tmp.clear();
      add_clause(e, calc(i, j, 1));
      if (tmp.empty()) {
        tmp.push_back(e);
        continue;
      }
      int e1 = tmp.back();
      tmp.push_back(e);
      add_clause(Not(calc(i, j, 1)), e1);
      add_clause(Not(calc(i, j, 1)), calc(i, j - 1, 1));
    }
  }
  memset(mk, 0, sizeof mk);
  tp_sz = 0;
  for (int i = 0; i < 2 * 5 * m; ++i)
    if (!mk[i]) dfs(i);
  int cmp = 0;
  memset(mk, 0, sizeof mk);
  for (int i = 2 * 5 * m - 1; ~i; --i)
    if (!mk[topol[i]]) sfd(topol[i], cmp++);
  for (int i = 0; i < 5 * m; ++i)
    if (col[i] == col[i + 5 * m]) return false;
  return true;
}
void make_ans() {
  for (int i = 0; i < m; ++i)
    if (col[i] > col[Not(i)])
      is[i] = true;
    else
      is[i] = false;
}
int main() {
  ios_base ::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    cin >> es[i] >> ee[i] >> ec[i] >> et[i];
    --es[i], --ee[i];
    adj[es[i]].push_back({ee[i], i});
    adj[ee[i]].push_back({es[i], i});
  }
  for (int i = 0; i < n; ++i) sort(adj[i].begin(), adj[i].end(), cmp);
  int L = 0, R = INF;
  while (L != R) {
    int mid = L + R >> 1;
    if (check(mid))
      R = mid;
    else
      L = mid + 1;
  }
  if (check(L)) {
    make_ans();
    vector<int> res;
    for (int i = 0; i < m; ++i)
      if (is[i]) res.push_back(i);
    cout << "Yes\n" << L << ' ' << ((int)(res).size()) << endl;
    for (int i = 0; i < ((int)(res).size()); ++i) cout << res[i] + 1 << ' ';
    cout << endl;
  } else
    cout << "No\n";
  return 0;
}
