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>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long
#define F first
#define S second
#define pb push_back
#define all(x) x.begin(), x.end()

const int N = 5e4 + 5;
const int LOG = 20;
const int MOD = 1e9 + 7;
const ll inf = 1e9 + 5;


int n, m;
struct edge{
    int u, v, c, w, id;
} e[N];

vector <int> col, wei;
inline void scan(){
    cin >> n >> m;
    for (int i = 0; i < m; i ++){
        e[i].id = i;
        cin >> e[i].u >> e[i].v;
        cin >> e[i].c >> e[i].w;
        col.pb(e[i].c);
        wei.pb(e[i].w);
    }
    sort(all(col));
    col.resize(unique(all(col)) - col.begin());
    return;
}

vector <int> E[N], V[N];
unordered_map <int, int> deg[N];
int dg[N];

int h[N];
vector <int> g[N];

inline int oth(int id, int v){
    return (e[id].v == v ? e[id].u : e[id].v);
}

bool dfs(int v, int pr, int c){
    for (int id : g[v]){
        int u = oth(id, v);
        if (!h[u]){
            h[u] = h[v] + 1;
            if ((h[u] & 1) && deg[v].count(c)) return 0;
            if ((h[u] & 1) == 0){
                dg[u] ++;
                dg[v] ++;
                if (2 <= dg[u]) return 0;
                if (2 <= dg[v]) return 0;
            }
            if (!dfs(u, id, c)) return 0;
        }
        else if (id != pr){
            if ((h[u] & 1) != (h[v] & 1)) return 0;
        }
    }
    return 1;
}
inline bool ok(int mid){
    for (int v = 1; v <= n; v ++){
        dg[v] = 0;
        deg[v].clear();
    }
    for (int i = 0; i < (int)col.size(); i ++){
        E[i].clear();
        V[i].clear();
    }
    for (int i = 0; i < m; i ++){
        int u = e[i].u;
        int v = e[i].v;
        int c = e[i].c;
        int id = lower_bound(all(col), c) - col.begin();
        if (e[i].w <= mid){
            E[id].pb(i);
            V[id].pb(u);
            V[id].pb(v);
            continue;
        }
        deg[u][c] ++; deg[v][c] ++;
        if (deg[u][c] == 2) return 0;
        if (deg[v][c] == 2) return 0;
    }
    for (int id = 0; id < (int)col.size(); id ++){
        for (int i : E[id]){
            int u = e[i].u;
            int v = e[i].v;
            g[u].pb(i); g[v].pb(i);
            if (2 < (int)g[u].size()) return 0;
            if (2 < (int)g[v].size()) return 0;
        }
        for (int v : V[id]){
            if (!h[v] && deg[v].count(col[id])){
                h[v] = 1;
                if (!dfs(v, -1, col[id])) return 0;
            }
        }
        for (int v : V[id]){
            h[v] = 0;
            g[v].clear();
        }
    }
    return 1;
}

int ans;
vector <int> vc;

inline void solve(){
    sort(all(wei));
    wei.resize(unique(all(wei)) - wei.begin());
    int l = -1, r = wei.size();
    while (l + 1 < r){
        int mid = (l + r) >> 1;
        (ok(mid) ? r : l) = mid;
    }
    ans = r;
    return;
}







void dfsCalc(int v, int c){
    for (int id : g[v]){
        int u = oth(id, v);
        if (!h[u]){
            h[u] = h[v] + 1;
            if ((h[u] & 1) == 0) vc.pb(id);
            dfsCalc(u, c);
        }
    }
    return;
}
inline void okCalc(int mid){
    for (int v = 1; v <= n; v ++){
        deg[v].clear();
    }
    for (int i = 0; i < (int)col.size(); i ++){
        E[i].clear();
        V[i].clear();
    }
    for (int i = 0; i < m; i ++){
        int u = e[i].u;
        int v = e[i].v;
        int c = e[i].c;
        int id = lower_bound(all(col), c) - col.begin();
        if (e[i].w <= mid){
            E[id].pb(i);
            V[id].pb(u);
            V[id].pb(v);
            continue;
        }
        deg[u][c] ++; deg[v][c] ++;
    }
    for (int id = 0; id < (int)col.size(); id ++){
        for (int i : E[id]){
            int u = e[i].u;
            int v = e[i].v;
            g[u].pb(i); g[v].pb(i);
        }
        for (int v : V[id]){
            if (!h[v] && deg[v].count(col[id])){
                h[v] = 1;
                dfsCalc(v, col[id]);
            }
        }
        for (int v : V[id]){
            h[v] = 0;
            g[v].clear();
        }
    }
    return;
}












inline void print(){
    if (!ok(ans)){
        cout << "No\n";
        return;
    }
    okCalc(ans);
    cout << "Yes\n" << ans << ' ' << (int)vc.size() << '\n';
    for (int it : vc) cout << it + 1 << ' ';
    cout << '\n';
    return;
}

int main() {
    scan();
    solve();
    print();
    return 0;
}