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<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define LL long long
#define Re register int
using namespace std;
const int N=5e4+3;
int n,m,l,r,t,O,Q_o,b[N],ip[N*10],Ans[N],S[N][2];
struct QAQ{int x,y,w,co;}B[N];vector<int>CO,a[N],E[N];
inline void in(Re &x){
    int f=0;x=0;char c=getchar();
    while(c<'0'||c>'9')f|=c=='-',c=getchar();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
    x=f?-x:x;
}
struct BK{int x,head;}bk[N*13];
struct Tarjan{
	int o,t,dfn_O,Q[N*10],pan[N*10],dfn[N*10],low[N*10],head[N*10];
	struct QAQ{int to,next;}a[N*13];
	inline void add(Re x,Re y){a[++o].to=y,a[o].next=head[x],bk[o]=(BK){x,head[x]},head[x]=o;}
	inline void back(Re to){while(o>to)head[bk[o].x]=bk[o].head,--o;}
	inline void tarjan(Re x){
		low[x]=dfn[x]=++dfn_O,Q[++t]=x,pan[x]=1;
		for(Re i=head[x],to;i;i=a[i].next)
			if(!dfn[to=a[i].to])tarjan(to),low[x]=min(low[x],low[to]);
			else if(pan[to])low[x]=min(low[x],dfn[to]);
		if(low[x]==dfn[x]){
			++Q_o;
			while(1){
				ip[Q[t]]=Q_o,pan[Q[t]]=0;
				if(x==Q[t--])break;
			}
		}
	}
	inline void SuoPoint(){
		for(Re i=1;i<=O;++i)dfn[i]=low[i]=pan[i]=ip[i]=0;
		dfn_O=Q_o=t=0;
		for(Re i=1;i<=O;++i)if(!dfn[i])tarjan(i);
	}
}T1;
inline int judge(Re mid){
	Re flag=1,tmp=T1.o;
	for(Re i=1;i<=m;++i)if(B[i].w>mid)T1.add(i+m,i);
	T1.SuoPoint();//printf("O=%d, o=%d, Q_o=%d\n",O,T1.o,Q_o);
//	for(Re i=1;i<=(m<<1);++i)printf("ip[%d]=%d\n",i,ip[i]);
	for(Re i=1;i<=m;++i)if(ip[i]==ip[i+m]){flag=0;break;}
	T1.back(tmp);return flag;
}
int main(){
//	freopen("123.txt","r",stdin);
	in(n),in(m),O=m<<1;
	for(Re i=1;i<=m;++i)in(B[i].x),in(B[i].y),in(B[i].co),in(B[i].w),b[i]=B[i].co,r=max(r,B[i].w),a[B[i].x].push_back(i),a[B[i].y].push_back(i);
	sort(b+1,b+m+1),t=unique(b+1,b+m+1)-b-1;
	for(Re i=1;i<=m;++i)B[i].co=lower_bound(b+1,b+t+1,B[i].co)-b;
	for(Re x=1;x<=n;++x){
		for(Re i=0,SZ=a[x].size(),id;i<SZ;++i){
			id=a[x][i],S[i][0]=++O,S[i][1]=++O;
			if(i)T1.add(S[i-1][1],S[i][1]),T1.add(S[i-1][1],id+0*m);
			if(i)T1.add(S[i][0],S[i-1][0]);T1.add(S[i][0],id+0*m);
			if(i)T1.add(id+1*m,S[i-1][0]);T1.add(id+1*m,S[i][1]);
		}
		for(Re i=0,SZ=a[x].size(),id;i<SZ;++i){
			id=a[x][i];
			if(E[B[id].co].empty())CO.push_back(B[id].co);
			E[B[id].co].push_back(id);
		}
		for(Re I=0,SZ=CO.size();I<SZ;++I){
//			printf("x=%d, co=%d:\n",x,CO[I]);
			for(Re i=0,co=CO[I],SZ_=E[co].size(),id;i<SZ_;++i){
				id=E[co][i],S[i][0]=++O,S[i][1]=++O;
//				printf("%d ",id);
				if(i)T1.add(S[i-1][0],S[i][0]),T1.add(S[i-1][0],id+1*m);
				if(i)T1.add(S[i][1],S[i-1][1]);T1.add(S[i][1],id+1*m);
				if(i)T1.add(id+0*m,S[i-1][1]);T1.add(id+0*m,S[i][0]);
			}
//			puts("");
		}
		for(Re i=0,SZ=a[x].size(),id;i<SZ;++i)id=a[x][i],E[B[id].co].clear();CO.clear();
	}
//	printf("O=%d, o=%d\n",O,T1.o);
	if(!judge(r)){puts("No");return 0;}
	while(l<r){
		Re mid=l+r>>1;
		if(judge(mid))r=mid;
		else l=mid+1;
	}
	for(Re i=1;i<=m;++i)if(ip[i+m]<ip[i])Ans[++Ans[0]]=i;//要选i
	printf("Yes\n%d %d\n",r,Ans[0]);
	for(Re i=1;i<=Ans[0];++i)printf("%d ",Ans[i]);
}