#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 10;
int n, m;
struct _ {
  int to, c, t, id;
  bool operator<(const _ &rhs) const { return c < rhs.c; }
};
vector<_> g[N];
struct twosat {
  int tot, n, dfn[N * 10], low[N * 10], sccno[N * 10], clk, scnt;
  int s[N * 10], s_top;
  vector<int> g[N * 10];
  void dfs(int x) {
    dfn[s[++s_top] = x] = low[x] = ++clk;
    for (int y : g[x]) {
      if (!dfn[y])
        dfs(y), low[x] = min(low[x], low[y]);
      else if (!sccno[y])
        low[x] = min(low[x], dfn[y]);
    }
    if (low[x] == dfn[x])
      for (int u = ++scnt; sccno[u = s[s_top--]] = scnt, u != x;)
        ;
  }
  void init(int _n) {
    for (int i = 1; i <= tot; ++i) {
      g[i].clear();
      dfn[i] = sccno[i] = 0;
    }
    tot = 2 * _n, n = _n;
    n = _n, clk = scnt = 0;
  }
  bool solve() {
    for (int i = 1; i <= tot; ++i)
      if (!dfn[i]) dfs(i);
    for (int i = 1; i <= n; ++i)
      if (sccno[i] == sccno[i + n]) return false;
    return true;
  }
} sat;
bool chk(int lim) {
  sat.init(m);
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < g[i].size(); ++j) {
      int id = ++sat.tot;
      sat.g[id].push_back(g[i][j].id + m);
      if (j) {
        sat.g[id].push_back(id - 1);
        if (g[i][j].t <= lim) sat.g[g[i][j].id].push_back(id - 1);
      }
    }
    for (int j = (int)g[i].size() - 1; j >= 0; --j) {
      int id = ++sat.tot;
      sat.g[id].push_back(g[i][j].id + m);
      if (j + 1 != g[i].size()) {
        sat.g[id].push_back(id - 1);
        if (g[i][j].t <= lim) sat.g[g[i][j].id].push_back(id - 1);
      }
    }
    for (int j = 0; j < g[i].size(); ++j) {
      if (g[i][j].t > lim) sat.g[g[i][j].id].push_back(g[i][j].id + m);
    }
    for (int j = 0, k; j < g[i].size(); j = k) {
      k = j;
      while (k < g[i].size() && g[i][k].c == g[i][j].c) ++k;
      for (int u = j; u < k; ++u) {
        int id = ++sat.tot;
        sat.g[id].push_back(g[i][u].id);
        if (u != j) {
          sat.g[id].push_back(id - 1);
          sat.g[g[i][u].id + m].push_back(id - 1);
        }
      }
      for (int u = k - 1; u >= j; --u) {
        int id = ++sat.tot;
        sat.g[id].push_back(g[i][u].id);
        if (u + 1 != k) {
          sat.g[id].push_back(id - 1);
          sat.g[g[i][u].id + m].push_back(id - 1);
        }
      }
    }
  }
  return sat.solve();
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    int u, v, c, t;
    scanf("%d%d%d%d", &u, &v, &c, &t);
    g[u].push_back({v, c, t, i});
    g[v].push_back({u, c, t, i});
  }
  for (int i = 1; i <= n; ++i) sort(g[i].begin(), g[i].end());
  int l = 0, r = 1e9 + 10, ans = -1;
  while (l <= r) {
    int mid = (l + r) / 2;
    if (chk(mid))
      ans = mid, r = mid - 1;
    else
      l = mid + 1;
  }
  if (ans == -1)
    puts("No");
  else {
    puts("Yes");
    chk(ans);
    int cnt = 0;
    for (int i = 1; i <= m; ++i)
      if (sat.sccno[i] < sat.sccno[i + m]) ++cnt;
    printf("%d %d\n", ans, cnt);
    for (int i = 1; i <= m; ++i)
      if (sat.sccno[i] < sat.sccno[i + m]) printf("%d ", i);
    puts("");
  }
}
