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;
inline int in() {
  int32_t x;
  scanf("%d", &x);
  return x;
}
inline long long lin() {
  long long x;
  scanf("%lld", &x);
  return x;
}
inline string get() {
  char ch[1000010];
  scanf("%s", ch);
  return ch;
}
const int MAX_LG = 21;
const long long maxn = 5e5 + 100;
const long long base = 29;
const long long mod = 1e9 + 7;
const long long INF = 1e9 + 100;
long long n, m, v[maxn], u[maxn], c[maxn], t[maxn], cmp[maxn];
bool mark[maxn];
map<long long, long long> saw;
bool ok[maxn];
vector<long long> g[maxn], ing[maxn], outg[maxn];
inline void clause(long long v, long long u) {
  outg[v ^ 1].push_back(u);
  ing[u].push_back(v ^ 1);
  outg[u ^ 1].push_back(v);
  ing[v].push_back(u ^ 1);
}
inline long long R(long long x) { return 2 * x + 1; }
inline long long L(long long x) { return 2 * x; }
vector<long long> vc;
inline void dfs(long long v, long long pr = -1) {
  mark[v] = true;
  for (auto u : outg[v])
    if (!mark[u]) dfs(u, v);
  vc.push_back(v);
}
inline void dfs2(long long v, long long cur) {
  cmp[v] = cur;
  for (auto u : ing[v]) {
    if (cmp[u] == -1) dfs2(u, cur);
  }
}
inline bool check(long long lim) {
  vc.clear();
  long long cur = m;
  long long comp = 0;
  for (long long i = 0; i < maxn; i++) {
    ing[i].clear();
    outg[i].clear();
    mark[i] = 0, cmp[i] = -1;
    ok[i] = 0;
  }
  for (long long i = 0; i < m; i++) {
    if (t[i] > lim) {
      outg[L(i)].push_back(R(i));
      ing[R(i)].push_back(L(i));
    }
  }
  for (long long i = 1; i <= n; i++) {
    saw.clear();
    long long preedge = -1;
    for (auto e : g[i]) {
      if (preedge == -1)
        preedge = e;
      else {
        clause(R(preedge), R(e));
        clause(R(preedge), L(cur));
        clause(R(e), L(cur));
        preedge = cur++;
      }
      if (saw[c[e]] == 0)
        saw[c[e]] = e + 1;
      else if (saw[c[e]] == -1)
        return false;
      else {
        clause(L(saw[c[e]] - 1), L(e));
        saw[c[e]] = -1;
      }
    }
  }
  for (long long i = 0; i < 2 * cur; i++)
    if (!mark[i]) dfs(i);
  for (long long i = 2 * cur - 1; i >= 0; i--)
    if (cmp[vc[i]] == -1) dfs2(vc[i], comp++);
  for (long long i = 0; i < 2 * cur; i++) {
    if (cmp[i] == cmp[i ^ 1]) return false;
    if (i % 2 == 0 && cmp[i] > cmp[i ^ 1]) ok[i / 2] = true;
  }
  return true;
}
int32_t main() {
  n = in(), m = in();
  for (long long i = 0; i < m; i++) {
    v[i] = in(), u[i] = in(), c[i] = in(), t[i] = in();
    g[v[i]].push_back(i);
    g[u[i]].push_back(i);
  }
  long long l = 0, r = INF, mid, best = INF;
  while (l <= r) {
    mid = (l + r) >> 1;
    if (check(mid)) {
      best = mid;
      r = mid - 1;
      continue;
    }
    l = mid + 1;
  }
  if (best == INF) {
    return cout << "No\n"
                << "\n",
           0;
  }
  vector<long long> vc;
  check(best);
  for (long long i = 0; i < m; i++) {
    if (ok[i]) vc.push_back(i + 1);
  }
  cout << "Yes\n";
  cout << best << " " << vc.size() << "\n";
  for (auto e : vc) cout << e << " ";
}
