#include <bits/stdc++.h>
using namespace std;
int n;
vector<vector<int>> adj;
deque<int> cycle;
vector<int> vis;
set<int> onstack;
bool cycle_found = false;
void dfs(int v) {
  vis[v] = true;
  onstack.insert(v);
  cycle.push_back(v);
  for (int x : adj[v]) {
    if (!vis[x])
      dfs(x);
    else if (onstack.count(x)) {
      cycle.push_back(x);
      cycle_found = true;
    }
    if (cycle_found) return;
  }
  if (cycle_found) return;
  onstack.erase(v);
  cycle.pop_back();
}
int e1 = -1, e2 = -1;
bool has_cycle(int v) {
  vis[v] = true;
  onstack.insert(v);
  bool res = false;
  for (int x : adj[v]) {
    if (v == e1 and x == e2) continue;
    if (!vis[x])
      res = res or has_cycle(x);
    else if (onstack.count(x))
      res = true;
  }
  onstack.erase(v);
  return res;
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  cin >> n;
  int m;
  cin >> m;
  adj.resize(n);
  vis.resize(n, false);
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b, a--, b--;
    adj[a].push_back(b);
  }
  for (int i = 0; i < n; i++) {
    if (!vis[i]) {
      dfs(i);
    }
    if (cycle_found) break;
  }
  if (!cycle_found) {
    cout << "YES\n";
    return 0;
  }
  reverse(cycle.begin(), cycle.end());
  while (cycle[0] != cycle[cycle.size() - 1]) cycle.pop_back();
  reverse(cycle.begin(), cycle.end());
  bool yes = false;
  for (int i = 1; i < cycle.size(); i++) {
    e1 = cycle[i - 1];
    e2 = cycle[i];
    onstack.clear();
    bool check = false;
    fill(vis.begin(), vis.end(), 0);
    for (int j = 0; j < n; j++) {
      if (!vis[j]) check = has_cycle(j);
      if (check) break;
    }
    if (!check) {
      yes = true;
      break;
    }
    e1 = -1;
    e2 = -1;
  }
  if (yes)
    cout << "YES\n";
  else
    cout << "NO\n";
  return 0;
}
