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 maxn = 50010;
int n, m, E, qt, G;
int flag[maxn], rev[maxn * 6], link[maxn], gval[maxn * 6], tgval[maxn * 6],
    q[maxn * 6], vis[maxn * 6], C[maxn], revg[maxn * 6];
vector<int> adj[maxn], con[maxn], rcon[maxn], gc[maxn], rgc[maxn];
struct Edge {
  int a, b, t, c, id;
  void input() {
    scanf("%d%d%d%d", &a, &b, &c, &t);
    --a;
    --b;
    adj[a].push_back(id);
    adj[b].push_back(id);
  }
} e[maxn];
void setrev(int u, int v) { rev[u] = v, rev[v] = u; }
void add(int u, int v) {
  con[u].push_back(v);
  con[rev[v]].push_back(rev[u]);
  rcon[v].push_back(u);
  rcon[rev[u]].push_back(rev[v]);
}
bool check() {
  memset(rev, -1, sizeof rev);
  E = m;
  int T = 1, i, j;
  for (i = 0; i < n; i++, T += 3) {
    int cnt = 0, thecol = -1, theid[2], ti = 0;
    int sz = adj[i].size();
    for (j = 0; j < sz; j++) {
      int id = adj[i][j];
      if (flag[e[id].c] < T)
        flag[e[id].c] = T;
      else
        flag[e[id].c]++;
      if (flag[e[id].c] >= T + 2) break;
      if (flag[e[id].c] == T + 1) cnt++, thecol = e[id].c;
      if (cnt >= 2) break;
    }
    if (j < sz) break;
    for (j = 0; j < sz; j++)
      if (e[adj[i][j]].c == thecol) theid[ti++] = adj[i][j];
    if (ti == 2) setrev(theid[0], theid[1]);
    for (j = 0; j < sz; j++)
      if (rev[adj[i][j]] == -1) setrev(adj[i][j], E), E++;
    for (j = 0; j < sz; j++, E += 2) link[adj[i][j]] = E, setrev(E, E + 1);
    for (j = 0; j < sz; j++) {
      int id = adj[i][j];
      add(id, link[id]);
      if (j < adj[i].size() - 1) add(link[id], link[id] + 2);
      if (j) add(id, rev[link[id] - 2]);
    }
  }
  return i == n;
}
inline void chkmin(int& a, int b) {
  if (a > b) a = b;
}
inline void chkmax(int& a, int b) {
  if (a < b) a = b;
}
void dfs(int u) {
  vis[u] = 1;
  for (auto i : con[u])
    if (!vis[i]) dfs(i);
  q[qt++] = u;
}
void rdfs(int u) {
  vis[u] = G;
  for (auto i : rcon[u])
    if (!vis[i]) rdfs(i);
}
bool strongly() {
  for (int i = 0; i < E; i++)
    if (!vis[i]) dfs(i);
  memset(vis, 0, sizeof vis);
  assert(qt == E);
  G = 1;
  for (int i = qt - 1; i >= 0; i--)
    if (!vis[q[i]]) rdfs(q[i]), G++;
  for (int i = 0; i < E; i++)
    if (vis[i] == vis[rev[i]]) return false;
  return true;
}
bool flow0(int u) {
  if (gval[u] == 1) return false;
  if (gval[u] == 0) return true;
  gval[u] = 0;
  for (int i = 0; i < rgc[u].size(); i++) {
    int v = rgc[u][i];
    if (!flow0(v)) return false;
  }
  return true;
}
bool flow1(int u) {
  if (gval[u] == 0) return false;
  if (gval[u] == 1) return true;
  gval[u] = 1;
  for (int i = 0; i < gc[u].size(); i++) {
    int v = gc[u][i];
    if (!flow1(v)) return false;
  }
  return true;
}
bool can(int mid) {
  for (int i = 1; i < G; i++) gval[i] = -1;
  for (int i = 0; i < m; i++)
    if (e[i].t > mid) {
      if (!flow0(vis[i])) return false;
      if (!flow1(vis[rev[i]])) return false;
    }
  return true;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) e[i].id = i, e[i].input(), C[i] = e[i].c;
  sort(C, C + m);
  int nc = unique(C, C + m) - C;
  for (int i = 0; i < m; i++) e[i].c = lower_bound(C, C + nc, e[i].c) - C;
  if (check()) {
    if (!strongly()) return puts("No");
    for (int i = 0; i < E; i++)
      revg[vis[i]] = vis[rev[i]], revg[rev[i]] = vis[i];
    for (int i = 0; i < E; i++)
      for (auto j : con[i]) {
        assert(vis[i]);
        assert(vis[j]);
        gc[vis[i]].push_back(vis[j]);
        rgc[vis[j]].push_back(vis[i]);
      }
    int low = e[0].t, high = e[0].t, ans = -1;
    for (int i = 1; i < m; i++) chkmin(low, e[i].t), chkmax(high, e[i].t);
    while (low <= high) {
      int mid = (low + high) / 2;
      if (can(mid))
        ans = mid, high = mid - 1;
      else
        low = mid + 1;
    }
    can(ans);
    assert(ans != -1);
    for (int i = 0; i < m; i++)
      if (gval[vis[i]] == -1) {
        for (int j = 1; j < G; j++) tgval[j] = gval[j];
        if (!flow1(vis[i])) {
          puts("once");
          for (int j = 1; j < G; j++) gval[j] = tgval[j];
          flow0(vis[i]);
          flow1(vis[rev[i]]);
        } else {
          flow0(vis[rev[i]]);
          flow1(vis[i]);
        }
      }
    puts("Yes");
    int cnt = 0;
    for (int i = 0; i < m; i++) cnt += gval[vis[i]];
    printf("%d %d\n", ans, cnt);
    for (int i = 0; i < m; i++)
      if (gval[vis[i]]) printf("%d%c", i + 1, i < m - 1 ? ' ' : '\n');
  } else
    puts("No");
  return 0;
}
