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<pair<int, int>, pair<int, int> > > g[100020];
vector<pair<int, pair<int, int> > > graph[100020];
int problem[100020];
int prob[100020][2];
int color[100020];
int can;
int tmp;
int ix[100020];
int cs[100020];
int ans;
vector<int> res;
bool used[100020];
bool fix[100020];
int XX[100020], YY[100020];
int CC[100020], TT[100020];
int n, m, u, v, c, t, U;
int z[100020];
bool fixe[100020];
void is_problem(int p, int u) {
  int now = 0;
  used[u] = 1;
  for (int i = 1; i < g[u].size(); i++) {
    if (g[u][i].first.first == g[u][i - 1].first.first) {
      now++;
      problem[u] = 1;
      color[u] = g[u][i].first.first;
      prob[u][1] = g[u][i].second.first;
      prob[u][2] = g[u][i - 1].second.first;
    }
  }
  if (now >= 2) can = false;
  for (int i = 0; i < g[u].size(); i++)
    if (g[u][i].second.first != p && !used[g[u][i].second.first])
      is_problem(u, g[u][i].second.first);
}
void solve(int p, int u) {
  bool b = 0;
  used[u] = 1;
  for (int i = 0; i < graph[u].size(); i++) {
    int to = graph[u][i].first;
    if (fixe[graph[u][i].second.second]) continue;
    tmp++;
    ix[tmp] = graph[u][i].second.second;
    cs[tmp] = graph[u][i].second.first;
    fixe[ix[tmp]] = 1;
    solve(u, to);
    tmp--;
    b = true;
  }
  if (!b) {
    int x = 0;
    int y = 0;
    for (int i = 1; i <= tmp; i++) {
      if (i % 2)
        x = max(x, cs[i]);
      else
        y = max(y, cs[i]);
    }
    int st = 0;
    if (x <= y)
      st = 1;
    else
      st = 2;
    ans = max(ans, min(x, y));
    for (int i = st; i <= tmp; i += 2) {
      res.push_back(ix[i]);
    }
  }
}
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d%d", &v, &u, &c, &t);
    XX[i] = v;
    YY[i] = u;
    CC[i] = c;
    TT[i] = t;
    g[u].push_back(make_pair(make_pair(c, i), make_pair(u, t)));
    g[v].push_back(make_pair(make_pair(c, i), make_pair(v, t)));
  }
  for (int i = 1; i <= n; i++) sort(g[i].begin(), g[i].end());
  can = true;
  for (int i = 1; i <= n; i++)
    if (!used[i]) is_problem(0, i);
  if (!can) {
    cout << "No" << endl;
    return 0;
  }
  for (int i = 1; i <= n; i++) used[i] = 0;
  for (int i = 1; i <= n; i++)
    if (problem[i]) {
      for (int j = 0; j < g[i].size(); j++) {
        int col = g[i][j].first.first;
        if (col == color[i]) continue;
        int to = g[i][j].second.first;
        if (problem[to] && color[to] == col) {
          fix[g[i][j].first.second] = 1;
          z[to]++;
        }
      }
    }
  for (int i = 1; i <= n; i++)
    if (z[i] >= 2) {
      cout << "No" << endl;
      return 0;
    }
  for (int i = 1; i <= m; i++) {
    if (fix[i]) continue;
    u = XX[i];
    v = YY[i];
    c = CC[i];
    t = TT[i];
    if (problem[u] && color[u] == c) {
      graph[u].push_back(make_pair(v, make_pair(t, i)));
      graph[v].push_back(make_pair(u, make_pair(t, i)));
    }
  }
  for (int i = 1; i <= n; i++) used[i] = 0;
  for (int i = 1; i <= n; i++) {
    if (!used[i]) solve(-1, i);
  }
  cout << "Yes" << endl;
  cout << ans << " " << res.size() << endl;
  for (int i = 0; i < res.size(); i++) printf("%d ", res[i]);
}
