#include <bits/stdc++.h>
using namespace std;
void GG() { puts("No"), exit(0); }
template <class T>
inline void read(T &x) {
  int f = 0;
  x = 0;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar()) f |= (ch == '-');
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  if (f) x = -x;
}
const int N = 100005;
const int inf = 1e9 + 9;
struct edge {
  int u, v, c, w;
} e[N];
int vis[N], n, m, cnt;
map<int, int> cur;
vector<pair<int, int> > t[N];
vector<int> g[N], pt;
namespace OwO {
vector<int> c[N], l[N], tmp, ans;
int cc, cl;
int bas[N], now[N], vis[N], cnt;
int loop[N], inl[N], fa[N], from[N], tot, cntv, cnte;
vector<pair<int, int> > t[N], T[N];
void dfs(int u) {
  vis[u] = 1;
  cntv++, cnte += t[u].size();
  int f = fa[u];
  for (auto v : t[u])
    if (!vis[v.first]) {
      fa[v.first] = u;
      from[v.first] = v.second;
      dfs(v.first);
    } else if (v.first == f)
      f = 0;
    else {
      tot = 0;
      loop[++tot] = v.second;
      inl[v.first] = 1, tmp.push_back(v.first);
      for (int x = u; x != v.first; x = fa[x]) {
        loop[++tot] = from[x];
        inl[x] = 1, tmp.push_back(x);
      }
    }
}
void push(int i) {
  if (i > 0) {
    for (int k = 1; k < l[i].size(); k += 2) ans.push_back(l[i][k]);
    return;
  }
  i *= -1;
  for (int k = 0; k < l[i].size(); k += 2) ans.push_back(l[i][k]);
}
void print(int u, int fa) {
  for (auto v : t[u])
    if (v.first != fa && !inl[v.first]) {
      push(v.second);
      print(v.first, u);
    }
}
struct tr {
  int a, b, c;
};
bool Bfs(int s, int ff) {
  static int q[N], fro[N];
  int l = 0, r = 0;
  q[r++] = s;
  fro[s] = 0;
  while (l < r) {
    int u = q[l++];
    for (auto v : T[u]) {
      if (fro[u] == v.second) continue;
      if (now[v.first]) return 0;
      now[v.first] = 1, q[r++] = v.first;
      fro[v.first] = -v.second;
      if (ff) push(v.second);
    }
  }
  return 1;
}
bool chk(int lim, int ff) {
  cnt = 0;
  if (ff) ans.clear();
  for (int i = (1); i <= (n); i++) now[i] = bas[i];
  for (int i = (1); i <= (cc); i++) {
    int A = 0, B = 0;
    for (int k = 0; k < c[i].size(); k += 2) {
      A = max(A, e[c[i][k]].w);
      B = max(B, e[c[i][k + 1]].w);
    }
    if (A > lim && B > lim) return 0;
    if (ff && A <= lim)
      for (int k = 0; k < c[i].size(); k += 2) ans.push_back(c[i][k]);
    else if (ff && B <= lim)
      for (int k = 1; k < c[i].size(); k += 2) ans.push_back(c[i][k]);
  }
  for (int i = (1); i <= (cl); i++)
    if (l[i].size() & 1) {
      int A = 0, B = 0;
      for (int k = 0; k < l[i].size(); k += 2) {
        A = max(A, e[l[i][k]].w);
        if (k + 1 < l[i].size()) B = max(B, e[l[i][k + 1]].w);
      }
      if (A > lim && B > lim) return 0;
      if (B <= lim) {
        if (ff)
          for (int k = 1; k < l[i].size(); k += 2) ans.push_back(l[i][k]);
      } else {
        int fir = e[l[i][0]].u;
        int las = e[l[i].back()].v;
        if (now[fir] || now[las]) return 0;
        now[fir] = now[las] = 1;
        if (ff)
          for (int k = 0; k < l[i].size(); k += 2) ans.push_back(l[i][k]);
      }
    }
  for (int i = (1); i <= (n); i++)
    vis[i] = inl[i] = 0, t[i].clear(), T[i].clear();
  vector<tr> Tmp;
  for (int i = (1); i <= (cl); i++)
    if (l[i].size() % 2 == 0) {
      int A = 0, B = 0;
      for (int k = 0; k < l[i].size(); k += 2) {
        A = max(A, e[l[i][k]].w);
        B = max(B, e[l[i][k + 1]].w);
      }
      if (A > lim && B > lim) return 0;
      int fir = e[l[i][0]].u;
      int las = e[l[i].back()].v;
      int X = (A <= lim && !now[fir]);
      int Y = (B <= lim && !now[las]);
      if (X && Y) {
        Tmp.push_back((tr){i, fir, las});
        T[fir].push_back(make_pair(las, i));
        T[las].push_back(make_pair(fir, -i));
      } else if (X) {
        now[fir] = 1;
        if (ff)
          for (int k = 0; k < l[i].size(); k += 2) ans.push_back(l[i][k]);
        if (!Bfs(fir, ff)) return 0;
      } else if (Y) {
        now[las] = 1;
        if (ff)
          for (int k = 1; k < l[i].size(); k += 2) ans.push_back(l[i][k]);
        if (!Bfs(las, ff)) return 0;
      } else
        return 0;
    }
  for (auto x : Tmp)
    if (!now[x.b] && !now[x.c]) {
      t[x.b].push_back(make_pair(x.c, x.a));
      t[x.c].push_back(make_pair(x.b, -x.a));
    }
  for (int i = (1); i <= (n); i++)
    if (!vis[i] && t[i].size()) {
      cntv = cnte = fa[i] = from[i] = 0;
      tmp.clear(), dfs(i);
      if (cnte > 2 * cntv) return 0;
      if (!ff) continue;
      if (cnte == 2 * cntv - 2)
        print(i, 0);
      else {
        for (int i = (1); i <= (tot); i++) push(loop[i]);
        for (auto x : tmp) print(x, 0);
      }
    }
  return 1;
}
void rmain() {
  memset(bas, 0, sizeof bas);
  for (int i = (1); i <= (cc); i++) {
    if (c[i].size() & 1) GG();
    for (auto k : c[i]) ++bas[e[k].u];
  }
  for (int i = (1); i <= (cl); i++) {
    for (int k = 0; k + 1 < l[i].size(); k++) ++bas[e[l[i][k]].v];
  }
  for (int i = (1); i <= (n); i++)
    if (bas[i] >= 2) GG();
  int l = 0, r = inf, mi;
  while (l < r) {
    mi = (l + r) >> 1;
    if (chk(mi, 0))
      r = mi;
    else
      l = mi + 1;
  }
  if (l == inf) GG();
  puts("Yes");
  chk(l, 1);
  printf("%d %d\n", l, (int)ans.size());
  for (auto x : ans) printf("%d ", x);
  puts("");
}
}  // namespace OwO
int main() {
  read(n), read(m);
  for (int i = (1); i <= (m); i++) {
    read(e[i].u), read(e[i].v);
    read(e[i].c), read(e[i].w);
    if (!cur[e[i].c])
      e[i].c = cur[e[i].c] = ++cnt;
    else
      e[i].c = cur[e[i].c];
    g[e[i].c].push_back(i);
  }
  for (int i = (1); i <= (cnt); i++) {
    pt.clear();
    for (auto k : g[i]) pt.push_back(e[k].u), pt.push_back(e[k].v);
    sort(pt.begin(), pt.end());
    pt.erase(unique(pt.begin(), pt.end()), pt.end());
    for (auto x : pt) {
      t[x].clear();
      vis[x] = 0;
    }
    for (auto k : g[i]) {
      t[e[k].u].push_back(make_pair(e[k].v, k));
      t[e[k].v].push_back(make_pair(e[k].u, k));
    }
    for (auto x : pt)
      if (t[x].size() >= 3) GG();
    for (auto x : pt)
      if (!vis[x] && t[x].size() == 1) {
        int las = x, p = t[x][0].first;
        vis[las] = 1;
        vector<int> owo(1, t[x][0].second);
        int kk = t[x][0].second;
        if (e[kk].u != x) swap(e[kk].u, e[kk].v);
        while (!vis[p]) {
          vis[p] = 1;
          if (t[p].size() == 1) break;
          int o = (las == t[p][0].first);
          owo.push_back(t[p][o].second);
          int kk = t[p][o].second;
          if (e[kk].u != p) swap(e[kk].u, e[kk].v);
          las = p, p = t[p][o].first;
        }
        if (owo.size() >= 2) OwO::l[++OwO::cl] = owo;
      }
    for (auto x : pt)
      if (!vis[x] && t[x].size() == 2) {
        int las = x, p = t[x][0].first;
        vis[las] = 1;
        vector<int> owo(1, t[x][0].second);
        int kk = t[x][0].second;
        if (e[kk].u != x) swap(e[kk].u, e[kk].v);
        while (!vis[p]) {
          vis[p] = 1;
          int o = (las == t[p][0].first);
          owo.push_back(t[p][o].second);
          int kk = t[p][o].second;
          if (e[kk].u != p) swap(e[kk].u, e[kk].v);
          las = p, p = t[p][o].first;
        }
        OwO::c[++OwO::cc] = owo;
      }
  }
  OwO::rmain();
  return 0;
}
