#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef vector<int> vi;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()

class unionfind {
	vector<int> par, rank;

public:
	void init(int n) {
		par.resize(n);
		rank.resize(n);

		for (int i = 0; i < n; i++) {
			par[i] = i;
			rank[i] = 0;
		}
	}

	int find(int x) {
		if (par[x] == x) return x;
		else return par[x] = find(par[x]);
	}

	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) return ;

		if (rank[x] < rank[y]) par[x] = y;
		else {
			par[y] = x;
			if (rank[x] == rank[y]) ++rank[x];
		}
	}

	bool same(int x, int y) { return (find(x) == find(y)); }
} uf;

#define MAX_V 510

int V;
vector<int> G[MAX_V], rG[MAX_V];
vector<int> vs; 

bool vis[MAX_V];
int cmp[MAX_V]; 

void add_edge(int from, int to)
{
	G[from].pb(to);
	rG[to].pb(from);
}

void dfs(int v)
{
	vis[v] = true;

	for (int to : G[v]) {
		if (!vis[to]) dfs(to);
	}

	vs.push_back(v);
}

void rdfs(int v, int k)
{
	vis[v] = true;
	cmp[v] = k;

	for (int to : rG[v]) {
		if (!vis[to]) rdfs(to, k);
	}
}

int scc()
{
	memset(vis, 0, sizeof(vis));
	vs.clear();

	rep(v, V) if (!vis[v]) dfs(v);

	memset(vis, 0, sizeof(vis));

	int k = 0;
	reverse(ALL(vs));

	for (int v : vs) {
		if (!vis[v]) rdfs(v, k++);
	}

	return k;
}

class LOWLINK {
public:
	int V;
	vector<int> G[510];
	vector<pair<int, int> > bridge;
	int ord[510], low[510];
	bool vis[510];
	bool not1[510];

	void init(int _V)
	{
		V = _V;
		memset(vis, 0, sizeof(vis));
		memset(not1, 0, sizeof(not1));
		rep(i, V) G[i].clear();
		bridge.clear();
	}

	void calc()
	{
		int k = 0;
		rep(i, V) if (!vis[i]) DFS(i, -1, k);

	}

	void add_edge(int a, int b)
	{
		G[a].pb(b); G[b].pb(a);
	}

	void DFS(int v, int p, int &k)
	{
		vis[v] = true;

		ord[v] = k++;
		low[v] = ord[v];

		bool isArticulation = false;
		int ct = 0;

		for (int i = 0; i < G[v].size(); i++) {
			if (!vis[G[v][i]]) {
				ct++;
				DFS(G[v][i], v, k);
				low[v] = min(low[v], low[G[v][i]]);
				if (ord[v] < low[G[v][i]]) {
					bridge.push_back(make_pair(min(v, G[v][i]), max(v, G[v][i])));
				} else {
					not1[v] = not1[G[v][i]] = 1;
				}
			}
			else if (G[v][i] != p) {
				low[v] = min(low[v], ord[G[v][i]]);
			}
		}
	}
} T;

int N, M;
int A[50010], B[50010];
int in[510];

int main() {
	scanf("%d %d", &N, &M);

	V = N;

	rep(i, M) {
		scanf("%d%d", &A[i], &B[i]);
		--A[i]; --B[i];
		//add_edge(A[i], B[i]);
	}

	rep(i, M) {
		T.init(N);
		rep(j, N) {
			G[j].clear();
			rG[j].clear();
		}

		rep(j, M) if (j != i) {
			add_edge(A[j], B[j]);
			T.add_edge(A[j],B[j]);
			T.add_edge(B[j],A[j]);
		}

		int now = scc();
		uf.init(N);

		bool ok = 1;

		rep(j, N) {
			for (int to : G[j]) {
				if (cmp[j] == cmp[to]) {
					ok = 0;
				}
				uf.unite(j, to);
			}
		}

		rep(j, N) {
			if (!uf.same(0,j)) ok=0;
		}
		T.calc();

		if (ok && T.bridge.size() >= 2) {
			puts("YES");
			return 0;
		}
	}
	puts("NO");
	return 0;

	int num = scc();

	if (num == N) {
		puts("CASE1");
		T.init(N);

		rep(i, M) {
			T.add_edge(A[i], B[i]);
			T.add_edge(B[i], A[i]);
		}
		T.calc();

		cout<<T.bridge.size()<<endl;

		bool size_3 = 0;
		rep(i, N) if (T.not1[i]) size_3 = 1;
		if (size_3 && T.bridge.size() >= 2) {
			puts("YES");
		} else {
			puts("NO");
		}
	} else {
		puts("CASE2");
		memset(in, -1, sizeof(in));

		vi cand;
		int id = -1;
		rep(i, N) cout << cmp[i] << endl;
		rep(i, M) {
			if (cmp[A[i]] == cmp[B[i]]) {
				if (in[B[i]] != -1 || (id != -1 && cmp[A[i]] != id)) {
					puts("NO");
					return 0;
				}

				id = cmp[A[i]];
				in[B[i]] = A[i];
				cand.pb(A[i]);
			}
		}
		cout<<cand.size()<<endl;

		if (num - 1 + (int)cand.size() != N) {
			puts("NO");
			return 0;
		}

		puts("DEB");
		for (int v : cand) {
			T.init(N);
			rep(i, M) {
				if (!(A[i] == in[v] && B[i] == v)) {
					T.add_edge(A[i], B[i]);
					T.add_edge(B[i], A[i]);
				}
			}
			T.calc();
			if ((int)T.bridge.size() >= 2) {
				puts("YES");
				return 0;
			}
		}

		puts("NO");
		return 0;
	}


	return 0;
}