import java.io.*;
import java.util.*;
public class TaskD {
private final InputReader reader;
private final OutputWriter writer;
public TaskD(InputReader reader, OutputWriter writer) {
this.reader = reader;
this.writer = writer;
}
//InputReader reader = new InputReader(new FileInputStream("/home/lafa/input-10.txt"));
InputReader reader
= new InputReader
(System.
in); //OutputWriter writer = new OutputWriter(new FileOutputStream("/home/lafa/log1"));
OutputWriter writer
= new OutputWriter
(System.
out); new TaskD(reader, writer).run();
writer.writer.flush();
}
int[] A, B, C, T;
List<Integer>[] E;
List<Integer>[] F, RF;
int n, m;
int[] topsort;
int tpt;
int[] temp2 = new int[2];
int iter;
int[] was;
void DFS(int x) {
was[x] = iter;
for (int y : F[x]) {
if (was[y] != iter)
DFS(y);
}
topsort[tpt++] = x;
}
int[] col;
void DFS2(int x, int c) {
was[x] = iter;
col[x] = c;
for (int y : RF[x]) {
if (was[y] != iter)
DFS2(y, c);
}
}
ArrayList<Integer> enabled = new ArrayList<Integer>();
boolean can(int v) {
iter++;
for (int i = 0; i < m; i++) {
if (T[i] > v) {
F[2 * i + 1].add(2 * i);
RF[2 * i].add(2 * i + 1);
}
}
tpt = 0;
for (int x = 0; x < 6 * m; x++) {
if (was[x] != iter) {
DFS(x);
}
}
if (tpt != 6 * m)
throw new AssertionError();
int cur_col = 0;
iter++;
for (int i = tpt - 1; i >= 0; i--) {
int x = topsort[i];
if (was[x] != iter)
DFS2(x, cur_col++);
}
enabled.clear();
boolean bad = false;
for (int i = 0; i < m; i++) {
if (col[2 * i] == col[2 * i + 1])
bad = true;
if (col[2 * i + 1] > col[2 * i])
enabled.add(i);
}
for (int i = 0; i < m; i++) {
if (T[i] > v) {
F[2 * i + 1].remove(F[2 * i + 1].size() - 1);
RF[2 * i].remove(RF[2 * i].size() - 1);
}
}
return !bad;
}
final int inf = 1000 * 1000 * 1000 + 42;
int[] prv, nxt;
int get_orient(int i, int e) {
return (A[e] == i) ? 2 * e : 2 * e + 1;
}
public void run() {
n = reader.nextInt();
m = reader.nextInt();
A = new int[m];
B = new int[m];
C = new int[m];
T = new int[m];
for (int i = 0; i < n; i++)
E[i] = new ArrayList<Integer>();
for (int i = 0; i < m; i++) {
A[i] = reader.nextInt() - 1;
B[i] = reader.nextInt() - 1;
C[i] = reader.nextInt();
T[i] = reader.nextInt();
E[A[i]].add(i);
E[B[i]].add(i);
}
for (int i = 0; i < 6 * m; i++) {
F[i] = new ArrayList<Integer>();
RF[i] = new ArrayList<Integer>();
}
was = new int[6 * m];
topsort = new int[6 * m];
prv = new int[2 * m];
nxt = new int[2 * m];
for (int x = 0; x < n; x++) {
@Override
return Integer.
compare(C
[a
], C
[b
]); }
});
int ea = -1, eb = -1;
for (int l = 0, r = 0; l < E[x].size(); l = r) {
while (r != E[x].size() && C[E[x].get(r)] == C[E[x].get(l)])
r++;
if (r - l == 1)
continue;
if (r - l > 2 || ea != -1) {
writer.printf("No\n");
return;
}
ea = E[x].get(l);
eb = E[x].get(l + 1);
F[2 * ea].add(2 * eb + 1);
RF[2 * eb + 1].add(2 * ea);
F[2 * eb].add(2 * ea + 1);
RF[2 * ea + 1].add(2 * eb);
}
}
for (int i = 0; i < n; i++) {
for (int e : E[i]) {
e = get_orient(i, e);
prv[e] = nxt[e] = -1;
}
for (int j = 0; j < E[i].size() - 1; j++) {
int e = E[i].get(j);
int f = E[i].get(j + 1);
e = get_orient(i, e);
f = get_orient(i, f);
prv[f] = e;
nxt[e] = f;
}
for (int e : E[i]) {
e = get_orient(i, e);
F[2 * m + 2 * e + 0].add(2 * (e / 2) + 0);
F[2 * m + 2 * e + 1].add(2 * (e / 2) + 0);
RF[2 * (e / 2) + 0].add(2 * m + 2 * e + 0);
RF[2 * (e / 2) + 0].add(2 * m + 2 * e + 1);
if (prv[e] != -1) {
F[2 * m + 2 * e + 0].add(2 * m + 2 * prv[e] + 0);
RF[2 * m + 2 * prv[e] + 0].add(2 * m + 2 * e + 0);
F[2 * (e / 2) + 1].add(2 * m + 2 * prv[e] + 0);
RF[2 * m + 2 * prv[e] + 0].add(2 * (e / 2) + 1);
}
if (nxt[e] != -1) {
F[2 * m + 2 * e + 1].add(2 * m + 2 * nxt[e] + 1);
RF[2 * m + 2 * nxt[e] + 1].add(2 * m + 2 * e + 1);
F[2 * (e / 2) + 1].add(2 * m + 2 * nxt[e] + 1);
RF[2 * m + 2 * nxt[e] + 1].add(2 * (e / 2) + 1);
}
}
}
col = new int[6 * m];
int ans = 0;
int l = -1, r = inf;
//int l = 999755901, r = l + 1;
//int l = 999522589 - 1, r = 999522589 + 1;
while (r - l > 1) {
int q = (l + r) / 2;
if (can(q)) {
r = q;
} else {
l = q;
}
}
if (r == inf) {
writer.printf("No\n");
} else {
can(r);
writer.printf("Yes\n");
writer.printf("%d %d\n", r, enabled.size());
for (int e : enabled)
writer.printf("%d ", e + 1);
writer.printf("\n");
}
}
static class InputReader {
tokenizer = null;
}
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
}
}
return tokenizer.nextToken();
}
public int nextInt() {
}
public double nextDouble() {
return Double.
parseDouble(next
()); }
public long nextLong() {
return Long.
parseLong(next
()); }
}
static class OutputWriter {
}
}
}
}