#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#define rep(i,n) for (int i = 0; i < n; ++i)
#define drep(i,n) for (int i = n-1; i >= 0; --i)
#define pb push_back
#define sz(x) int(x.size())
#define mins(x,y) x = min(x,y)
#define maxs(x,y) x = max(x,y)
using namespace std;
inline int in() { int x; scanf("%d", &x); return x;}
typedef vector<int> vi;
typedef vector<vi> vvi;

struct Lowlink {
  int n, k;
  vvi to, st, br;
  vi ord, low;
  Lowlink(int n=0):n(n),to(n),st(n),br(n),ord(n,-1),low(n){}
  void add(int a, int b) {
    to[a].pb(b); st[a].pb(0);
    to[b].pb(a); st[b].pb(0);
  }
  void dfs(int v, int p=-1) {
    ord[v] = low[v] = k++;
    rep(i,sz(to[v])) {
      int u = to[v][i];
      if (u == p) continue;
      if (ord[u] == -1) {
        st[v][i] = 1;
        dfs(u,v);
        mins(low[v],low[u]);
      } else {
        st[v][i] = -1;
        mins(low[v],ord[u]);
      }
    }
  }
  int init() {
    k = 0;
    dfs(0);
    int res = 0;
    rep(i,n)rep(j,sz(to[i])) {
      int v = i, u = to[i][j];
      if (ord[v] > ord[u]) swap(v,u);
      if (ord[u] == low[u]) res++;
      br[i].pb(ord[u] == low[u]);
    }
    return res/2;
  }
};

int n, m;
vvi to;
vi used, vs;

int rv;
bool cfs(vvi& to, int v) {
  if (used[v]) {
    if (used[v] == 2) return false;
    rv = v;
    return true;
  }
  used[v] = 1;
  for (int u : to[v]) {
    if (cfs(to,u)) {
      if (rv != -1) vs.pb(v);
      if (rv == v) rv = -1;
      return true;
    }
  }
  used[v] = 2;
  return false;
}
bool findCycle(vvi& to) {
  used = vi(n);
  rv = -1;
  rep(i,n) if (!used[i]) {
    if (cfs(to,i)) return true;
  }
  return false;
}
bool solve1(int u, int v) {
  // printf("%d %d\n", v, u);
  vvi t(n);
  rep(i,n) for (int j : to[i]) {
    if (i == v && j == u) continue;
    t[i].pb(j);
    // printf("edge %d %d\n", i, j);
  }
  if (findCycle(t)) return false;
  // printf("%d %d\n", v, u);
  Lowlink g(n);
  rep(i,n) for (int j : to[i]) {
    if (i == v && j == u) continue;
    g.add(i,j);
  }
  return g.init() >= 2;
}
bool solve2(Lowlink& g, int ei, int ej) {
  Lowlink t(n);
  rep(i,n)rep(j,sz(g.to[i])) {
    if (ei == i && ej == j) continue;
    int u = g.to[i][j];
    if (!g.st[i][j]) continue;
    if (g.st[i][j] == -1 && i < u) continue;
    t.add(i,u);
  }
  return t.init() >= 2;
}

int main() {
  n = in(); m = in();
  to = vvi(n);
  rep(i,m) {
    int a = in(), b = in();
    --a; --b;
    to[a].pb(b);
  }
  if (findCycle(to)) {
    int s = sz(vs);
    rep(i,s) {
      if (solve1(vs[i],vs[(i+1)%s])) {
        puts("YES");
        return 0;
      }
    }
  } else if (m >= n) {
    Lowlink g(n);
    rep(i,n) for (int u : to[i]) g.add(i,u);
    if (g.init() >= 2) {
      puts("YES");
      return 0;
    }
    rep(i,n) rep(j,sz(g.to[i])) {
      if (g.st[i][j] != 1 || g.br[i][j]) continue;
      if (solve2(g,i,j)) {
        puts("YES");
        return 0;
      }
    }
  }
  puts("NO");
  return 0;
}