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 std::cerr;
using std::endl;
const int N = 1e6 + 10;
int n, m;
struct Edge {
  int x, y, c, t;
} E[N];
std::vector<int> G[N];
std::vector<int> T[N];
int tot;
inline void addedge(std::vector<int> vec, int op) {
  int S = 0, _S = 0;
  for (int i : vec) {
    int x = i, _x = x + m, s = ++tot, _s = ++tot;
    if (op == 0) {
      T[x].push_back(s), T[_s].push_back(_x);
      if (S) {
        T[S].push_back(s), T[_s].push_back(_S);
        T[S].push_back(_x), T[x].push_back(_S);
      }
    } else {
      T[s].push_back(x), T[_x].push_back(_s);
      if (S) {
        T[s].push_back(S), T[_S].push_back(_s);
        T[_x].push_back(S), T[_S].push_back(x);
      }
    }
    S = s, _S = _s;
  }
}
int dfn[N], low[N], num, stk[N], top, ins[N], bel[N], cnt;
void tarjan(int x) {
  dfn[x] = low[x] = ++num;
  ins[x] = 1;
  stk[++top] = x;
  for (int y : T[x]) {
    if (!dfn[y]) {
      tarjan(y);
      low[x] = std::min(low[x], low[y]);
    } else if (ins[y])
      low[x] = std::min(low[x], dfn[y]);
  }
  if (low[x] == dfn[x]) {
    ++cnt;
    for (int z = 0; z != x; --top) {
      z = stk[top];
      ins[z] = 0;
      bel[z] = cnt;
    }
  }
}
inline int check(int mid) {
  for (int i = 1; i <= m; ++i)
    if (E[i].t > mid) {
      T[i].push_back(i + m);
    }
  memset(dfn, 0, sizeof(int) * (tot + 1));
  memset(low, 0, sizeof(int) * (tot + 1));
  memset(bel, 0, sizeof(int) * (tot + 1));
  num = top = cnt = 0;
  for (int i = 1; i <= tot; ++i) {
    if (!dfn[i]) {
      tarjan(i);
    }
  }
  int ok = 1;
  for (int i = 1; i <= m; ++i) {
    if (bel[i] == bel[i + m]) {
      ok = 0;
      break;
    }
  }
  for (int i = 1; i <= m; ++i)
    if (!T[i].empty() && T[i].back() == i + m) T[i].pop_back();
  return ok;
}
int main() {
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  std::cin >> n >> m;
  tot = m * 2;
  for (int i = 1; i <= m; ++i) {
    std::cin >> E[i].x >> E[i].y >> E[i].c >> E[i].t;
    G[E[i].x].push_back(i);
    G[E[i].y].push_back(i);
  }
  for (int i = 1; i <= n; ++i) {
    std::sort(G[i].begin(), G[i].end(),
              [&](int a, int b) { return E[a].c < E[b].c; });
    addedge(G[i], 0);
    std::vector<int> tmp;
    for (int l = 0, r = 0; l < G[i].size(); l = ++r) {
      tmp.push_back(G[i][l]);
      while (r + 1 < G[i].size() && E[G[i][r + 1]].c == E[G[i][l]].c)
        tmp.push_back(G[i][++r]);
      addedge(tmp, 1);
      tmp.clear();
    }
  }
  int l = 0, r = 0, res = -1;
  for (int i = 1; i <= m; ++i) r = std::max(r, E[i].t);
  if (!check(r)) {
    std::cout << "No\n";
    return 0;
  }
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      res = mid, r = mid - 1;
    else
      l = mid + 1;
  }
  assert(res != -1);
  check(res);
  std::cout << "Yes\n";
  std::vector<int> ans;
  for (int i = 1; i <= m; ++i)
    if (bel[i] < bel[i + m]) ans.push_back(i);
  std::cout << res << " " << ans.size() << '\n';
  for (auto e : ans) std::cout << e << ' ';
  std::cout << '\n';
  return 0;
}
