#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,b) FOR(i,0,b)
#define PB push_back
#define ALL(c) c.begin(),c.end()
using namespace std;
typedef long long LL;
typedef int ut;
typedef pair<ut,ut> pr;
typedef vector<ut> VI;
typedef vector<pr> Vpr;
const LL INF = 1LL<<60;
const int SIZE=1001;
int a[SIZE],b[SIZE];
VI edge[SIZE];
VI cedge[SIZE];
int N,M;
int directed[SIZE];
int bridges=0;
int bridgesP[SIZE];
bool searched[SIZE];
bool beused[SIZE];
bool isDAG(){
	queue<int> qu;
	FOR(i,1,N+1){
		if(cedge[i].size()==0) qu.push(i);
	}
	int times=0;
	while(!qu.empty()){
		int now=qu.front();
		qu.pop();
		times++;
		REP(i,edge[now].size()){
			int next=edge[now][i];
			directed[next]++;
			if(directed[next]==cedge[next].size()) qu.push(next);
		}
	}
	//cout << " " <<times << endl;
	return times==N;
}
int bridge(int now,int from){
	if(searched[now]){
		if(beused[now]){
			bridgesP[now]++;
			return beused[now];
		}
		return 0;
	}
	searched[now]=true;
	beused[now]=true;
	//cout << now << endl;
	int inbrids=0;
	REP(i,cedge[now].size()){
		int next=cedge[now][i];
		if(next!=from)
			inbrids+=bridge(next,now);
	}
	beused[now]=false;
	if(inbrids-bridgesP[now]==0&& from!=-1) bridges++;
	return inbrids-bridgesP[now];
}
bool solve(int x){
	FOR(i,1,N+1){
		edge[i].clear();
		cedge[i].clear();
		directed[i]=0;
		searched[i]=false;
		bridgesP[i]=0;
	}
	bridges=0;
	REP(i,M){
		if(x!=i){
			edge[a[i]].PB(b[i]);
			cedge[b[i]].PB(a[i]);
		}
	}
	if(!isDAG()) return false;
	//cout <<" FO" << endl;
//	cout << x << endl;
	REP(i,M){
		if(x!=i){
			cedge[a[i]].PB(b[i]);
		}
	}
	bridge(1,-1);
//	cout << bridges << endl;
	FOR(i,1,N+1){
		if(!searched[i]) return false;
	}
	if(bridges>=2) return true;
	return false;
}
int main(){
	cin >> N >> M;
	REP(i,M){
		cin >> a[i] >> b[i];
	}
	REP(i,M){
		if(solve(i)){
			cout << "YES" << endl;
			return 0;
		}
	}
	cout << "NO" << endl;
	return 0;
}