#include <bits/stdc++.h>
using namespace std;
struct T {
  int u, v, c, t, idx;
} t[50010];
int n, m;
int myless(const T &a, const T &b) { return a.c < b.c; }
vector<int> g;
int freq[50010];
int ec[50010];
vector<int> ans;
vector<int> e[50010];
vector<int> E[400010], rE[400010];
int ord[400010], c;
int done[400010];
int gr[400010];
int N;
void add_edge(int v, int w) {
  E[v].push_back(w);
  rE[w].push_back(v);
}
int dfs(int v) {
  done[v] = 1;
  for (int i = 0; i < E[v].size(); i++) {
    if (!done[E[v][i]]) {
      dfs(E[v][i]);
    }
  }
  ord[c++] = v;
}
int rdfs(int v, int k) {
  done[v] = 1;
  gr[v] = k;
  for (int i = 0; i < rE[v].size(); i++) {
    if (!done[rE[v][i]]) {
      rdfs(rE[v][i], k);
    }
  }
}
int f(int hi, int sw) {
  for (int i = 0; i < m; i++) {
    if (t[i].t > hi) {
      add_edge(i + m, i);
    }
  }
  for (int i = 0; i < N; i++) {
    done[i] = 0;
  }
  c = 0;
  for (int i = 0; i < N; i++) {
    if (!done[i]) {
      dfs(i);
    }
  }
  for (int i = 0; i < N; i++) {
    done[i] = 0;
  }
  int k = 0;
  for (int i = N - 1; i >= 0; i--) {
    int v = ord[i];
    if (!done[v]) {
      rdfs(v, k++);
    }
  }
  for (int i = 0; i < m; i++) {
    if (t[i].t > hi) {
      E[i + m].pop_back();
      rE[i].pop_back();
    }
  }
  for (int i = 0; i < m; i++) {
    if (gr[i] == gr[i + m]) {
      return 0;
    }
  }
  for (int i = 2 * m; i < N - 2 * m; i++) {
    if (gr[i] == gr[i + 2 * m]) {
      return 0;
    }
  }
  if (sw) {
    for (int i = 0; i < m; i++) {
      if (gr[i] < gr[i + m]) {
        ans.push_back(t[i].idx);
      }
    }
  }
  return 1;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int u, v, co, ti;
    scanf("%d%d%d%d", &u, &v, &co, &ti);
    --u;
    --v;
    t[i] = (T){u, v, co, ti, i};
  }
  sort(t, t + m, myless);
  g.push_back(0);
  for (int i = 1; i < m; i++) {
    if (t[i].c != t[i - 1].c) {
      g.push_back(i);
    }
  }
  g.push_back(m);
  int can = 1;
  int bad = 0;
  for (int i = 0; i < g.size() - 1; i++) {
    for (int j = g[i]; j < g[i + 1]; j++) {
      ++freq[t[j].u];
      ++freq[t[j].v];
      if (freq[t[j].u] > 1 || freq[t[j].v] > 1) {
        can = 0;
      }
      if (freq[t[j].u] > 2 || freq[t[j].v] > 2) {
        bad = 1;
      }
    }
    for (int j = g[i]; j < g[i + 1]; j++) {
      if (freq[t[j].u]-- == 2) {
        ec[t[j].u]++;
      }
      if (freq[t[j].v]-- == 2) {
        ec[t[j].v]++;
      }
    }
  }
  if (can) {
    puts("Yes");
    puts("0 0\n");
    return 0;
  }
  for (int i = 0; i < n; i++) {
    if (ec[i] >= 2) {
      bad = 1;
    }
  }
  if (bad) {
    puts("No");
    return 0;
  }
  for (int i = 0; i < m; i++) {
    e[t[i].u].push_back(i);
    e[t[i].v].push_back(i);
  }
  N = 2 * m;
  for (int i = 0; i < n; i++) {
    int cn = 0;
    for (int j = 0; j < e[i].size(); j++) {
      add_edge(e[i][j] + m, N + 2 * m);
      add_edge(N, e[i][j]);
      if (j > 0) {
        add_edge(N - 1 + 2 * m, N + 2 * m);
        add_edge(N, N - 1);
        add_edge(e[i][j] + m, N - 1);
        add_edge(N - 1 + 2 * m, e[i][j]);
      }
      if (cn > 0 && e[i][j] < g[cn]) {
        add_edge(e[i][j], e[i][j - 1] + m);
        add_edge(e[i][j - 1], e[i][j] + m);
      }
      while (e[i][j] >= g[cn]) {
        ++cn;
      }
      N++;
    }
  }
  N += 2 * m;
  if (!f(1001001001, 0)) {
    puts("No");
    return 0;
  }
  int lo = 0, hi = 1001001001;
  while (lo + 1 < hi) {
    int mid = (lo + hi) / 2;
    if (f(mid, 0)) {
      hi = mid;
    } else {
      lo = mid;
    }
  }
  f(hi, 1);
  puts("Yes");
  printf("%d %d\n", hi, ans.size());
  for (int i = 0; i < ans.size(); i++) {
    printf("%d ", ans[i] + 1);
  }
  return 0;
}
