#include <bits/stdc++.h>
using namespace std;
template <typename T>
using Vec = vector<T>;
class StronglyConnectedComponentDecomposition {
 public:
  struct Result {
    Vec<int> topol;
    Vec<Vec<int> > dag;
  };

 private:
  int N;
  const Vec<Vec<int> >& adj;
  Vec<Vec<int> > rev_adj;
  Vec<int> rev_order;
  Vec<bool> used;
  Vec<int> topol;
  void dfs(int v) {
    used[v] = true;
    for (int u : adj[v])
      if (!used[u]) dfs(u);
    rev_order.push_back(v);
  }
  void revDfs(int v, int k) {
    used[v] = true;
    topol[v] = k;
    for (int u : rev_adj[v])
      if (!used[u]) revDfs(u, k);
  }

 public:
  StronglyConnectedComponentDecomposition(const Vec<Vec<int> >& _adj_)
      : N(_adj_.size()), adj(_adj_) {
    rev_adj.assign(N, Vec<int>());
    for (int v = (0); v < (N); ++v)
      for (int u : adj[v]) rev_adj[u].push_back(v);
  }
  Result decomposition() {
    used.assign(N, false);
    rev_order.clear();
    topol.assign(N, -1);
    for (int v = (0); v < (N); ++v)
      if (!used[v]) dfs(v);
    fill((used).begin(), (used).end(), false);
    int k = 0, m = rev_order.size();
    for (int i = (m - 1); i >= (0); --i) {
      int v = rev_order[i];
      if (!used[v]) revDfs(v, k++);
    }
    Vec<Vec<int> > dag(k);
    for (int v = (0); v < (N); ++v) {
      int tv = topol[v];
      for (int u : adj[v]) {
        int tu = topol[u];
        if (tv != tu) dag[tv].push_back(tu);
      }
    }
    for (int i = (0); i < (k); ++i) {
      sort((dag[i]).begin(), (dag[i]).end());
      dag[i].erase(unique((dag[i]).begin(), (dag[i]).end()), dag[i].end());
    }
    return Result{topol, dag};
  }
};
class FindBridge {
 private:
  int V;
  Vec<set<int> > adj;
  Vec<int> low, pre;
  int dfs(int v, int& count, int p, Vec<pair<int, int> >& br) {
    pre[v] = count++;
    low[v] = pre[v];
    for (int u : adj[v]) {
      if (pre[u] == -1) {
        low[v] = min(low[v], dfs(u, count, v, br));
        if (low[u] == pre[u]) br.push_back(pair<int, int>(v, u));
      } else {
        if (u != p) low[v] = min(low[v], low[u]);
      }
    }
    return low[v];
  }

 public:
  FindBridge(int V__) : V(V__), adj(V__, set<int>()) {}
  void addEdge(int u, int v) {
    adj[u].insert(v);
    adj[v].insert(u);
  }
  int count() {
    Vec<pair<int, int> > br;
    low.assign(V, -1);
    pre.assign(V, -1);
    int count = 0;
    dfs(0, count, -1, br);
    return br.size();
  }
};
int N, M, a[1010], b[1010];
Vec<Vec<int> > adj;
int doSCC() {
  StronglyConnectedComponentDecomposition::Result scc =
      StronglyConnectedComponentDecomposition(adj).decomposition();
  Vec<int> vcnt(N, 0);
  for (int v = (0); v < (N); ++v) vcnt[scc.topol[v]]++;
  int szov2 = 0;
  for (int i = (0); i < (N); ++i)
    if (vcnt[i] >= 2) szov2++;
  return szov2;
}
void solve() {
  for (int ig = (0); ig < (M); ++ig) {
    adj.assign(N, Vec<int>());
    for (int i = (0); i < (M); ++i) {
      if (i == ig) continue;
      adj[a[i]].push_back(b[i]);
    }
    if (doSCC() == 0) {
      FindBridge fb(N);
      for (int i = (0); i < (M); ++i) {
        if (i == ig) continue;
        fb.addEdge(a[i], b[i]);
      }
      if (fb.count() >= 2) {
        puts("YES");
        exit(0);
      }
    }
  }
  puts("NO");
}
int main() {
  cin >> N >> M;
  for (int i = (0); i < (M); ++i) {
    cin >> a[i] >> b[i];
    --a[i];
    --b[i];
  }
  solve();
}
