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 inf = 1e9;
const double eps = 1e-9;
const double pi = 4 * atan(1.0);
const int N = int(1e6) + 100;
struct edge {
  int u, v, c, t, num;
};
bool operator<(const edge& a, const edge& b) { return a.c < b.c; }
int sz, ptr;
set<int> vers;
bool used[N];
edge e[N];
int cur_num[N], w[N], col[N], ord[N];
int ee[N][2];
int vv[N][2];
vector<int> g[N], rg[N];
inline void fail() {
  puts("No");
  exit(0);
}
inline void add_edge(int v, int u, int e) {
  if (ee[v][0] == -1) {
    ee[v][0] = e;
    vv[v][0] = u;
  } else if (ee[v][1] == -1) {
    ee[v][1] = e;
    vv[v][1] = u;
  } else {
    fail();
  }
}
inline void add(int v, int u) {
  g[v].push_back(u);
  rg[u].push_back(v);
}
void dfs1(int v) {
  used[v] = true;
  for (int i = 0; i < ((int)(g[v]).size()); ++i) {
    if (!used[g[v][i]]) {
      dfs1(g[v][i]);
    }
  }
  ord[ptr++] = v;
}
void dfs2(int v) {
  col[v] = ptr;
  for (int i = 0; i < ((int)(rg[v]).size()); ++i) {
    if (col[rg[v][i]] == -1) {
      dfs2(rg[v][i]);
    }
  }
}
inline bool check(int w) {
  for (int i = 0; i < 2 * sz; ++i) {
    g[i].clear();
    rg[i].clear();
    used[i] = false;
    col[i] = -1;
  }
  for (int i = 0; i < sz; ++i) {
    if (ee[i][1] != -1) {
      if (e[ee[i][0]].t > w) {
        add(i, i + sz);
      }
      if (e[ee[i][1]].t > w) {
        add(i + sz, i);
      }
      for (int j = 0; j < 2; ++j) {
        int ii = vv[i][j];
        if (ee[ii][1] != -1) {
          int jj = 0;
          if (ee[ii][jj] != ee[i][j]) {
            jj = 1;
          }
          assert(ee[ii][jj] == ee[i][j]);
          add(i + j * sz, ii + jj * sz);
          add(i + (1 - j) * sz, ii + (1 - jj) * sz);
        }
      }
    }
  }
  ptr = 0;
  for (int i = 0; i < 2 * sz; ++i) {
    if (!used[i]) {
      dfs1(i);
    }
  }
  ptr = 0;
  for (int i = 2 * sz - 1; i >= 0; --i) {
    if (col[ord[i]] == -1) {
      dfs2(ord[i]);
      ++ptr;
    }
  }
  for (int i = 0; i < sz; ++i) {
    if (col[i] == col[i + sz]) {
      return false;
    }
  }
  return true;
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    scanf("%d %d %d %d", &e[i].v, &e[i].u, &e[i].c, &e[i].t);
    e[i].num = i;
    w[i] = e[i].t;
  }
  w[m] = 0;
  sort(w, w + m + 1);
  int k = unique(w, w + m + 1) - w;
  sz = 0;
  sort(e, e + m);
  int i = 0;
  while (i < m) {
    int j = i;
    while (j + 1 < m && e[i].c == e[j + 1].c) {
      ++j;
    }
    vers.clear();
    for (int z = i; z <= j; ++z) {
      vers.insert(e[z].v);
      vers.insert(e[z].u);
    }
    for (int v : vers) {
      ee[sz][0] = ee[sz][1] = -1;
      cur_num[v] = sz++;
    }
    for (int z = i; z <= j; ++z) {
      add_edge(cur_num[e[z].v], cur_num[e[z].u], z);
      add_edge(cur_num[e[z].u], cur_num[e[z].v], z);
    }
    i = j + 1;
  }
  int res = -1, l = 0, r = k - 1;
  while (l <= r) {
    int mid = (l + r) / 2;
    if (check(w[mid])) {
      res = mid;
      r = mid - 1;
    } else {
      l = mid + 1;
    }
  }
  if (res == -1) {
    fail();
  }
  check(w[res]);
  vers.clear();
  for (int i = 1; i <= n; ++i) {
    used[i] = false;
  }
  for (int i = 0; i < sz; ++i) {
    if (ee[i][1] != -1) {
      int del = -1;
      if (col[i] < col[i + sz]) {
        del = ee[i][1];
      } else {
        del = ee[i][0];
      }
      vers.insert(e[del].num);
    }
  }
  printf("Yes\n%d %d\n", w[res], ((int)(vers).size()));
  for (int e : vers) {
    printf("%d ", e + 1);
  }
  puts("");
  return 0;
}
