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 long double pi = 3.1415926535897932384626433832795l;
template <typename T>
inline auto sqr(T x) -> decltype(x * x) {
  return x * x;
}
template <typename T1, typename T2>
inline bool umx(T1& a, T2 b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename T1, typename T2>
inline bool umn(T1& a, T2 b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
const int N = 50100, M = 50100;
struct Input {
  int n, m;
  vector<pair<int, int> > e;
  int c[M], t[M];
  vector<int> a[N];
  bool read() {
    if (scanf("%d%d", &n, &m) != 2) {
      return 0;
    }
    for (int i = int(0); i < int(m); ++i) {
      int u, v;
      scanf("%d%d", &u, &v);
      u--, v--;
      e.push_back(make_pair(u, v));
      scanf("%d%d", &c[i], &t[i]);
      a[u].push_back(i);
      a[v].push_back(i);
    }
    return 1;
  }
  void init(const Input& input) { *this = input; }
};
struct Data : Input {
  bool ok;
  vector<int> ans;
  void write() {
    if (!ok) {
      puts("No");
      return;
    }
    puts("Yes");
    int res = 0;
    for (int i = int(0); i < int(((int)(ans).size())); ++i) umx(res, t[ans[i]]);
    cout << res << ' ' << ((int)(ans).size()) << endl;
    for (int i = int(0); i < int(((int)(ans).size())); ++i) {
      printf("%d ", ans[i] + 1);
    }
    cout << endl;
  }
  virtual void solve() {}
  virtual void clear() { *this = Data(); }
};
struct Solution : Data {
  int sz;
  vector<int> g[6 * M];
  int p[M];
  int dead[M];
  vector<int> revg[6 * M];
  bool use[6 * M];
  int col[6 * M];
  vector<int> ord;
  void add(int u, int v) {
    g[u ^ 1].push_back(v);
    g[v ^ 1].push_back(u);
  }
  void build(int kol) {
    sz = 3 * m;
    for (int i = int(0); i < int(3 * M); ++i) {
      g[i] = vector<int>();
    }
    int tek = 0;
    for (int i = int(0); i < int(m); ++i) {
      if (dead[i] >= kol) g[2 * i + 1].push_back(2 * i);
    }
    for (int i = int(0); i < int(n); ++i) {
      for (int j = int(0); j < int(((int)(a[i]).size()) - 1); ++j) {
        if (c[a[i][j]] == c[a[i][j + 1]]) {
          add(2 * a[i][j] + 1, 2 * a[i][j + 1] + 1);
        }
      }
      for (int j = int(0); j < int(((int)(a[i]).size())); ++j) {
        add(2 * a[i][j], 2 * (m + tek) + 2 * j + 1);
        if (j > 0) {
          add(2 * (m + tek) + 2 * (j - 1), 2 * (m + tek) + 2 * j + 1);
        }
        if (j + 1 < ((int)(a[i]).size())) {
          add(2 * a[i][j + 1], 2 * (m + tek) + 2 * j);
        }
      }
      tek += ((int)(a[i]).size());
    }
  }
  void dfs(int v) {
    use[v] = 1;
    for (int i = int(0); i < int(((int)(g[v]).size())); ++i) {
      int to = g[v][i];
      if (!use[to]) dfs(to);
    }
    ord.push_back(v);
  }
  void color(int v, int c) {
    col[v] = c;
    for (int i = int(0); i < int(((int)(revg[v]).size())); ++i) {
      int to = revg[v][i];
      if (col[to] == -1) {
        color(to, c);
      }
    }
  }
  bool check(int kol) {
    build(kol);
    for (int i = int(0); i < int(2 * sz); ++i) revg[i] = vector<int>();
    for (int i = int(0); i < int(2 * sz); ++i) {
      for (int j = int(0); j < int(((int)(g[i]).size())); ++j) {
        revg[g[i][j]].push_back(i);
      }
    }
    memset(col, -1, sizeof(col));
    memset(use, 0, sizeof(use));
    for (int i = int(0); i < int(2 * sz); ++i) {
      if (!use[i]) dfs(i);
    }
    int cnt = 0;
    for (int i = int(((int)(ord).size())) - 1; i >= int(0); --i) {
      int u = ord[i];
      if (col[u] < 0) {
        color(u, cnt++);
      }
    }
    ans.clear();
    for (int i = int(0); i < int(sz); ++i) {
      if (col[2 * i] == col[2 * i + 1]) {
        return 0;
      } else if (i < sz / 3 && col[2 * i + 1] > col[2 * i]) {
        ans.push_back(i);
      }
    }
    return 1;
  }
  void solve() {
    for (int i = int(0); i < int(m); ++i) p[i] = i;
    sort(p, p + m, [&](int i, int j) { return t[i] < t[j]; });
    for (int i = 0; i < m;) {
      int j = i;
      for (; j < m && t[p[i]] == t[p[j]]; ++j)
        ;
      for (int k = i; k < j; ++k) {
        dead[p[k]] = j;
      }
      i = j;
    }
    for (int i = int(0); i < int(n); ++i) {
      sort((a[i]).begin(), (a[i]).end(),
           [&](int a, int b) { return c[a] < c[b]; });
      for (int j = 0; j < ((int)(a[i]).size());) {
        int k = j;
        for (; k < ((int)(a[i]).size()) && c[a[i][j]] == c[a[i][k]]; ++k)
          ;
        if (k - j > 2) {
          ok = 0;
          return;
        }
        j = k;
      }
    }
    int l = 0, r = m;
    while (l < r) {
      int m = (l + r) >> 1;
      if (check(m)) {
        r = m;
      } else {
        l = m + 1;
      }
    }
    ok = check(r);
  }
  void clear() { *this = Solution(); }
};
Solution sol;
int main() {
  cout.setf(ios::showpoint | ios::fixed);
  cout.precision(20);
  sol.read();
  sol.solve();
  sol.write();
  return 0;
}
