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>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define put(x) cerr<<"Line "<<__LINE__<<": "<<#x<<" = "<<x<<endl;
#define X first
#define Y second
#define pb push_back
using namespace std;
typedef long long num;
typedef pair<int,int> point;
const int maxn=4e6+10,maxx=maxn,inf=1e9+10;

int n,m;

struct edge{
	int to,c,t,id,ii;
	edge(int _to=0,int _c=0,int _t=0,int _id=0,int _ii=0){
		to=_to;
		c=_c;
		t=_t;
		id=_id;
		ii=_ii;
	}
	bool operator < (edge e){
		if(c!=e.c){
			return c<e.c;
		}
		if(to!=e.to){
			return to<e.to;
		}
		return t<e.t;
	}
};

vector<edge> G[maxn];
vector<int> H[maxx],Hp[maxx];
vector<int> ans;
int mark[maxx];

int color[maxn],csize=0,st[maxx],last,cid[maxx],ts[maxx];

void dfs0(int a){
	mark[a]=1;
	for(int b:H[a]){
		if(!mark[b]){
			dfs0(b);
		}
	}
	ts[a]=last;
	st[last++]=a;
}

void dfs1(int a,int c){
	mark[a]=1;
	cid[a]=c;
	for(int b:Hp[a]){
		if(!mark[b]){
			dfs1(b,c);
		}
	}
}

bool check(int mid){
	rep(a,0,6*m){
		H[a].clear();
		Hp[a].clear();
	}
	rep(a,0,n){
		int sz=G[a].size();
		rep(i,0,sz){
			edge e=G[a][i];
			H[e.id+0*m].pb(e.ii+2*m);
			H[e.ii+3*m].pb(e.id+1*m);

			H[e.id+1*m].pb(e.ii+4*m);
			H[e.ii+5*m].pb(e.id+0*m);
			if(e.t>mid){
				H[e.id+0*m].pb(e.id+1*m);
			}
		}
		rep(i,0,sz-1){
			edge e0=G[a][i+0];
			edge e1=G[a][i+1];

			H[e0.ii+2*m].pb(e1.ii+2*m);
			H[e1.ii+3*m].pb(e0.ii+3*m);

			H[e0.ii+2*m].pb(e1.id+1*m);
			H[e1.id+0*m].pb(e0.ii+3*m);

			if(e0.c==e1.c){
				H[e0.ii+4*m].pb(e1.ii+4*m);
				H[e1.ii+5*m].pb(e0.ii+5*m);

				H[e0.ii+4*m].pb(e1.id+0*m);
				H[e1.id+1*m].pb(e0.ii+5*m);
			}
		}
	}
	last=0;
	memset(mark,0,sizeof mark);
	rep(a,0,6*m){
		if(!mark[a]){
			dfs0(a);
		}
	}
	rep(a,0,6*m){
		for(edge e:H[a]){
			int b=e.to;
			Hp[b].pb(a);
		}
	}
	memset(mark,0,sizeof mark);
	int coms=1;
	for(int i=6*m-1;i>=0;i--){
		int a=st[i];
		if(!mark[a]){
			dfs1(a,coms++);
		}
	}
	while(last!=6*m) {}
	rep(i,0,6*m){
		while(ts[st[i]]!=i){}
	}
	rep(i,0,m/2){
		if(cid[i]==cid[i+m]){
			return 0;
		}
	}
	ans.clear();
	rep(i,0,m/2){
		if(ts[i]<ts[i+m]){
			ans.pb(i);
		}
	}
	/*
	memset(mark,0,sizeof mark);
	for(int i=6*m-1;i>=0;i--){
		int a=st[i];
		if(a<m/2 && mark[a]==0){
			mark[a]=1;
		}
		if(a>=m && a<m+m/2 && mark[a-m]==0){
			mark[a-m]=1;
			ans.pb(a-m);
		}
	}
	*/
	return 1;
}

int32_t main(){
	scanf("%d%d",&n,&m);
	rep(i,0,m){
		int a,b,c,t;
		scanf("%d%d%d%d",&a,&b,&c,&t);
		a--,b--;
		color[i]=c;
		G[a].pb(edge(b,c,t,i,i<<1));
		G[b].pb(edge(a,c,t,i,i<<1|1));
	}
	m*=2;
	sort(color,color+m);
	csize=unique(color,color+m)-color;

	rep(a,0,n){
		for(edge &e:G[a]){
			e.c=lower_bound(color,color+csize,e.c)-color;
		}
		sort(G[a].begin(),G[a].end());
	}


	int l=-1,r=inf;
	while(r-l>1){
		int mid=(l+r)>>1;
		if(check(mid)){
			r=mid;
		}else{
			l=mid;
		}
	}
	if(r==inf){
		printf("No\n");
	}else{
		printf("Yes\n%d %d\n",r,int(ans.size()));
		for(int po:ans){
			printf("%d ",po+1);
		}
		printf("\n");
	}
}