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


/* This code is written by Nemlit */
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define debug printf("Now is Line : %d\n",__LINE__)
#define rep(i, a, b) for(re int i = (a); i <= (b); ++ i)
#define drep(i, a, b) for(re int i = (b); i >= (a); -- i)
#define Next(i, u) for(re int i = head[u]; i; i = e[i].next)
#define mem(k, p) memset(k, p, sizeof(k))
#define int long long
#define inf 1023456789
il int read() {
    re int x = 0, f = 1; re char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
    return x * f;
}
#define maxn 600005
int head[maxn], cnt, n, m, col[maxn], st[maxn], top, dfn[maxn], low[maxn], tim, co;
struct Edge { int u, v, c, t; }a[maxn];
struct edge { int v, next; }e[maxn];
struct node { int u, c; };
il void add(int u, int v) { e[++ cnt] = (edge){v, head[u]}, head[u] = cnt; }
vector<node>pax[maxn], pay[maxn];
il void Tarjan(int u) {
	dfn[u] = low[u] = ++ tim, st[++ top] = u;
	Next(i, u) {
		int v = e[i].v;
		if(!dfn[v]) Tarjan(v), low[u] = min(low[u], low[v]);
		else if(!col[v]) low[u] = min(low[u], dfn[v]);
	}
	if(low[u] == dfn[u]) {
		++ co;
		while(st[top + 1] != u) col[st[top --]] = co;
	}
}
il bool check(int x) {
	int tot = 2 * m;
	mem(head, 0), cnt = 0, mem(dfn, 0), mem(col, 0), mem(low, 0), top = 0, co = 0;
	rep(i, 1, m) if(a[i].t > x) add(i + m, i);
	rep(i, 1, n) {
		if(pax[i].size() < 2) continue;
		for(re int j = 0; j < (int)pax[i].size(); ++ j) {
			++ tot, add(tot, pax[i][j].u);
			if(j) add(tot - 1, tot), add(pax[i][j - 1].u + m, tot);
		}
		for(re int j = pax[i].size() - 1; ~j; -- j) {
			++ tot, add(tot, pax[i][j].u);
			if(j != (int)pax[i].size() - 1) add(tot - 1, tot), add(pax[i][j + 1].u + m, tot);
		}
	}
	rep(i, 1, n) {
		if(pay[i].size() < 2) continue;
		for(re int j = 0; j < (int)pay[i].size(); ++ j) {
			++ tot, add(tot, pax[i][j].u + m);
			if(j && pay[i][j].c == pay[i][j - 1].c) add(tot - 1, tot), add(pay[i][j - 1].u, tot);
		}
		for(re int j = pay[i].size() - 1; ~j; -- j) {
			++ tot, add(tot, pay[i][j].u + m);
			if(j != (int)pay[i].size() - 1 && pay[i][j].c == pay[i][j + 1].c) add(tot - 1, tot), add(pay[i][j + 1].u, tot);
		}
	}
	rep(i, 1, tot) if(!dfn[i]) Tarjan(i);
	rep(i, 1, m) if(col[i] == col[i + m]) return 0;
	return 1;
}
il bool cmp(node a, node b) { return a.c < b.c; }
signed main() {
	n = read(), m = read();
	rep(i, 1, m) {
		a[i].u = read(), a[i].v = read(), a[i].c = read(), a[i].t = read();
		pax[a[i].u].push_back((node){i, 0}), pax[a[i].v].push_back((node){i, 0});
		pay[a[i].u].push_back((node){i, a[i].c}), pay[a[i].v].push_back((node){i, a[i].c});
	}
	rep(i, 1, n) sort(pay[i].begin(), pay[i].end(), cmp);
	int l = 0, r = 1e9, ans = 0;
	while(l <= r) {
		int mid = (l + r) >> 1;
		if(check(mid)) r = mid - 1, ans = mid;
		else l = mid + 1;
	}
	if(!check(ans)) return puts("No"), 0;
	puts("Yes");
	rep(i, 1, m) if(col[i] > col[i + m]) st[++ top] = i;
	cout << ans << ' ' << top << endl;
	rep(i, 1, top) cout << st[i] << ' ';
	return 0;
}