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 RLEN = 1 << 20 | 1;
inline char gc() {
  static char ibuf[RLEN], *ib, *ob;
  (ib == ob) && (ob = (ib = ibuf) + fread(ibuf, 1, RLEN, stdin));
  return (ib == ob) ? EOF : *ib++;
}
inline int read() {
  char ch = gc();
  int res = 0;
  bool f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) res = (res + (res << 2) << 1) + (ch ^ 48), ch = gc();
  return f ? res : -res;
}
inline long long readll() {
  char ch = gc();
  long long res = 0;
  bool f = 1;
  while (!isdigit(ch)) f ^= ch == '-', ch = gc();
  while (isdigit(ch)) res = (res + (res << 2) << 1) + (ch ^ 48), ch = gc();
  return f ? res : -res;
}
inline int readstring(char *s) {
  int top = 0;
  char ch = gc();
  while (isspace(ch)) ch = gc();
  while (!isspace(ch) && ch != EOF) s[++top] = ch, ch = gc();
  s[top + 1] = '\0';
  return top;
}
template <typename tp>
inline void chemx(tp &a, tp b) {
  a = max(a, b);
}
template <typename tp>
inline void chemn(tp &a, tp b) {
  a = min(a, b);
}
const int mod = 1e9 + 7;
inline int add(int a, int b) {
  return (a + b) >= mod ? (a + b - mod) : (a + b);
}
inline int dec(int a, int b) { return (a < b) ? (a - b + mod) : (a - b); }
inline int mul(int a, int b) {
  static long long r;
  r = (long long)a * b;
  return (r >= mod) ? (r % mod) : r;
}
inline void Add(int &a, int b) { a = (a + b) >= mod ? (a + b - mod) : (a + b); }
inline void Dec(int &a, int b) { a = (a < b) ? (a - b + mod) : (a - b); }
inline void Mul(int &a, int b) {
  static long long r;
  r = (long long)a * b;
  a = (r >= mod) ? (r % mod) : r;
}
inline int ksm(int a, int b, int res = 1) {
  for (; b; b >>= 1, Mul(a, a)) (b & 1) && (Mul(res, a), 1);
  return res;
}
inline int Inv(int x) { return ksm(x, mod - 2); }
inline int fix(long long x) {
  x %= mod;
  return (x < 0) ? x + mod : x;
}
const int N = 50005, M = N * 10;
vector<int> e[M];
vector<int> edge[N];
struct Edge {
  int u, v, c, t;
} E[N];
int low[M], dfn[M], stk[M], top, tim, bel[M], vis[M], tot, belnum;
int n, m;
inline void tarjan(int u) {
  low[u] = dfn[u] = ++tim;
  stk[++top] = u, vis[u] = 1;
  for (int &v : e[u]) {
    if (!dfn[v]) {
      tarjan(v), chemn(low[u], low[v]);
    } else if (vis[v]) {
      chemn(low[u], dfn[v]);
    }
  }
  if (low[u] == dfn[u]) {
    belnum++;
    int tmp;
    do {
      tmp = stk[top--];
      bel[tmp] = belnum, vis[tmp] = 0;
    } while (tmp != u);
  }
}
inline bool check(int k) {
  for (int i = 1; i <= m; i++)
    if (E[i].t > k) e[i].push_back(i + m);
  for (int i = 1; i <= tot; i++) bel[i] = dfn[i] = low[i] = vis[i] = 0;
  top = tim = belnum = 0;
  int res = 1;
  for (int i = 1; i <= tot; i++)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= m; i++)
    if (bel[i] == bel[i + m]) res = 0;
  for (int i = 1; i <= m; i++)
    if (E[i].t > k) e[i].pop_back();
  return res;
}
inline void link1(const vector<int> &a) {
  int now0, now1, pre0, pre1;
  for (int i = 0; i < a.size(); i++) {
    int u = a[i], v = a[i] + m;
    now0 = ++tot, now1 = ++tot;
    e[u].push_back(now0), e[now1].push_back(v);
    if (i > 0)
      e[pre0].push_back(v), e[u].push_back(pre1), e[pre0].push_back(now0),
          e[now1].push_back(pre1);
    pre0 = now0, pre1 = now1;
  }
}
inline void Link2(const vector<int> &a) {
  int now0, now1, pre0, pre1;
  for (int i = 0; i < a.size(); i++) {
    int u = a[i], v = a[i] + m;
    now0 = ++tot, now1 = ++tot;
    e[now0].push_back(u), e[v].push_back(now1);
    if (i > 0)
      e[v].push_back(pre0), e[pre1].push_back(u), e[now0].push_back(pre0),
          e[pre1].push_back(now1);
    pre0 = now0, pre1 = now1;
  }
}
inline void link2(const vector<int> &a) {
  vector<int> now;
  for (int j = 0, r = 0; j < a.size(); j = ++r) {
    now.push_back(a[j]);
    while (r + 1 < a.size() && E[a[r + 1]].c == E[a[r]].c)
      now.push_back(a[++r]);
    Link2(now);
    now.clear();
  }
}
int ans[N], cnt, b[N];
int main() {
  n = read(), m = read();
  for (int i = 1; i <= m; i++) {
    E[i].u = read(), E[i].v = read(), E[i].c = read(), E[i].t = read();
    b[i] = E[i].t;
    edge[E[i].u].push_back(i), edge[E[i].v].push_back(i);
  }
  tot = m * 2;
  for (int i = 1; i <= n; i++) {
    sort(edge[i].begin(), edge[i].end(),
         [&](const int &i, const int &j) { return E[i].c < E[j].c; });
    link1(edge[i]), link2(edge[i]);
  }
  b[m + 1] = 0;
  sort(b + 1, b + m + 2);
  int l = 1, r = m + 1, res = -1;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(b[mid]))
      r = mid - 1, res = mid;
    else
      l = mid + 1;
  }
  if (res == -1) return puts("No"), 0;
  puts("Yes");
  check(b[res]);
  for (int i = 1; i <= m; i++)
    if (bel[i] < bel[i + m]) ans[++cnt] = i;
  cout << b[res] << " " << cnt << '\n';
  for (int i = 1; i <= cnt; i++) cout << ans[i] << " ";
  return 0;
}
