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 = 5e4;
struct EDGE {
  int to;
  EDGE *nxt;
  EDGE() {}
  EDGE(int _t, EDGE *_n) : to(_t), nxt(_n) {}
};
struct GRAPH {
  EDGE edg[20 * N], *head[N * 6 + 3], *ncnt;
  void Clear(int siz) {
    for (int i = 0; i <= siz; i++) head[i] = NULL;
    ncnt = edg;
  }
  GRAPH() { ncnt = edg; }
  void AddEdge(int u, int v) {
    ncnt++;
    *ncnt = EDGE(v, head[u]);
    head[u] = ncnt;
  }
  EDGE *operator[](int id) { return head[id]; }
};
GRAPH Gr;
struct STACK {
  int stk[N * 6 + 3], head;
  int Size() { return head; }
  int Top() { return stk[head]; }
  void Pop() { head--; }
  void Push(int val) { stk[++head] = val; }
};
STACK St;
int n, m, ndfn, nscc;
int edg[N + 2][2];
vector<int> lnk[N + 3];
int dfn[6 * N + 3], low[6 * N + 3], scc[6 * N + 3];
bool inst[6 * N + 3];
bool cmpEDGE(int A, int B) { return edg[A][0] < edg[B][0]; }
void Tarjan(int u) {
  dfn[u] = low[u] = ++ndfn;
  St.Push(u);
  inst[u] = true;
  for (EDGE *it = Gr[u]; it; it = it->nxt) {
    int v = it->to;
    if (!dfn[v])
      Tarjan(v), low[u] = min(low[u], low[v]);
    else if (inst[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    int cur;
    nscc++;
    do {
      cur = St.Top();
      St.Pop();
      scc[cur] = nscc;
      inst[cur] = false;
    } while (cur != u);
  }
}
bool Solve(int lim) {
  Gr.Clear(6 * m);
  int ecnt = m - 1;
  ndfn = nscc = 0;
  for (int i = 0; i < 6 * m; i++) dfn[i] = low[i] = scc[i] = inst[i] = 0;
  for (int i = 1; i <= n; i++) {
    int lef = ecnt + 1;
    ecnt += (int)lnk[i].size();
    for (int j = 0; j < (int)lnk[i].size(); j++) {
      if (j < (int)lnk[i].size() - 1) {
        Gr.AddEdge((lef + j) << 1 | 1, (lef + j + 1) << 1 | 1);
        Gr.AddEdge((lef + j) << 1 | 1, lnk[i][j + 1] << 1);
      }
      if (j > 0) {
        Gr.AddEdge((lef + j) << 1, (lef + j - 1) << 1);
        Gr.AddEdge(lnk[i][j] << 1 | 1, (lef + j - 1) << 1);
      }
      Gr.AddEdge(lnk[i][j] << 1 | 1, (lef + j) << 1 | 1);
      Gr.AddEdge((lef + j) << 1, lnk[i][j] << 1);
    }
    int cnt1 = 0, cnt2 = 0, lasc = -1;
    for (int j = 0; j < (int)lnk[i].size(); j++) {
      if (lasc == edg[lnk[i][j]][0]) {
        Gr.AddEdge(lnk[i][j] << 1, lnk[i][j - 1] << 1 | 1);
        Gr.AddEdge(lnk[i][j - 1] << 1, lnk[i][j] << 1 | 1);
        cnt1++;
      } else
        lasc = edg[lnk[i][j]][0], cnt1 = 1;
      if (cnt1 == 2) cnt2++;
      if (cnt1 > 2) {
        printf("No\n");
        exit(0);
      }
      if (cnt2 > 1) {
        printf("No\n");
        exit(0);
      }
    }
  }
  for (int i = 0; i < m; i++)
    if (edg[i][1] > lim) Gr.AddEdge(i << 1 | 1, i << 1);
  for (int i = 0; i < ecnt * 2; i++)
    if (!dfn[i]) Tarjan(i);
  for (int i = 0; i < ecnt; i++)
    if (scc[i << 1] == scc[i << 1 | 1]) return false;
  return true;
}
int main() {
  scanf("%d%d", &n, &m);
  int lef = 0, rig = 0;
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d%d%d", &u, &v, &edg[i][0], &edg[i][1]);
    rig = max(rig, edg[i][1]);
    lnk[u].push_back(i);
    lnk[v].push_back(i);
  }
  for (int i = 1; i <= n; i++) sort(lnk[i].begin(), lnk[i].end(), cmpEDGE);
  while (lef + 1 < rig) {
    int mid = (lef + rig) >> 1;
    if (Solve(mid))
      rig = mid;
    else
      lef = mid;
  }
  if (Solve(lef)) {
    printf("Yes\n");
    int cnt3 = 0;
    for (int i = 0; i < m; i++)
      if (scc[i << 1] > scc[i << 1 | 1]) cnt3++;
    printf("%d %d\n", lef, cnt3);
    for (int i = 0; i < m; i++)
      if (scc[i << 1] > scc[i << 1 | 1]) {
        printf("%d", i + 1);
        cnt3--;
        if (cnt3)
          printf(" ");
        else
          printf("\n");
      }
  } else {
    if (!Solve(rig)) {
      printf("No\n");
      return 0;
    }
    printf("Yes\n");
    int cnt3 = 0;
    for (int i = 0; i < m; i++)
      if (scc[i << 1] > scc[i << 1 | 1]) cnt3++;
    printf("%d %d\n", rig, cnt3);
    for (int i = 0; i < m; i++)
      if (scc[i << 1] > scc[i << 1 | 1]) {
        printf("%d", i + 1);
        cnt3--;
        if (cnt3)
          printf(" ");
        else
          printf("\n");
      }
  }
  return 0;
}
