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;
vector<int> to[1000010];
void build(int u, int v) {
  to[u].push_back(v);
  return;
}
int dfn[1000010], low[1000010], now;
int sta[1000010], head;
bool insta[1000010];
int c[1000010], color;
void dfs(int u) {
  dfn[u] = low[u] = ++now;
  sta[++head] = u;
  insta[u] = true;
  for (int i = 0; i < to[u].size(); i++) {
    int v = to[u][i];
    if (!dfn[v]) {
      dfs(v);
      low[u] = min(low[u], low[v]);
    } else if (insta[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] == low[u]) {
    color++;
    do {
      c[sta[head]] = color;
      insta[sta[head]] = false;
    } while (sta[head--] != u);
  }
  return;
}
int n, m;
struct Edge {
  int u, v, c, t;
} e[400010];
bool cmp(int a, int b) { return e[a].c < e[b].c; }
vector<int> vec[400010];
int N;
bool check(int mid, bool ifclear = true) {
  N = m * 2;
  for (int i = 1; i <= m; i++)
    if (e[i].t > mid) build(i, i + m);
  for (int i = 1; i <= n; i++) {
    int lsts1 = 0, lsts2 = 0;
    for (int j = 0; j < vec[i].size(); j++) {
      int x = vec[i][j];
      int s1 = ++N;
      int s2 = ++N;
      build(x, s1);
      build(s2, x + m);
      if (j > 0) {
        build(lsts1, s1);
        build(s2, lsts2);
        build(lsts1, x + m);
        build(x, lsts2);
      }
      lsts1 = s1;
      lsts2 = s2;
    }
    for (int j = 0, k; j < vec[i].size(); j = k) {
      k = j;
      lsts1 = 0, lsts2 = 0;
      int x = vec[i][k];
      int C = e[x].c;
      while (k < vec[i].size() && e[x].c == C) {
        int s1 = ++N;
        int s2 = ++N;
        build(x + m, s1);
        build(s2, x);
        if (k > j) {
          build(lsts1, s1);
          build(s2, lsts2);
          build(lsts1, x);
          build(x + m, lsts2);
        }
        lsts1 = s1;
        lsts2 = s2;
        k++;
        if (k < vec[i].size()) x = vec[i][k];
      }
    }
  }
  for (int i = 1; i <= N; i++)
    if (!dfn[i]) dfs(i);
  bool res = true;
  for (int i = 1; i <= m; i++)
    if (c[i] == c[i + m]) res = false;
  if (ifclear) {
    for (int i = 1; i <= N; i++) {
      to[i].clear();
      dfn[i] = low[i] = c[i] = 0;
    }
  }
  now = color = 0;
  return res;
}
bool choose[400010];
int main() {
  scanf("%d %d", &n, &m);
  int mx = 0;
  for (int i = 1; i <= m; i++) {
    scanf("%d %d %d %d", &e[i].u, &e[i].v, &e[i].c, &e[i].t);
    mx = max(mx, e[i].t);
    vec[e[i].u].push_back(i);
    vec[e[i].v].push_back(i);
  }
  for (int i = 1; i <= n; i++) sort(vec[i].begin(), vec[i].end(), cmp);
  int l = -1, r = mx + 1;
  while (l + 1 < r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      r = mid;
    else
      l = mid;
  }
  if (r == mx + 1)
    printf("No\n");
  else {
    printf("Yes\n");
    check(r, false);
    int cnt = 0;
    for (int i = 1; i <= m; i++)
      if (c[i] < c[i + m]) {
        cnt++;
        choose[i] = true;
      }
    printf("%d %d\n", r, cnt);
    for (int i = 1; i <= m; i++)
      if (choose[i]) printf("%d ", i);
    printf("\n");
  }
  return 0;
}
