#include <bits/stdc++.h>
using namespace std;
template <typename A, typename B>
inline void chmin(A &a, B b) {
  if (a > b) a = b;
}
template <typename A, typename B>
inline void chmax(A &a, B b) {
  if (a < b) a = b;
}
namespace SCC {
void visit(const vector<vector<long long>> &G, vector<long long> &vs,
           vector<long long> &used, long long v) {
  used[v] = true;
  for (auto u : G[v]) {
    if (!used[u]) visit(G, vs, used, u);
  }
  vs.push_back(v);
}
void visit2(const vector<vector<long long>> &T, vector<long long> &used,
            vector<long long> &comp, vector<long long> &vec, long long k,
            long long v) {
  comp[v] = k;
  used[v] = true;
  vec.push_back(v);
  for (auto u : T[v]) {
    if (!used[u]) visit2(T, used, comp, vec, k, u);
  }
}
void decompose(const vector<vector<long long>> &G, vector<vector<long long>> &H,
               vector<long long> &comp) {
  vector<vector<long long>> T(G.size());
  for (long long i = 0; i < G.size(); i++) {
    for (auto v : G[i]) {
      T[v].push_back(i);
    }
  }
  comp.resize(G.size());
  vector<long long> vs(G.size());
  vector<long long> used(G.size());
  for (long long i = 0; i < G.size(); i++) {
    if (!used[i]) visit(G, vs, used, i);
  }
  reverse(vs.begin(), vs.end());
  fill(used.begin(), used.end(), 0);
  long long K = 0;
  vector<vector<long long>> S;
  for (auto v : vs) {
    if (!used[v]) {
      S.push_back(vector<long long>());
      visit2(T, used, comp, S.back(), K++, v);
    }
  }
  H.resize(K);
  fill(used.begin(), used.end(), 0);
  for (long long i = 0; i < K; i++) {
    for (auto v : S[i]) {
      for (auto u : G[v]) {
        if (used[comp[u]] || comp[v] == comp[u]) continue;
        used[comp[u]] = true;
        H[comp[v]].push_back(comp[u]);
      }
    }
    for (auto v : H[i]) used[v] = false;
  }
}
}  // namespace SCC
struct UF {
  vector<long long> par, sz;
  void init(long long n) {
    par.resize(n);
    sz.resize(n);
    for (long long i = 0; i < n; i++) {
      par[i] = i;
      sz[i] = 1;
    }
  }
  long long find(long long x) {
    return x == par[x] ? x : par[x] = find(par[x]);
  }
  void unite(long long x, long long y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    sz[x] += sz[y];
    par[y] = x;
  }
  bool same(long long x, long long y) { return find(x) == find(y); }
  long long size(long long x) { return sz[find(x)]; }
};
vector<vector<long long>> G;
vector<pair<long long, long long>> bridge;
long long ord[1000], low[1000];
bool vis[1000];
void dfs(long long v, long long p, long long &k) {
  vis[v] = true;
  ord[v] = k++;
  low[v] = ord[v];
  for (long long i = 0; i < G[v].size(); i++) {
    if (!vis[G[v][i]]) {
      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 if (G[v][i] != p) {
      low[v] = min(low[v], ord[G[v][i]]);
    }
  }
}
long long A[100000], B[100000];
long long N, M;
vector<pair<long long, long long>> backer;
long long sum[1000];
long long par[1000];
long long dep[1000];
void dfs2(long long v, long long p, long long d) {
  vis[v] = true;
  par[v] = p;
  dep[v] = d;
  for (auto u : G[v]) {
    if (u == p) continue;
    if (vis[u])
      backer.push_back(pair<long long, long long>(min(u, v), max(u, v)));
    else {
      dfs2(u, v, d + 1);
    }
  }
}
void solve() {
  G = vector<vector<long long>>(N);
  for (long long i = 0; i < (M); i++)
    G[A[i]].push_back(B[i]), G[B[i]].push_back(A[i]);
  memset(vis, 0, sizeof(vis));
  dfs2(0, -1, 0);
  sort((backer).begin(), (backer).end());
  backer.erase(unique((backer).begin(), (backer).end()), backer.end());
  for (long long i = 0; i < (backer.size()); i++) {
    long long v = backer[i].first, u = backer[i].second;
    while (v != u) {
      if (dep[v] < dep[u]) swap(v, u);
      sum[v]++;
      v = par[v];
    }
  }
  for (long long i = 0; i < (backer.size()); i++) {
    long long v = backer[i].first, u = backer[i].second;
    while (v != u) {
      if (dep[v] < dep[u]) swap(v, u);
      sum[v]--;
      v = par[v];
    }
    long long cnt = 0;
    for (long long j = (1); j < (N); j++)
      if (sum[j] == 0) cnt++;
    if (cnt >= 2) {
      cout << "YES" << endl;
      return;
    }
    v = backer[i].first;
    u = backer[i].second;
    while (v != u) {
      if (dep[v] < dep[u]) swap(v, u);
      sum[v]++;
      v = par[v];
    }
  }
  cout << "NO" << endl;
}
signed main() {
  cin >> N >> M;
  for (long long i = 0; i < (M); i++) cin >> A[i] >> B[i], A[i]--, B[i]--;
  bool flag = false;
  long long deg[1000] = {};
  {
    vector<vector<long long>> G(N), H;
    for (long long i = 0; i < (M); i++) G[A[i]].push_back(B[i]);
    vector<long long> comp;
    SCC::decompose(G, H, comp);
    for (long long i = 0; i < (M); i++) {
      if (comp[A[i]] == comp[B[i]]) deg[B[i]]++;
    }
    if (H.size() == N) flag = true;
  }
  if (!flag) {
    for (long long i = 0; i < (M); i++) {
      if (deg[B[i]] != 1) continue;
      UF uf;
      uf.init(N);
      for (long long j = 0; j < (M); j++)
        if (i != j) uf.unite(A[j], B[j]);
      bool ok = true;
      for (long long j = 0; j < (N); j++)
        if (uf.find(j) != uf.find(0)) ok = false;
      if (!ok) continue;
      G = vector<vector<long long>>(N);
      for (long long j = 0; j < (M); j++)
        if (i != j) G[A[j]].push_back(B[j]);
      vector<vector<long long>> H;
      vector<long long> comp;
      SCC::decompose(G, H, comp);
      if (H.size() != N) continue;
      G = vector<vector<long long>>(N);
      for (long long j = 0; j < (M); j++)
        if (i != j) G[A[j]].push_back(B[j]), G[B[j]].push_back(A[j]);
      memset(vis, 0, sizeof(vis));
      long long K = 0;
      bridge.clear();
      dfs(0, -1, K);
      if (bridge.size() >= 2) {
        cout << "YES" << endl;
        return 0;
      }
    }
    cout << "NO" << endl;
    return 0;
  }
  solve();
  return 0;
}
