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 N = 1000010;
int n, m, cnt, tot, G[N];
struct iedge {
  int s, t, w, c, g;
} ie[N];
int tmp[N], icnt;
vector<iedge> e[N];
struct edge {
  int t, nx;
} E[N << 1];
inline void addedge(int x, int y, int c, int t, int g) {
  e[x].push_back({x, y, t, c, g});
  e[y].push_back({x, y, t, c, g});
}
vector<int> cc[N];
int tt[N], iit;
inline void addedge(int x, int y) {
  E[++cnt].t = y;
  E[cnt].nx = G[x];
  G[x] = cnt;
}
int vis[N], g[N], dfn[N], low[N], s[N], tp, iiit, ig;
void tarjan(int x) {
  dfn[x] = low[x] = ++iiit;
  vis[x] = 1;
  s[++tp] = x;
  for (int i = G[x]; i; i = E[i].nx) {
    if (!vis[E[i].t]) tarjan(E[i].t);
    if (vis[E[i].t] != 2) low[x] = min(low[x], low[E[i].t]);
  }
  if (dfn[x] == low[x]) {
    int k;
    ++ig;
    do {
      k = s[tp--];
      vis[k] = 2;
      g[k] = ig;
    } while (tp && k != x);
  }
}
int lst[N];
inline bool check(int x) {
  memset(G, 0, sizeof(G));
  cnt = 0;
  memset(vis, 0, sizeof(vis));
  for (int i = 1; i <= m; i++)
    if (ie[i].w > x) addedge(i << 1 | 1, i << 1);
  tot = (m << 1 | 1) + 1;
  for (int i = 1; i <= n; i++) {
    ++iit;
    vector<int> a, b;
    for (auto u : e[i]) {
      if (tt[u.c] != iit) tt[u.c] = iit, cc[u.c].clear(), a.push_back(u.c);
      cc[u.c].push_back(u.g);
      b.push_back(u.g);
    }
    if (!b.size()) continue;
    addedge(b[0] << 1 | 1, tot);
    addedge(tot + 1, b[0] << 1);
    for (int j = 1; j < (int)b.size(); j++) {
      addedge(tot + ((j - 1) << 1), tot + (j << 1));
      addedge(tot + (j << 1 | 1), tot + ((j - 1) << 1 | 1));
      addedge(b[j] << 1 | 1, tot + (j << 1));
      addedge(tot + (j << 1 | 1), b[j] << 1);
      addedge(b[j] << 1 | 1, tot + ((j - 1) << 1 | 1));
      addedge(tot + ((j - 1) << 1), b[j] << 1);
    }
    tot += (b.size() << 1 | 1) + 1;
    for (int u : a) {
      if (cc[u].size() < 2) continue;
      addedge(cc[u][0] << 1, tot);
      addedge(tot + 1, cc[u][0] << 1 | 1);
      for (int j = 1; j < (int)cc[u].size(); j++) {
        addedge(tot + ((j - 1) << 1), tot + (j << 1));
        addedge(tot + (j << 1 | 1), tot + ((j - 1) << 1 | 1));
        addedge(cc[u][j] << 1, tot + (j << 1));
        addedge(tot + (j << 1 | 1), cc[u][j] << 1 | 1);
        addedge(cc[u][j] << 1, tot + ((j - 1) << 1 | 1));
        addedge(tot + ((j - 1) << 1), cc[u][j] << 1 | 1);
      }
      tot += (cc[u].size() << 1 | 1) + 1;
    }
  }
  tp = iiit = ig = 0;
  for (int i = 2; i <= tot; i++)
    if (!vis[i]) tarjan(i);
  for (int i = 1; i <= m; i++)
    if (g[i << 1] == g[i << 1 | 1]) return false;
  memcpy(lst, g, sizeof(g));
  return true;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1, x, y, c, t; i <= m; i++)
    scanf("%d%d%d%d", &x, &y, &c, &t), ie[i] = {x, y, t, c, i}, tmp[++icnt] = c;
  sort(tmp + 1, tmp + 1 + icnt);
  icnt = unique(tmp + 1, tmp + 1 + icnt) - tmp - 1;
  for (int i = 1; i <= m; i++)
    ie[i].c = lower_bound(tmp + 1, tmp + 1 + icnt, ie[i].c) - tmp;
  for (int i = 1; i <= m; i++) addedge(ie[i].s, ie[i].t, ie[i].c, ie[i].t, i);
  int l = 0, r = 1e9, mid, ans = -1;
  while (l <= r) check(mid = (l + r) >> 1) ? r = (ans = mid) - 1 : l = mid + 1;
  vector<int> pt;
  if (!~ans) return puts("No"), 0;
  puts("Yes");
  for (int i = 1; i <= m; i++)
    if (lst[i << 1 | 1] < lst[i << 1]) pt.push_back(i);
  printf("%d %d\n", ans, pt.size());
  for (int u : pt) printf("%d ", u);
  return 0;
}
