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 = 2 * 5e4 + 100;
int n, m, cnt;
map<int, vector<int> > ck[maxn * 5];
vector<int> side[maxn * 5], edge[maxn * 5];
bool vis[maxn * 5];
int dfn[maxn * 5], low[maxn * 5], idx, scc[maxn * 5], scc_cnt, stk[maxn * 5],
    top;
int mylist[maxn * 5][2];
int pc[maxn * 5][2][2];
int pre[maxn * 5];
struct gg {
  int u, v, c, w;
} mydata[maxn];
void add(int u, int i, int ty) {
  if (mylist[u][0]) {
    pre[cnt + 1] = mylist[u][0], pre[mylist[u][1]] = cnt + 2;
    side[cnt + 1].push_back(mylist[u][0]);
    side[mylist[u][1]].push_back(cnt + 2);
  }
  mylist[u][0] = cnt + 1;
  mylist[u][1] = cnt + 2;
  cnt += 2;
  side[mylist[u][0]].push_back(i + m);
  side[mylist[u][1]].push_back(i + m);
  pc[i][0][ty] = mylist[u][0];
  pc[i][1][ty] = mylist[u][1];
}
void pro(int u, int i, int c, int ty) {
  if (pre[pc[i][0][ty]]) side[i].push_back(pre[pc[i][0][ty]]);
  if (pre[pc[i][1][ty]]) side[i].push_back(pre[pc[i][1][ty]]);
  for (int j = 0; j < ck[u][c].size(); j++) {
    if (ck[u][c][j] == i) continue;
    side[i + m].push_back(ck[u][c][j]);
  }
}
void tarjan(int x) {
  stk[++top] = x;
  dfn[x] = low[x] = ++idx;
  vis[x] = 1;
  for (int i = 0; i < edge[x].size(); i++) {
    int v = edge[x][i];
    if (!dfn[v])
      tarjan(v), low[x] = min(low[x], low[v]);
    else if (!scc[v])
      low[x] = min(low[x], dfn[v]);
  }
  if (dfn[x] == low[x]) {
    scc_cnt++;
    while (1) {
      scc[stk[top]] = scc_cnt;
      if (stk[top--] == x) break;
    }
  }
}
bool check(int k) {
  top = idx = scc_cnt = 0;
  for (int i = 1; i <= cnt; i++)
    edge[i] = side[i], scc[i] = dfn[i] = low[i] = vis[i] = 0;
  for (int i = 1; i <= m; i++) {
    if (mydata[i].w > k) edge[i].push_back(i + m);
  }
  for (int i = 1; i <= cnt; i++)
    if (!vis[i]) tarjan(i);
  for (int i = 1; i <= m; i++)
    if (scc[i] == scc[i + m]) return 0;
  return 1;
}
vector<int> ans;
int main() {
  scanf("%d%d", &n, &m);
  cnt = 2 * m;
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d%d", &mydata[i].u, &mydata[i].v, &mydata[i].c, &mydata[i].w);
    add(mydata[i].u, i, 0);
    add(mydata[i].v, i, 1);
    if (ck[mydata[i].u][mydata[i].c].size() == 2 ||
        ck[mydata[i].v][mydata[i].c].size() == 2) {
      printf("No");
      return 0;
    }
    ck[mydata[i].u][mydata[i].c].push_back(i);
    ck[mydata[i].v][mydata[i].c].push_back(i);
  }
  for (int i = 1; i <= m; i++) {
    pro(mydata[i].u, i, mydata[i].c, 0);
    pro(mydata[i].v, i, mydata[i].c, 1);
  }
  int l = 0, r = 1e9;
  if (!check(1e9)) {
    printf("No");
    return 0;
  }
  while (l < r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      r = mid;
    else
      l = mid + 1;
  }
  check(l);
  for (int i = 1; i <= m; i++)
    if (scc[i] < scc[i + m]) ans.push_back(i);
  printf("Yes\n%d %d\n", l, ans.size());
  for (int i = 0; i < ans.size(); i++) printf("%d ", ans[i]);
  return 0;
}
