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<pair<int, int>> edge[50005];
vector<int> to[500005];
int n, m, tim, dfn[500005], low[500005], st[500005], col[500005], cnt;
bool ins[500005];
struct node {
  int x, y, c, t, id;
} e[50005];
void dfs(int x) {
  dfn[x] = low[x] = ++tim;
  ins[x] = 1;
  st[++st[0]] = x;
  for (auto tar : to[x]) {
    if (!dfn[tar])
      dfs(tar), low[x] = min(low[x], low[tar]);
    else if (ins[tar])
      low[x] = min(low[x], dfn[tar]);
  }
  if (dfn[x] == low[x]) {
    cnt++;
    while (st[st[0]] != x) ins[st[st[0]]] = 0, col[st[st[0]]] = cnt, st[0]--;
    col[x] = cnt;
    ins[x] = 0;
    st[0]--;
  }
}
bool check(int mid) {
  for (int i = 1; i <= n; i++) edge[i].clear();
  for (int i = 1; i <= 500000; i++) to[i].clear();
  for (int i = 1; i <= m; i++) {
    edge[e[i].x].push_back({e[i].c, i}), edge[e[i].y].push_back({e[i].c, i});
    if (e[i].t > mid) to[i].push_back(i + m);
  }
  int now = 2 * m + 1;
  for (int i = 1; i <= n; i++) {
    vector<int> v;
    for (int j = 0; j <= edge[i].size(); j++) {
      if (j &&
          (j == edge[i].size() || edge[i][j].first != edge[i][j - 1].first)) {
        if (v.size() > 1) {
          for (int k = 0; k < v.size() - 1; k++)
            to[now + k].push_back(now + k + 1);
          for (int k = 0; k < v.size(); k++)
            to[now + k].push_back(v[k]), to[now + k + v.size()].push_back(v[k]);
          for (int k = v.size() - 1; k > 0; k--)
            to[now + k + v.size()].push_back(now + k + v.size() - 1);
          for (int k = 0; k < v.size(); k++) {
            if (k) to[v[k] + m].push_back(now + v.size() + k - 1);
            if (k < v.size() - 1) to[v[k] + m].push_back(now + k + 1);
          }
          now += 2 * v.size();
        }
        v.clear();
      }
      if (j < edge[i].size()) v.push_back(edge[i][j].second);
    }
    for (int j = 0; j < edge[i].size(); j++) v.push_back(edge[i][j].second);
    if (v.size() > 1) {
      for (int k = 0; k < v.size() - 1; k++) to[now + k].push_back(now + k + 1);
      for (int k = 0; k < v.size(); k++)
        to[now + k].push_back(v[k] + m),
            to[now + k + v.size()].push_back(v[k] + m);
      for (int k = v.size() - 1; k > 0; k--)
        to[now + k + v.size()].push_back(now + k + v.size() - 1);
      for (int k = 0; k < v.size(); k++) {
        if (k) to[v[k]].push_back(now + v.size() + k - 1);
        if (k < v.size() - 1) to[v[k]].push_back(now + k + 1);
      }
      now += 2 * v.size();
    }
  }
  memset(dfn, 0, sizeof(dfn));
  cnt = tim = 0;
  for (int i = 1; i < now; i++)
    if (!dfn[i]) dfs(i);
  for (int i = 1; i <= m; i++)
    if (col[i] == col[i + m]) return 0;
  return 1;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++)
    e[i].id = i, scanf("%d%d%d%d", &e[i].x, &e[i].y, &e[i].c, &e[i].t);
  sort(e + 1, e + m + 1, [&](node a, node b) { return a.c < b.c; });
  int l = 0, r = 1e9;
  if (!check(r)) {
    puts("No");
    return 0;
  }
  while (l < r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      r = mid;
    else
      l = mid + 1;
  }
  puts("Yes");
  printf("%d ", l);
  check(l);
  vector<int> v;
  for (int i = 1; i <= m; i++)
    if (col[i] < col[i + m]) v.push_back(e[i].id);
  printf("%llu\n", v.size());
  for (auto i : v) printf("%d ", i);
  return 0;
}
