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 gi() {
  char c = getchar();
  int x = 0;
  for (; c < '0' || c > '9'; c = getchar())
    ;
  for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
  return x;
}
const int N = 3e5 + 5;
struct node {
  int v, col, w, id;
};
vector<node> e[N];
bool operator<(node x, node y) { return x.col < y.col; }
int n, m, id, L, R, bel[N], scc, dfn[N], low[N], tid, stk[N], tp;
bool ins[N];
vector<int> ne[N], ans;
void adde(int u, int v, int c, int w, int id) {
  e[u].push_back((node){v, c, w, id});
  e[v].push_back((node){u, c, w, id});
}
void adde(int u, int v) {
  ne[u].push_back(v);
  ne[v ^ 1].push_back(u ^ 1);
}
void tarjan(int u) {
  dfn[u] = low[u] = ++tid;
  ins[u] = true, stk[++tp] = u;
  for (auto v : ne[u])
    if (!dfn[v])
      tarjan(v), low[u] = min(low[v], low[u]);
    else if (ins[v])
      low[u] = min(low[v], dfn[u]);
  if (dfn[u] == low[u]) {
    int v;
    ++scc;
    do {
      v = stk[tp--];
      ins[v] = false, bel[v] = scc;
    } while (u != v);
  }
}
void init() {
  memset(bel, 0, sizeof(bel)), memset(dfn, 0, sizeof(dfn)),
      memset(low, 0, sizeof(low)), scc = tp = tid = 0;
  for (int i = 1; i <= 4 * m; ++i) ne[i].clear();
}
bool check(int mid) {
  init();
  for (int u = 1; u <= n; ++u) {
    bool f = true;
    for (int i = 1; i < e[u].size(); ++i) {
      const int id = e[u][i].id, lid = e[u][i - 1].id;
      adde(2 * (m + lid), 2 * (m + id));
      adde(2 * (m + lid), 2 * id + 1);
      adde(2 * id, 2 * (m + id));
      if (e[u][i - 1].col == e[u][i].col) {
        if (f)
          f = false;
        else
          return false;
        adde(2 * lid + 1, 2 * id);
        adde(2 * lid, 2 * id + 1);
      }
    }
    for (int i = 0; i < e[u].size(); ++i) {
      const int id = e[u][i].id;
      adde(2 * id, 2 * (m + id));
      if (e[u][i].w > mid) adde(2 * id, 2 * id + 1);
    }
  }
  for (int i = 1; i <= 4 * m; ++i)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= 2 * m; ++i)
    if (bel[2 * i] == bel[2 * i + 1]) return false;
  return true;
}
int main() {
  n = gi(), m = gi();
  for (int i = 1; i <= m; ++i) {
    int u = gi(), v = gi(), c = gi(), w = gi();
    adde(u, v, c, w, i), R = max(R, w);
  }
  for (int i = 1; i <= n; ++i) sort(e[i].begin(), e[i].end());
  while (L <= R) {
    int mid = L + R >> 1;
    check(mid) ? R = mid - 1 : L = mid + 1;
  }
  if (!check(R + 1)) {
    puts("No");
    return 0;
  }
  for (int i = 1; i <= m; ++i)
    if (bel[2 * i] < bel[2 * i + 1]) ans.push_back(i);
  printf("Yes\n%d %d\n", R + 1, ans.size());
  for (auto x : ans) printf("%d ", x);
}
