/*
ЗАПУСКАЕМ ПРАВОСЛАВНОГО
ГУСЯ░▄▀▀▀▄░РАБОТЯГИ░
▄▄██▀░◐░░░▌░░░░░░░
░░░░▌░░░░░▐░░░░░░░
░░░░▌░░†░░▐▄▄░░░░░
░░░░▌░░░░▄▀▒▒▀▀▀▀▄
░░░▐░░░░▐▒▒▒▒▒▒▒▒▀▀▄
░░░▐░░░░▐▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░▀▄░░░░▀▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░░▀▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▀▄
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░▄▄▌▌▄▌▌░░░░░
 */
#include<bits/stdc++.h>
using namespace std;

const int sz = 500;
vector<int> g[sz];
vector<int> cycle;
int color[sz];

int dfs(int f) {
  color[f] = 1;
  for(int v : g[f]) {
    if(color[v] == 1) {
      cycle.push_back(f);
      return v;
    }
    if(color[v] == 2) continue;
    int res = dfs(v);
    if(res == -2) return -2;
    if(res == -1) continue;
    cycle.push_back(f);
    if(res == f) {
      return -2;
    } else {
      return res;
    }
  }
  color[f] = 2;
  return -1;
}

pair<int,int> bad;

int F, T;

bool check(int f) {
  color[f] = 1;
  for(int v : g[f]) {
    if(v == T && f == F) continue;
    if(color[v] == 1) return 1;
    if(check(v)) return 1;
  }
  color[f] = 2;
  return 0;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  for(int i=0;i<m;i++) {
    int f,t;
    cin >> f >> t;
    f--,t--;
    g[f].push_back(t);
  }
  memset(color, 0, sizeof color);
  for(int i=0;i<n && cycle.size() == 0; i++) {
    if(color[i] == 0) {
      dfs(i);
    }
  }
  if(cycle.size() == 0) {
    cout << "YES\n";
    return 0;
  }
  reverse(cycle.begin(), cycle.end());
  for (int i=0;i<cycle.size();i++) {
    F = cycle[i];
    T = cycle[(i + 1) % cycle.size()];
    memset(color, 0, sizeof color);
    bool bad = false;
    for(int i=0;i<n && !bad;i++) {
      if(!color[i]) {
        bad |= check(i);
      }
    }
    if(!bad) {
      cout << "YES\n";
      return 0;
    }
  }
  cout << "NO\n";
  return 0;
}


/*
ЗАПУСКАЕМ ПРАВОСЛАВНОГО
ГУСЯ░▄▀▀▀▄░РАБОТЯГИ░
▄▄██▀░◐░░░▌░░░░░░░
░░░░▌░░░░░▐░░░░░░░
░░░░▌░░†░░▐▄▄░░░░░
░░░░▌░░░░▄▀▒▒▀▀▀▀▄
░░░▐░░░░▐▒▒▒▒▒▒▒▒▀▀▄
░░░▐░░░░▐▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░▀▄░░░░▀▄▒▒▒▒▒▒▒▒▒▒▀▄
░░░░░▀▄▄▄▄▄█▄▄▄▄▄▄▄▄▄▀▄
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░░░▌▌░▌▌░░░░░
░░░░░░░░░▄▄▌▌▄▌▌░░░░░
 */
#include<bits/stdc++.h>
using namespace std;

const int sz = 500;
vector<int> g[sz];
vector<int> cycle;
int color[sz];

int dfs(int f) {
  color[f] = 1;
  for(int v : g[f]) {
    if(color[v] == 1) {
      cycle.push_back(f);
      return v;
    }
    int res = dfs(v);
    if(res == -2) return -2;
    if(res == -1) continue;
    cycle.push_back(f);
    if(res == f) {
      return -2;
    } else {
      return res;
    }
  }
  color[f] = 2;
  return -1;
}

pair<int,int> bad;

int F, T;

bool check(int f) {
  color[f] = 1;
  for(int v : g[f]) {
    if(v == T && f == F) continue;
    if(color[v] == 1) return 1;
    if(check(v)) return 1;
  }
  color[f] = 2;
  return 0;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  cin >> n >> m;
  for(int i=0;i<m;i++) {
    int f,t;
    cin >> f >> t;
    f--,t--;
    g[f].push_back(t);
  }
  memset(color, 0, sizeof color);
  for(int i=0;i<n && cycle.size() == 0; i++) {
    if(color[i] == 0) {
      dfs(i);
    }
  }
  if(cycle.size() == 0) {
    cout << "YES\n";
    return 0;
  }
  reverse(cycle.begin(), cycle.end());
  for (int i=0;i<cycle.size();i++) {
    F = cycle[i];
    T = cycle[(i + 1) % cycle.size()];
    memset(color, 0, sizeof color);
    bool bad = false;
    for(int i=0;i<n && !bad;i++) {
      if(!color[i]) {
        bad |= check(i);
      }
    }
    if(!bad) {
      cout << "YES\n";
      return 0;
    }
  }
  cout << "NO\n";
  return 0;
}


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

const int sz = 505;
vector<int> g[sz];
pair<int,int> bad;
int color[sz];

bool dfs(int f) {
  color[f] = 1;
  for(int v : g[f]) {
    if(make_pair(f,v) == bad) continue;
    if(color[v] == 2) continue;
    if(color[v] == 1) return true;
    if(dfs(v)) return true;
  }
  color[f] = 2;
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  vector<pair<int,int> > edges;
  cin >> n >> m;
  for(int i=0;i<m;i++) {
    int f,t;
    cin >> f >> t;
    f--,t--;
    g[f].push_back(t);
    edges.push_back({f,t});
  }

  for(auto p : edges) {
    bad = p;
    for(int i=0;i<n;i++) {
      color[i] = 0;
    }
    bool bad = false;
    for(int i=0;i<n && !bad; i++) {
      if(color[i] == 0) {
        bad |= dfs(i);
      }
    }
    if(!bad) {
      cout << "YES" << endl;
      return 0;
    }
  }
  cout << "NO" << endl;
  return 0;
}


#pragma GCC optimize("O3")
#pragma GCC target("avx,avx2,fma")
#include<bits/stdc++.h>
using namespace std;

const int sz = 505;
vector<int> g[sz];
int F, T;
int color[sz];

bool dfs(int f) {
  color[f] = 1;
  for(int v : g[f]) {
    if(f == F && v == T) continue;
    if(color[v] == 1) return true;
    if(color[v] == 2) continue;
    if(dfs(v)) return true;
  }
  color[f] = 2;
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, m;
  vector<pair<int,int> > edges;
  cin >> n >> m;
  for(int i=0;i<m;i++) {
    int f,t;
    cin >> f >> t;
    f--,t--;
    g[f].push_back(t);
    edges.push_back({f,t});
  }

  for(auto & p : edges) {
    F = p.first;
    T = p.second;
    for(int i=0;i<n;i++) {
      color[i] = 0;
    }
    bool bad = false;
    for(int i=0;i<n && !bad; i++) {
      if(color[i] == 0) {
        bad |= dfs(i);
      }
    }
    if(!bad) {
      cout << "YES" << endl;
      return 0;
    }
  }
  cout << "NO" << endl;
  return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> used, from;
V<int> path;
int ngfr, ngto;

bool dfs(int i) {
    path.emplace_back(i);
    if (from[i] && !used[i]) return true;
    from[i] = true;
    for (int e: edges[i]) {
        if (used[e]) continue;
        if (dfs(e)) {
            return true;
        }
    }
    used[i] = true;
    path.pop_back();
    return false;
}

bool dfs2nd(int i) {
    // cout << "i " << i << '\n';
    if (from[i] && !used[i]) return true;
    from[i] = true;
    for (int e: edges[i]) {
        if (i == ngfr && e == ngto) continue;
        if (used[e]) continue;
        if (dfs2nd(e)) {
            return true;
        }
    }
    used[i] = true;
    return false;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }
    used.resize(n, false), from.resize(n, false);
    bool path_exists = false;
    for (int i = 0; i < n; i++) {
        if (from[i]) continue;
        if (dfs(i)) {
            path_exists = true;
            break;
        }
    }

    if (!path_exists) {
        cout << "YES\n";
        return 0;
    }

    int start;
    for (start = 0; start < (int)path.size(); start++) {
        if (path[start] == path.back()) break;
    }

    // start から順に探索
    for (; start < (int)path.size() - 1; start++) {
        ngfr = path[start], ngto = path[start + 1];
        // cout << ngfr << ' ' << ngto << '\n';
        used = V<bool>(n, false);
        from = V<bool>(n, false);
        path_exists = false;
        for (int i = 0; i < n; i++) {
            if (from[i]) continue;
            if (dfs2nd(i)) {
                path_exists = true;
                break;
            }
        }
        if (!path_exists) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> visit, leave;
V<int> path;
bool is_cycle;

bool dfs_cycle(int i) {
    visit[i] = true;
    path.emplace_back(i);
    for (int e: edges[i]) {
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            return true;
        }
        if (dfs_cycle(e)) return true;
    }
    path.pop_back();
    leave[i] = true;
    return false;
}

int p1, p2;
void dfs_exist_cycle(int i) {
    visit[i] = true;
    for (int e: edges[i]) {
        if (p1 == i && p2 == e) continue;
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            is_cycle = true;
            return;
        }
        dfs_exist_cycle(e);
        if (is_cycle) continue;
    }
    leave[i] = true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }

    visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
    dfs_cycle(0);

    int sz = path.size();
    for (int i = 0; i < sz - 1; i++) {
        visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
        p1 = path[i], p2 = path[i + 1];
        dfs_exist_cycle(i);
        if (is_cycle) {
            cout << "NO\n";
            return 0;
        }
    }
    cout << "YES\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> used, from;
V<int> path;
int ngfr, ngto;

bool dfs(int i) {
    path.emplace_back(i);
    if (from[i] && !used[i]) return true;
    from[i] = true;
    for (int e: edges[i]) {
        if (dfs(e)) {
            return true;
        }
    }
    used[i] = true;
    path.pop_back();
    return false;
}

bool dfs2nd(int i) {
    // cout << "i " << i << '\n';
    if (from[i] && !used[i]) return true;
    from[i] = true;
    for (int e: edges[i]) {
        if (i == ngfr && e == ngto) continue;
        if (dfs2nd(e)) {
            return true;
        }
    }
    used[i] = true;
    return false;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }
    used.resize(n, false), from.resize(n, false);
    bool path_exists = false;
    for (int i = 0; i < n; i++) {
        if (from[i]) continue;
        if (dfs(i)) {
            path_exists = true;
            break;
        }
    }

    if (!path_exists) {
        cout << "YES\n";
        return 0;
    }

    int start;
    for (start = 0; start < (int)path.size(); start++) {
        if (path[start] == path.back()) break;
    }

    // start から順に探索
    for (; start < (int)path.size() - 1; start++) {
        ngfr = path[start], ngto = path[start + 1];
        // cout << ngfr << ' ' << ngto << '\n';
        used = V<bool>(n, false);
        from = V<bool>(n, false);
        path_exists = false;
        for (int i = 0; i < n; i++) {
            if (from[i]) continue;
            if (dfs2nd(i)) {
                path_exists = true;
                break;
            }
        }
        if (!path_exists) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> visit, leave;
V<int> path;
bool is_cycle;

bool dfs_cycle(int i) {
    visit[i] = true;
    path.emplace_back(i);
    for (int e: edges[i]) {
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            return true;
        }
        if (dfs_cycle(e)) return true;
    }
    path.pop_back();
    leave[i] = true;
    return false;
}

int p1, p2;
void dfs_exist_cycle(int i) {
    visit[i] = true;
    for (int e: edges[i]) {
        if (p1 == i && p2 == e) continue;
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            is_cycle = true;
            return;
        }
        dfs_exist_cycle(e);
        if (is_cycle) continue;
    }
    leave[i] = true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }

    visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
    bool path_exist = false;
    for (int i = 0; i < n; i++) {
        if (leave[i]) continue;
        path_exist |= dfs_cycle(i);
        if (path_exist) break;
    }
    if (!path_exist) {
        cout << "YES\n";
        return 0;
    }
    // DEBUG_VLL(path)

    int sz = path.size();
    for (int i = 0; i < sz - 1; i++) {
        visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
        p1 = path[i], p2 = path[i + 1];
        for (int j = 0; j < n; j++) {
            if (!leave[j]) dfs_exist_cycle(j);
        }
        if (!is_cycle) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> visit, leave;
V<int> path;
bool is_cycle;

bool dfs_cycle(int i) {
    visit[i] = true;
    path.emplace_back(i);
    for (int e: edges[i]) {
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            path.emplace_back(e);
            return true;
        }
        if (dfs_cycle(e)) return true;
    }
    path.pop_back();
    leave[i] = true;
    return false;
}

int p1, p2;
bool dfs_exist_cycle(int i) {
    visit[i] = true;
    for (int e: edges[i]) {
        if (p1 == i && p2 == e) continue;
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            return true;
        }
        if (dfs_exist_cycle(e)) return true;
    }
    leave[i] = true;
    return false;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }

    visit = V<bool>(n, false), leave = V<bool>(n, false);
    bool path_exist = false;
    for (int i = 0; i < n; i++) {
        if (leave[i]) continue;
        path_exist |= dfs_cycle(i);
        if (path_exist) break;
    }
    if (!path_exist) {
        cout << "YES\n";
        return 0;
    }

    int startp = 0;
    while (path.back() != path[startp]) startp++;

    int sz = path.size();
    for (int i = startp; i < sz - 1; i++) {
        visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
        p1 = path[i], p2 = path[i + 1];
        for (int j = 0; j < n; j++) {
            if (leave[j]) continue;
            is_cycle |= dfs_exist_cycle(j);
            if (is_cycle) break;
        }
        if (!is_cycle) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> visit, leave;
V<int> path;
bool is_cycle;

bool dfs_cycle(int i) {
    visit[i] = true;
    path.emplace_back(i);
    for (int e: edges[i]) {
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            return true;
        }
        if (dfs_cycle(e)) return true;
    }
    path.pop_back();
    leave[i] = true;
    return false;
}

int p1, p2;
void dfs_exist_cycle(int i) {
    visit[i] = true;
    for (int e: edges[i]) {
        if (p1 == i && p2 == e) continue;
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            is_cycle = true;
            return;
        }
        dfs_exist_cycle(e);
        if (is_cycle) break;
    }
    leave[i] = true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }

    visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
    bool path_exist = false;
    for (int i = 0; i < n; i++) {
        if (leave[i]) continue;
        path_exist |= dfs_cycle(i);
        if (path_exist) break;
    }
    if (!path_exist) {
        cout << "YES\n";
        return 0;
    }
    // DEBUG_VLL(path)

    int sz = path.size();
    for (int i = 0; i < sz; i++) {
        visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
        p1 = path[i], p2 = path[(i + 1) % sz];
        for (int j = 0; j < n; j++) {
            if (!leave[j]) dfs_exist_cycle(j);
        }
        if (!is_cycle) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> used, from;
V<int> path;
int ngfr, ngto;

bool dfs(int i) {
    path.emplace_back(i);
    if (used[i]) return true;
    from[i] = true;
    used[i] = true;
    for (int e: edges[i]) {
        if (dfs(e)) {
            return true;
        }
    }
    used[i] = false;
    path.pop_back();
    return false;
}

bool dfs2nd(int i) {
    // cout << "i " << i << '\n';
    if (used[i]) return true;
    from[i] = true;
    used[i] = true;
    for (int e: edges[i]) {
        if (i == ngfr && e == ngto) continue;
        if (dfs2nd(e)) {
            return true;
        }
    }
    used[i] = false;
    return false;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }
    used.resize(n, false), from.resize(n, false);
    bool path_exists = false;
    for (int i = 0; i < n; i++) {
        if (dfs(i)) {
            path_exists = true;
            break;
        }
    }

    if (!path_exists) {
        cout << "YES\n";
        return 0;
    }

    int start;
    for (start = 0; start < (int)path.size(); start++) {
        if (path[start] == path.back()) break;
    }

    // start から順に探索
    for (; start < (int)path.size() - 1; start++) {
        ngfr = path[start], ngto = path[start + 1];
        // cout << ngfr << ' ' << ngto << '\n';
        used = V<bool>(n, false);
        from = V<bool>(n, false);
        path_exists = false;
        for (int i = 0; i < n; i++) {
            if (dfs2nd(i)) {
                path_exists = true;
                break;
            }
        }
        if (!path_exists) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> used;
V<int> path;
int ngfr, ngto;

bool dfs(int i) {
    path.emplace_back(i);
    if (used[i]) {
        return true;
    }
    used[i] = true;
    for (int e: edges[i]) {
        if (dfs(e)) {
            return true;
        }
    }
    used[i] = false;
    path.pop_back();
    return false;
}

bool dfs2nd(int i) {
    if (used[i]) {
        return true;
    }
    used[i] = true;
    for (int e: edges[i]) {
        if (i == ngfr && e == ngto) continue;
        if (dfs2nd(e)) {
            return true;
        }
    }
    used[i] = false;
    return false;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }
    used.resize(n, false);
    if (!dfs(0)) {
        cout << "YES\n";
        return 0;
    }

    int start;
    for (start = 0; start < (int)path.size(); start++) {
        if (path[start] == path.back()) break;
    }

    // start から順に探索
    used = V<bool>(n, false);
    for (; start < (int)path.size() - 1; start++) {
        ngfr = path[start], ngto = path[start + 1];
        if(!dfs2nd(0)) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> visit, leave;
V<int> path;
bool is_cycle;

bool dfs_cycle(int i) {
    visit[i] = true;
    path.emplace_back(i);
    for (int e: edges[i]) {
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            return true;
        }
        if (dfs_cycle(e)) return true;
    }
    path.pop_back();
    leave[i] = true;
    return false;
}

int p1, p2;
void dfs_exist_cycle(int i) {
    visit[i] = true;
    for (int e: edges[i]) {
        if (p1 == i && p2 == e) continue;
        if (leave[e]) continue;
        if (visit[e] && !leave[e]) {
            is_cycle = true;
            return;
        }
        dfs_exist_cycle(e);
        if (is_cycle) continue;
    }
    leave[i] = true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }

    visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
    bool path_exist = false;
    for (int i = 0; i < n; i++) {
        if (leave[i]) continue;
        path_exist |= dfs_cycle(i);
        if (path_exist) break;
    }
    if (!path_exist) {
        cout << "YES\n";
        return 0;
    }
    // DEBUG_VLL(path)

    int sz = path.size();
    for (int i = 0; i < sz; i++) {
        visit = V<bool>(n, false), leave = V<bool>(n, false), is_cycle = false;
        p1 = path[i], p2 = path[(i + 1) % sz];
        for (int j = 0; j < n; j++) {
            if (!leave[j]) dfs_exist_cycle(j);
        }
        if (!is_cycle) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define rep(i, k, n) for (ll i=k; i<(ll)n; ++i)
#define REP(i, n) rep(i, 0, n)
#define ALL(v) v.begin(),v.end()
#define mp(a, b) make_pair(a, b)
#define fi first
#define se second
template<class T> inline bool chmax(T& a, T b) {if (a<b) {a=b; return true;} return false;}
template<class T> inline bool chmin(T& a, T b) {if (a>b) {a=b; return true;} return false;}
#define DEBUG_VLL(vec) REP(sz, vec.size()) cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

constexpr ll MOD = 1000000007;
constexpr ll HIGHINF = (ll)1e18;
constexpr int INF = 1e9;

int n, m;
V< V<int> > edges;
V<bool> used, from;
V<int> path;
int ngfr, ngto;

bool dfs(int i) {
    path.emplace_back(i);
    if (used[i]) return true;
    from[i] = true;
    used[i] = true;
    for (int e: edges[i]) {
        if (dfs(e)) {
            return true;
        }
    }
    used[i] = false;
    path.pop_back();
    return false;
}

bool dfs2nd(int i) {
    // cout << "i " << i << '\n';
    if (used[i]) return true;
    from[i] = true;
    used[i] = true;
    for (int e: edges[i]) {
        if (i == ngfr && e == ngto) continue;
        if (dfs2nd(e)) {
            return true;
        }
    }
    used[i] = false;
    return false;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> n >> m;
    edges.resize(n);
    for (int i = 0; i < m; i++) {
        int u, v; cin >> u >> v;
        u--, v--;
        edges[u].emplace_back(v);
    }
    used.resize(n, false), from.resize(n, false);
    bool path_exists = false;
    for (int i = 0; i < n; i++) {
        if (from[i]) continue;
        if (dfs(i)) {
            path_exists = true;
            break;
        }
    }

    if (!path_exists) {
        cout << "YES\n";
        return 0;
    }

    int start;
    for (start = 0; start < (int)path.size(); start++) {
        if (path[start] == path.back()) break;
    }

    // start から順に探索
    for (; start < (int)path.size() - 1; start++) {
        ngfr = path[start], ngto = path[start + 1];
        // cout << ngfr << ' ' << ngto << '\n';
        used = V<bool>(n, false);
        from = V<bool>(n, false);
        path_exists = false;
        for (int i = 0; i < n; i++) {
            if (from[i]) continue;
            if (dfs2nd(i)) {
                path_exists = true;
                break;
            }
        }
        if (!path_exists) {
            cout << "YES\n";
            return 0;
        }
    }
    cout << "NO\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long

const int N=3e5+5;
vector<vector<array<int,2>>> v(N);
vector<vector<int>> G(N);
vector<int> vis(N),block(N);
int ct=0;
vector<int> tmp;
void dfs(int node,int p)
{
  vis[node]=1;
  int f=0;
  for(auto i:v[node])
  {
     if(vis[i[0]]==1)
     {
      f=1;
    //  cout<<node<<" "<<i[0]<<endl;
     }
     else
     {
      dfs(i[0],node);
     }
  }
  if(f)
    ct++;

}

signed main() {
 ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);

 int n,m,x,y;
 cin>>n>>m;
 for(int i=1;i<=m;i++)
 {
  cin>>x>>y;
  v[x].push_back({y,i});
 }
 dfs(1,1);
 if(ct<2)
 {
  cout<<"YES";
 }
 else{
  cout<<"NO";
 }
}


/*
 Sarthak Jain
*/
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
const int N=505;
vector<vector<array<int,2>>> v(N);
vector<int> vis(N),dis(N),low(N),block(N);
int cycle,edge;
vector<int> q,tmp;
int tar=-1;

int dfs(int node,int p,int id)
{
  vis[node]=1;
  int f=0;
  for(auto i:v[node])
  {
    if(block[i[1]])
      continue;
    if(vis[i[0]]==1)
    {
      tar=i[0];
      tmp.push_back(i[1]);
    //  cout<<endl<<node<<" * "<<i[0]<<"\n";
      return 1;
    }
    else if(vis[i[0]]==0)
    {
       if(dfs(i[0],node,i[1]))
       f=1;
       //cout<<tar<<endl;
       if(f)
       {
        if(tar!=-1)
        {
          tmp.push_back(i[1]);
          if(node==tar)
            tar=-1;
        }
        break;
       }
    }
  }
  vis[node]=2;
  return f;
}

int detectCycle(int n)
{
  vis=vector<int>(n+1);
  for(int i=1;i<=n;i++)
  {
//    cout<<i<<" = "<<vis[i]<<endl;
    if(vis[i])
      continue;
    tar=-1;
    tmp.clear();
    int chk=dfs(i,-1,-1);
    if(chk)
      return 1;
  }
  return 0;
}

signed main() {
 ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
 int n,m,x,y;
 cin>>n>>m;

 for(int i=1;i<=m;i++)
 {
    cin>>x>>y;
    v[x].push_back({y,i});
 }
 cycle=detectCycle(n);
 if(cycle)
 {
  for(auto i:tmp){
    if(i==-1)
      continue;
//    cout<<endl;
  //  cout<<"block="<<i<<endl;
    block[i]=1;
    if(!detectCycle(n))
    {
      cout<<"YES";
      return 0;
    }
    block[i]=0;
   // cout<<i<<" ";
  }
 }
 else{
  cout<<"YES";
  return 0;
 }
 cout<<"NO";

}


/*
 Sarthak Jain
*/
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
const int N=505;
vector<vector<array<int,2>>> v(N);
vector<int> vis(N),dis(N),low(N),block(N);
int cycle,edge;
vector<int> q,tmp;
int tar=-1;

int dfs(int node,int p,int id)
{
  vis[node]=1;
  int f=0;
  for(auto i:v[node])
  {
    if(block[i[1]])
      continue;
    if(vis[i[0]]==1)
    {
      tar=i[0];
      tmp.push_back(i[1]);
    //  cout<<endl<<node<<" * "<<i[0]<<"\n";
      return 1;
    }
    else if(vis[i[0]]==0)
    {
       f|=dfs(i[0],node,i[1]);
       if(f)
       {
        if(tar!=-1)
        {
          tmp.push_back(i[1]);
          if(node==tar)
            tar=-1;
        }
        break;
       }
    }
  }
  vis[node]=2;
  return f;
}

int detectCycle(int n)
{
  vis=vector<int>(n+1);
  for(int i=1;i<=n;i++)
  {
//    cout<<i<<" = "<<vis[i]<<endl;
    if(vis[i])
      continue;
    if(dfs(i,-1,-1))
      return 1;
  }
  return 0;
}

signed main() {
 ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
 int n,m,x,y;
 cin>>n>>m;

 for(int i=1;i<=m;i++)
 {
    cin>>x>>y;
    v[x].push_back({y,i});
 }
 cycle=detectCycle(n);
 if(cycle)
 {
  for(auto i:tmp){
    if(i==-1)
      continue;
//    cout<<endl;
//    cout<<"block="<<i<<endl;
    block[i]=1;
    if(!detectCycle(n))
    {
      cout<<"YES";
      return 0;
    }
    block[i]=0;
   // cout<<i<<" ";
  }
 }
 else{
  cout<<"YES";
  return 0;
 }
 cout<<"NO";

}


/*
 Sarthak Jain
*/
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
#define int long long
const int N=505;
vector<vector<array<int,2>>> v(N);
vector<int> vis(N),dis(N),low(N),block(N);
int cycle,edge;
vector<int> q,tmp;
int tar=-1;

int dfs(int node,int p,int id)
{
  vis[node]=1;
  int f=0;
  for(auto i:v[node])
  {
    if(block[i[1]])
      continue;
    if(vis[i[0]]==1)
    {
      tar=i[0];
      tmp.push_back(i[1]);
    //  cout<<endl<<node<<" * "<<i[0]<<"\n";
      return 1;
    }
    else if(vis[i[0]]==0)
    {
       int f1=dfs(i[0],node,i[1]);
       if(f1)
       f=1;
       //cout<<tar<<endl;
       if(f)
       {
        if(tar!=-1)
        {
          tmp.push_back(i[1]);
          if(node==tar)
            tar=-1;
        }
        break;
       }
    }
  }
  vis[node]=2;
  return f;
}

int detectCycle(int n)
{
  vis=vector<int>(n+1);
  for(int i=1;i<=n;i++)
  {
//    cout<<i<<" = "<<vis[i]<<endl;
    if(vis[i])
      continue;
    tar=-1;
    tmp.clear();
    int chk=dfs(i,-1,-1);
    if(chk)
      return 1;
  }
  return 0;
}

signed main() {
 ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
 int n,m,x,y;
 cin>>n>>m;

 for(int i=1;i<=m;i++)
 {
    cin>>x>>y;
    v[x].push_back({y,i});
 }
 cycle=detectCycle(n);
 if(cycle)
 {
  for(auto i:tmp){
    if(i==-1)
      continue;
//    cout<<endl;
  //  cout<<"block="<<i<<endl;
    block[i]=1;
    if(!detectCycle(n))
    {
      cout<<"YES";
      return 0;
    }
    block[i]=0;
   // cout<<i<<" ";
  }
 }
 else{
  cout<<"YES";
  return 0;
 }
 cout<<"NO";

}


#include <bits/stdc++.h>
using namespace std;
const int N=505;
vector<vector<array<int,2>>> v(N);
vector<int> vis(N),block(N);
int cycle,edge;
vector<int> q,tmp;
int tar=-1;

int dfs(int node,int p,int id)
{
  vis[node]=1;
  int f=0;
  for(auto i:v[node])
  {
    if(block[i[1]])
      continue;
    if(vis[i[0]]==1)
    {
      tar=i[0];
      tmp.push_back(i[1]);
    //  cout<<endl<<node<<" * "<<i[0]<<"\n";
      return 1;
    }
    else if(vis[i[0]]==0)
    {
       int f1=dfs(i[0],node,i[1]);
       if(f1)
       f=1;
       //cout<<tar<<endl;
       if(f)
       {
        if(tar!=-1)
        {
          tmp.push_back(i[1]);
          if(node==tar)
            tar=-1;
        }
        break;
       }
    }
  }
  vis[node]=2;
  return f;
}

int detectCycle(int n)
{
  vis=vector<int>(n+1);
  for(int i=1;i<=n;i++)
  {
//    cout<<i<<" = "<<vis[i]<<endl;
    if(vis[i])
      continue;
    tar=-1;
    tmp.clear();
    int chk=dfs(i,-1,-1);
    if(chk)
      return 1;
  }
  return 0;
}

signed main() {

 int n,m,x,y;
 cin>>n>>m;

 for(int i=1;i<=m;i++)
 {
    cin>>x>>y;
    v[x].push_back({y,i});
 }
 cycle=detectCycle(n);
 if(cycle)
 {
  for(auto i:tmp){
    if(i==-1)
      continue;
//    cout<<endl;
  //  cout<<"block="<<i<<endl;
    block[i]=1;
    int f1=detectCycle(n);
    if(!f1)
    {
      cout<<"YES";
      return 0;
    }
    block[i]=0;
   // cout<<i<<" ";
  }
 }
 else{
  cout<<"YES";
  return 0;
 }
 cout<<"NO";

}


/*
 Sarthak Jain
*/
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"

const int N=505;
vector<vector<array<int,2>>> v(N);
vector<int> vis(N),dis(N),low(N),block(N);
int cycle,edge;
vector<int> q,tmp,tmp2;
int tar=-1;

int dfs(int node,int p,int id)
{
 // cout<<node<<" "<<p<<" "<<id<<endl;
  vis[node]=1;
  int f=0;
  for(auto i:v[node])
  {
    if(block[i[1]])
      continue;
    if(vis[i[0]]==1)
    {
      tar=i[0];
      tmp.push_back(i[1]);
    //  cout<<endl<<node<<" * "<<i[0]<<"\n";
      return 1;
    }
    else if(vis[i[0]]==0)
    {
       int f1=dfs(i[0],node,i[1]);
       if(f1)
       f=1;
       //cout<<tar<<endl;
       if(f)
       {
        if(tar!=-1)
        {
          tmp.push_back(i[1]);
          if(node==tar)
            tar=-1;
        }
        break;
       }
    }
  }
  vis[node]=2;
  return f;
}

int detectCycle(int n)
{
  vis=vector<int>(n+1);
  for(int i=1;i<=n;i++)
  {
//    cout<<i<<" = "<<vis[i]<<endl;
    if(vis[i])
      continue;
    tar=-1;
    tmp.clear();
    int chk=dfs(i,-1,-1);
    if(chk)
      return 1;
  }
  return 0;
}

signed main() {
 int n,m,x,y;
 cin>>n>>m;

 for(int i=1;i<=m;i++)
 {
    cin>>x>>y;
    v[x].push_back({y,i});
 }
 cycle=detectCycle(n);
 if(cycle)
 {
  tmp2=tmp;
  for(auto i:tmp2){
    if(i==-1)
      continue;
    block[i]=1;
    if(!detectCycle(n))
    {
      cout<<"YES";
      return 0;
    }
    block[i]=0;
   // cout<<i<<" ";
  }
 }
 else{
  cout<<"YES";
  return 0;
 }
 cout<<"NO";

}


#include <bits/stdc++.h>

using namespace std;
#define int long long
vector<int> g[501], rg[501];
vector<int> color, ts;
int col = 1, cycles;

void dfs(int v) {
    color[v] = 1;
    for (auto u:g[v])
        if (!color[u])
            dfs(u);
    ts.push_back(v);
}

void dfs_r(int v) {
    color[v] = col;
    for (auto u:rg[v]) {
        if (color[u] == 0)
            dfs_r(u);
        if(color[u] == col){
            ++cycles;
        }
    }
    color[v] = col + 1;
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    color.resize(n);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g[u].push_back(v);
        rg[v].push_back(u);
    }
    for (int i = 0; i < n; ++i)
        if (color[i] == 0) dfs(i);
    reverse(ts.begin(), ts.end());
    color.assign(n, 0);
    for (auto v:ts) {
        if (color[v] == 0) {
            dfs_r(v);
            col += 2;
        }
    }
    (col == 3 || cycles <= 1) ? cout << "YES" : cout << "NO";
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
vector<multiset<int>> g;
vector<int> color, p;
vector<pair<int,int>> cycle;
int sv, ev;
bool dfs(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(color[u] == 0) {
            p[u] = v;
            if(dfs(u)) return true;
        }
        if(color[u] == 1){
            ev = v;
            sv = u;
            return true;
        }
    }
    color[v] = 2;
    return false;
}
bool dfs2(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(color[u] == 0)
            dfs(u);
        if(color[u] == 1)
            return true;
    }
    color[v] = 2;
    return false;
}
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    color.resize(n);
    g.resize(n);
    p.resize(n, -1);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g[u].insert(v);
    }
    for(int i = 0; i < n; ++i){
        if(color[i] == 0) {
            if (dfs(i)){
                for(int v = ev; v != sv; v = p[v])
                    cycle.emplace_back(p[v], v);
                cycle.emplace_back(ev, sv);
                break;
            }
        }
    }
    if(cycle.size()){
        for(auto &x:cycle){
            bool ok = true;
            g[x.first].erase(x.second);
            color.assign(n, 0);
            for(int i = 0; i < n && ok; ++i){
                if(color[i] == 0)
                    if(dfs2(i))
                        ok = false;
            }
            if(ok){
                cout << "YES";
                return 0;
            }
            g[x.first].insert(x.second);
        }
        cout << "NO";
        return 0;
    }
    cout << "YES";
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
vector<multiset<int>> g;
vector<int> color, p;
vector<pair<int,int>> cycle;
int sv, ev;
bool dfs(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(color[u] == 0) {
            p[u] = v;
            if(dfs(u)) return true;
        }
        if(color[u] == 1){
            ev = v;
            sv = u;
            return true;
        }
    }
    color[v] = 2;
    return false;
}
bool dfs2(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(color[u] == 0)
            dfs(u);
        if(color[u] == 1)
            return true;
    }
    color[v] = 2;
    return false;
}
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    color.resize(n);
    g.resize(n);
    p.resize(n, -1);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g[u].insert(v);
    }
    for(int i = 0; i < n; ++i){
        if(color[i] == 0) {
            if (dfs(i)){
                for(int v = ev; v != sv; v = p[v])
                    cycle.emplace_back(p[v], v);
                cycle.emplace_back(ev, sv);
                break;
            }
        }
    }
    reverse(cycle.begin(), cycle.end());
    if(cycle.size()){
        for(auto &x:cycle){
            bool ok = true;
            g[x.first].erase(x.second);
            color.assign(n, 0);
            for(int i = 0; i < n && ok; ++i){
                if(color[i] == 0)
                    if(dfs2(i))
                        ok = false;
            }
            if(ok){
                cout << "YES";
                return 0;
            }
            g[x.first].insert(x.second);
        }
        cout << "NO";
        return 0;
    }
    cout << "YES";
}


    #include <bits/stdc++.h>

    using namespace std;
    #define int long long
    vector<multiset<int>> g;
    vector<int> color, p;
    vector<pair<int,int>> cycle;
    int sv, ev;
    bool dfs(int v){
        color[v] = 1;
        for(auto u:g[v]){
            if(color[u] == 0) {
                p[u] = v;
                if(dfs(u)) return true;
            }
            if(color[u] == 1){
                ev = v;
                sv = u;
                return true;
            }
        }
        color[v] = 2;
        return false;
    }
    bool dfs2(int v){
        color[v] = 1;
        for(auto u:g[v]){
            if(color[u] == 0)
                if(dfs2(u)) return true;
            if(color[u] == 1)
                return true;
        }
        color[v] = 2;
        return false;
    }
    signed main() {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int n, m;
        cin >> n >> m;
        color.resize(n);
        g.resize(n);
        p.resize(n, -1);
        for (int i = 0; i < m; ++i) {
            int u, v;
            cin >> u >> v;
            --u;
            --v;
            g[u].insert(v);
        }
        for(int i = 0; i < n; ++i){
            if(color[i] == 0) {
                if (dfs(i)){
                    for(int v = ev; v != sv; v = p[v])
                        cycle.emplace_back(p[v], v);
                    cycle.emplace_back(ev, sv);
                    break;
                }
            }
        }
        reverse(cycle.begin(), cycle.end());
        if(cycle.size()){
            for(auto &x:cycle){
                bool ok = true;
                g[x.first].erase(x.second);
                color.assign(n, 0);
                for(int i = 0; i < n && ok; ++i){
                    if(color[i] == 0)
                        if(dfs2(i))
                            ok = false;
                }
                if(ok){
                    cout << "YES";
                    return 0;
                }
                g[x.first].insert(x.second);
            }
            cout << "NO";
            return 0;
        }
        cout << "YES";
    }


#include <bits/stdc++.h>

using namespace std;
#define int long long
vector<multiset<int>> g;
vector<int> color, p;
vector<pair<int, int>> cycle;
int colored = 1;
int sv, ev;

bool dfs(int v) {
    color[v] = colored;
    for (auto u:g[v]) {
        if (color[u] == 0) {
            p[u] = v;
            if (dfs(u)) return true;
        }
        if (color[u] == colored) {
            ev = v;
            sv = u;
            return true;
        }
    }
    color[v] = colored + 1;
    return false;
}

bool dfs2(int v) {
    color[v] = 1;
    for (auto u:g[v]) {
        if (color[u] == 0) {
            if (dfs2(u)) return true;
        }
        if (color[u] == 1)
            return true;
    }
    color[v] = 2;
    return false;
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    color.resize(n);
    g.resize(n);
    p.resize(n, -1);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g[u].insert(v);
    }
    for (int i = 0; i < n; ++i) {
        if (color[i] == 0) {
            if (dfs(i)) {
                for (int v = ev; v != sv; v = p[v])
                    cycle.emplace_back(p[v], v);
                break;
            } else colored += 2;
        }
    }
    cycle.emplace_back(4, 0);
    if (cycle.size()) {
        for (auto &x:cycle) {
            bool ok = true;
            g[x.first].erase(x.second);
            color.assign(n, 0);
            for (int i = 0; i < n && ok; ++i) {
                if (color[i] == 0)
                    if (dfs2(i))
                        ok = false;
            }
            if (ok) {
                cout << "YES";
                return 0;
            } else
                g[x.first].insert(x.second);
        }
        cout << "NO";
        return 0;
    }
    cout << "YES";
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
vector<multiset<int>> g;
vector<int> color, p;
vector<pair<int,int>> cycle;
int sv, ev;
bool dfs(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(color[u] == 0) {
            p[u] = v;
            if(dfs(u)) return true;
        }
        if(color[u] == 1){
            ev = v;
            sv = u;
            return true;
        }
    }
    color[v] = 2;
    return false;
}
bool dfs2(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(color[u] == 0)
            dfs(u);
        if(color[u] == 1)
            return true;
    }
    color[v] = 2;
    return false;
}
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    color.resize(n);
    g.resize(n);
    p.resize(n, -1);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g[u].insert(v);
    }
    for(int i = 0; i < n; ++i){
        if(color[i] == 0) {
            if (dfs(i)){
                for(int v = ev; v != sv; v = p[v])
                    cycle.emplace_back(p[v], v);
                break;
            }
        }
    }
    if(cycle.size()){
        for(auto &x:cycle){
            bool ok = true;
            g[x.first].erase(x.second);
            color.assign(n, 0);
            for(int i = 0; i < n && ok; ++i){
                if(color[i] == 0)
                    if(dfs2(i))
                        ok = false;
            }
            if(ok){
                cout << "YES";
                return 0;
            }
            else
                g[x.first].insert(x.second);
        }
        cout << "NO";
        return 0;
    }
    cout << "YES";
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
vector<int> g[501], rg[501];
vector<int> color, ts;
int col = 0;

void dfs(int v) {
    color[v] = 1;
    for (auto u:g[v])
        if (!color[u])
            dfs(u);
    ts.push_back(v);
}

void dfs_r(int v) {
    color[v] = col;
    for (auto u:rg[v])
        if (color[u] == 0)
            dfs_r(u);
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    color.resize(n);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g[u].push_back(v);
        rg[v].push_back(u);
    }
    for (int i = 0; i < n; ++i)
        if (color[i] == 0) dfs(i);
    reverse(ts.begin(), ts.end());
    color.assign(n, 0);
    for (auto v:ts) {
        if (color[v] == 0) {
            ++col;
            if(col > 1){
                cout << "NO";
                return 0;
            }
            dfs_r(v);
        }
    }
    cout << "YES";
}


#include <bits/stdc++.h>

using namespace std;
#define int long long
vector<vector<int>> g;
vector<int> color, p;
vector<pair<int,int>> cycle;
int sv, ev, v1, v2;
bool dfs(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(color[u] == 0) {
            p[u] = v;
            if(dfs(u)) return true;
        }
        if(color[u] == 1){
            ev = v;
            sv = u;
            return true;
        }
    }
    color[v] = 2;
    return false;
}
bool dfs2(int v){
    color[v] = 1;
    for(auto u:g[v]){
        if(v1 == v && v2 == u) continue;
        if(color[u] == 0) {
            if (dfs2(u)) return true;
        }
        if(color[u] == 1)
            return true;
    }
    color[v] = 2;
    return false;
}
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    color.resize(n);
    g.resize(n);
    p.resize(n, -1);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g[u].push_back(v);
    }
    for(int i = 0; i < n; ++i){
        if(color[i] == 0) {
            if (dfs(i)){
                for(int v = ev; v != sv; v = p[v])
                    cycle.emplace_back(p[v], v);
                cycle.emplace_back(ev, sv);
                break;
            }
        }
    }
    reverse(cycle.begin(), cycle.end());
    if(cycle.size()){
        for(auto &x:cycle){
            bool ok = true;
            v1 = x.first; v2 = x.second;
            color.assign(n, 0);
            for(int i = 0; i < n && ok; ++i){
                if(color[i] == 0)
                    if(dfs2(i))
                        ok = false;
            }
            if(ok){
                cout << "YES";
                return 0;
            }
        }
        cout << "NO";
        return 0;
    }
    cout << "YES";
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <random>
#include <stack>
#include <iomanip>
#include <ctime>
#include <limits.h>
#include <chrono>

#define fast                          \
    ios_base::sync_with_stdio(false); \
    cin.tie(0);                       \
    cout.tie(0);

#define ll long long
#define ld long double

#define pb push_back
#define ins insert
#define er erase

#define f(i, a, b) for (int i = a; i < b; ++i)
#define rf(i, a, b) for (int i = a; i >= b; --i)
#define cmax(a, b) a = max(a, b)
#define cmin(a, b) a = min(a, b)
#define cadd(a, b) a = add(a, b)
#define csub(a, b) a = subt(a, b)
#define cmul(a, b) a = mult(a, b)
#define mem(a, b) memset(a, b, sizeof(a))

#define vi vector<int>
#define vst vector<string>
#define vpii vector<pii>
#define sz(a) (int)(a).size()

#define all(v) v.begin(), v.end()
#define lb lower_bound
#define ub upper_bound
#define mxe max_element
#define mne min_element

#define srt(v) sort(all(v))
#define rsrt(v) sort(v.rbegin(), v.rend())

#define pii pair<int, int>
#define ff first
#define ss second

#define bs bitset
#define bpc(a) __builtin_popcount(a)
#define prec(a) fixed << setprecision(a)

#define mii map<int, int>
#define umii unordered_map<int, int>

#define si set<int>
#define usi unordered_set<int>
#define spii set<pii>

#define dbg(a, st, end)                   \
    f(i, st, end + 1) cerr << a[i] << sp; \
    cerr << nl;
#define pnt(a, st, end)                   \
    f(i, st, end + 1) cout << a[i] << sp; \
    cout << nl;
#define dbgc(a)          \
    for (auto y : a)     \
        cerr << y << sp; \
    cerr << nl;
#define dbgm(a)                            \
    for (auto y : a)                       \
        cerr << y.ff << "," << y.ss << sp; \
    cerr << nl;

#define trace(a) cerr << a << nl;
#define trace2(a, b) cerr << a << sp << b << nl;
#define trace3(a, b, c) cerr << a << sp << b << sp << c << nl;
#define trace4(a, b, c, d) cerr << a << sp << b << sp << c << sp << d << nl;

#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) ((a)*1ll * (b)) / gcd(a, b)

#define nl "\n"
#define sp " "

using namespace std;
using namespace std::chrono;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<pii, null_type, less<pii>, rb_tree_tag, tree_order_statistics_node_update>
#define ok order_of_key
#define fo find_by_order

ll md = 1000000007;
ld pi = 3.141592653;
//ll md = 998244353;

ll pw(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m);
        m = (m * m);
        b /= 2;
    }
    return c;
}

ll pwmd(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m) % md;
        m = (m * m) % md;
        b /= 2;
    }
    return c;
}

ll modinv(ll n)
{
    return pwmd(n, md - 2);
}

ll my_ceil(ll a, ll b)
{
    if (a % b == 0)
        return a / b;
    return a / b + 1;
}

ll nc2(ll n)
{
    return (1ll * n * (n - 1)) / 2;
}

ll nsum(ll n)
{
    return (1ll * n * (n + 1)) / 2;
}

int my_log(ll n, int b)
{
    ll i = 1;
    int ans = 0;
    while (1)
    {
        if (i > n / b)
            break;
        i *= b;
        ans++;
    }
    return ans;
}

inline int nc()
{
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}

inline int read()
{
    int ret = 0;
    bool f = 0;
    char ch = nc();
    while (ch > '9' || ch < '0')
        f ^= ch == '-', ch = nc();
    while (ch <= '9' && ch >= '0')
        ret = ret * 10 + ch - '0', ch = nc();
    return f ? -ret : ret;
}

inline int randint(int l, int r)
{
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<int>(l, r)(rng);
}

inline ll randll(ll l, ll r)
{
    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<ll>(l, r)(rng);
}

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

inline ll add(ll a, ll b) { return (((a >= md) ? a % md : a) + ((b >= md) ? b % md : b) + md) % md; }
inline ll subt(ll a, ll b) { return (a - b + md) % md; }
inline ll mult(ll a, ll b) { return (1ll * ((a >= md) ? a % md : a) * ((b >= md) ? b % md : b)) % md; }

inline int manhatten(pii p1, pii p2) { return abs(p1.ff - p2.ff) + abs(p1.ss - p2.ss); }

inline bool kthbit(ll n, int k) { return (n >> k) & 1; }
inline ll setkthbit(ll n, int k) { return n | (1ll << k); }
inline ll unsetkthbit(ll n, int k) { return n & ~(1ll << k); }
inline ll flipkthbit(ll n, int k) { return n ^ (1ll << k); }

//#define int long long //UNCOMMENT IF NEEDED
#define UNAGI

/*
    You have to stop the Q-Tip when there's resistance!
                                - Chandler Bing, S02E01
*/

const int N = 505;

si adj[N], radj[N];
int n, vis[N], alive[N];

bool cycle(int node)
{
    vis[node] = alive[node] = 1;
    for (auto y : adj[node])
    {
        if (vis[y] && alive[y])
            return 1;
        if (vis[y])
            continue;
        if (cycle(y))
            return 1;
    }
    alive[node] = 0;
    return 0;
}

bool checkCycle()
{
    mem(vis, 0);
    bool yes = 0;
    f(i, 1, 1 + n) if (!vis[i]) yes |= cycle(i);
    return yes;
}

bool solve()
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    spii nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], i});
    vpii candidates;
    while (!nodes.empty())
    {
        pii p = *nodes.begin();
        if (p.ff)
        {
            for (auto y : nodes)
                if (y.ff == p.ff)
                    candidates.pb({y.ss, *radj[y.ss].begin()});
            break;
        }
        nodes.er(p);
        for (auto y : adj[p.ss])
        {
            nodes.er({indeg[y], y});
            indeg[y]--;
            radj[y].er(p.ss);
            nodes.ins({indeg[y], y});
        }
    } //dbgm(candidates);
    bool no = 1;
    for (auto y : candidates)
    {
        adj[y.ss].er(y.ff);
        no &= checkCycle();
        adj[y.ss].ins(y.ff);
        if (!no)
            break;
    }
    no ^= 1;
    return no;
}

int32_t main()
{
    fast;

#ifndef UNAGI
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int h, e, m, y, k;
    int x, q, l, r, c;

    string s, t;

    auto start = high_resolution_clock::now();

    int tcnt = 0;

    int tests = 1;
    //pre();
    //cin >> tests;

    while (tests--)
    {
        //cout << "Case #" << ++tcnt << ": ";

        cin >> n >> m;
        while (m--)
            cin >> l >> r, adj[l].ins(r), radj[r].ins(l);
        if (!checkCycle())
            cout << "YES";
        else
            cout << (solve() ? "YES" : "NO");

        // RESTORE SEGTREE SIZE
    }
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cerr << "Time taken: "
         << duration.count() / 1000000.0 << "seconds" << nl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <random>
#include <stack>
#include <iomanip>
#include <ctime>
#include <limits.h>
#include <chrono>

#define fast                          \
    ios_base::sync_with_stdio(false); \
    cin.tie(0);                       \
    cout.tie(0);

#define ll long long
#define ld long double

#define pb push_back
#define ins insert
#define er erase

#define f(i, a, b) for (int i = a; i < b; ++i)
#define rf(i, a, b) for (int i = a; i >= b; --i)
#define cmax(a, b) a = max(a, b)
#define cmin(a, b) a = min(a, b)
#define cadd(a, b) a = add(a, b)
#define csub(a, b) a = subt(a, b)
#define cmul(a, b) a = mult(a, b)
#define mem(a, b) memset(a, b, sizeof(a))

#define vi vector<int>
#define vst vector<string>
#define vpii vector<pii>
#define sz(a) (int)(a).size()

#define all(v) v.begin(), v.end()
#define lb lower_bound
#define ub upper_bound
#define mxe max_element
#define mne min_element

#define srt(v) sort(all(v))
#define rsrt(v) sort(v.rbegin(), v.rend())

#define pii pair<int, int>
#define ff first
#define ss second

#define bs bitset
#define bpc(a) __builtin_popcount(a)
#define prec(a) fixed << setprecision(a)

#define mii map<int, int>
#define umii unordered_map<int, int>

#define si set<int>
#define usi unordered_set<int>
#define spii set<pii>

#define dbg(a, st, end)                   \
    f(i, st, end + 1) cerr << a[i] << sp; \
    cerr << nl;
#define pnt(a, st, end)                   \
    f(i, st, end + 1) cout << a[i] << sp; \
    cout << nl;
#define dbgc(a)          \
    for (auto y : a)     \
        cerr << y << sp; \
    cerr << nl;
#define dbgm(a)                            \
    for (auto y : a)                       \
        cerr << y.ff << "," << y.ss << sp; \
    cerr << nl;

#define trace(a) cerr << a << nl;
#define trace2(a, b) cerr << a << sp << b << nl;
#define trace3(a, b, c) cerr << a << sp << b << sp << c << nl;
#define trace4(a, b, c, d) cerr << a << sp << b << sp << c << sp << d << nl;

#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) ((a)*1ll * (b)) / gcd(a, b)

#define nl "\n"
#define sp " "

using namespace std;
using namespace std::chrono;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<pii, null_type, less<pii>, rb_tree_tag, tree_order_statistics_node_update>
#define ok order_of_key
#define fo find_by_order

ll md = 1000000007;
ld pi = 3.141592653;
//ll md = 998244353;

ll pw(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m);
        m = (m * m);
        b /= 2;
    }
    return c;
}

ll pwmd(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m) % md;
        m = (m * m) % md;
        b /= 2;
    }
    return c;
}

ll modinv(ll n)
{
    return pwmd(n, md - 2);
}

ll my_ceil(ll a, ll b)
{
    if (a % b == 0)
        return a / b;
    return a / b + 1;
}

ll nc2(ll n)
{
    return (1ll * n * (n - 1)) / 2;
}

ll nsum(ll n)
{
    return (1ll * n * (n + 1)) / 2;
}

int my_log(ll n, int b)
{
    ll i = 1;
    int ans = 0;
    while (1)
    {
        if (i > n / b)
            break;
        i *= b;
        ans++;
    }
    return ans;
}

inline int nc()
{
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}

inline int read()
{
    int ret = 0;
    bool f = 0;
    char ch = nc();
    while (ch > '9' || ch < '0')
        f ^= ch == '-', ch = nc();
    while (ch <= '9' && ch >= '0')
        ret = ret * 10 + ch - '0', ch = nc();
    return f ? -ret : ret;
}

inline int randint(int l, int r)
{
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<int>(l, r)(rng);
}

inline ll randll(ll l, ll r)
{
    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<ll>(l, r)(rng);
}

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

inline ll add(ll a, ll b) { return (((a >= md) ? a % md : a) + ((b >= md) ? b % md : b) + md) % md; }
inline ll subt(ll a, ll b) { return (a - b + md) % md; }
inline ll mult(ll a, ll b) { return (1ll * ((a >= md) ? a % md : a) * ((b >= md) ? b % md : b)) % md; }

inline int manhatten(pii p1, pii p2) { return abs(p1.ff - p2.ff) + abs(p1.ss - p2.ss); }

inline bool kthbit(ll n, int k) { return (n >> k) & 1; }
inline ll setkthbit(ll n, int k) { return n | (1ll << k); }
inline ll unsetkthbit(ll n, int k) { return n & ~(1ll << k); }
inline ll flipkthbit(ll n, int k) { return n ^ (1ll << k); }

#define int long long //UNCOMMENT IF NEEDED
#define UNAGI

/*
    You have to stop the Q-Tip when there's resistance!
                                - Chandler Bing, S02E01
*/

const int N = 505;

vi adj[N];
int n, vis[N], alive[N];

bool topo(int spNode)
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    set<pair<bool, pii>> nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], {i != spNode, i}});
    int surplus = 0;
    while (!nodes.empty())
    {
        auto p = *nodes.begin();
        surplus += p.ff; //trace(p.ss.ss);
        nodes.er(nodes.begin());
        for (auto y : adj[p.ss.ss])
        {
            if (nodes.find({indeg[y], {y != spNode, y}}) == nodes.end())
                continue;
            nodes.er({indeg[y], {y != spNode, y}});
            indeg[y]--;
            nodes.ins({indeg[y], {y != spNode, y}});
        }
    }
    //trace2(spNode,surplus);
    return surplus < 2;
}

bool solve()
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    spii nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], i});
    vi candidates;
    while (!nodes.empty())
    {
        pii p = *nodes.begin();
        if (p.ff)
        {
            for (auto y : nodes)
                if (y.ff == p.ff)
                    candidates.pb(y.ss);
            break;
        }
        nodes.er(p);
        for (auto y : adj[p.ss])
        {
            nodes.er({indeg[y], y});
            indeg[y]--;
            nodes.ins({indeg[y], y});
        }
    } //dbgc(candidates);
    bool ans = 0;
    for (auto y : candidates)
        ans |= topo(y);
    return ans;
}

bool cycle(int node)
{
    vis[node] = alive[node] = 1;
    for (auto y : adj[node])
    {
        if (vis[y] && alive[y])
            return 1;
        if (vis[y])
            continue;
        if (cycle(y))
            return 1;
    }
    alive[node] = 0;
    return 0;
}

bool checkCycle()
{
    bool yes = 0;
    f(i, 1, 1 + n) if (!vis[i]) yes |= cycle(i);
    return yes;
}

int32_t main()
{
    fast;

#ifndef UNAGI
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int h, e, m, y, k;
    int x, q, l, r, c;

    string s, t;

    auto start = high_resolution_clock::now();

    int tcnt = 0;

    int tests = 1;
    //pre();
    //cin >> tests;

    while (tests--)
    {
        //cout << "Case #" << ++tcnt << ": ";

        cin >> n >> m;
        while (m--)
            cin >> l >> r, adj[l].pb(r);
        if (!checkCycle())
            cout << "YES";
        else
            cout << (solve() ? "YES" : "NO");

        // RESTORE SEGTREE SIZE
    }
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cerr << "Time taken: "
         << duration.count() / 1000000.0 << "seconds" << nl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <random>
#include <stack>
#include <iomanip>
#include <ctime>
#include <limits.h>
#include <chrono>

#define fast                          \
    ios_base::sync_with_stdio(false); \
    cin.tie(0);                       \
    cout.tie(0);

#define ll long long
#define ld long double

#define pb push_back
#define ins insert
#define er erase

#define f(i, a, b) for (int i = a; i < b; ++i)
#define rf(i, a, b) for (int i = a; i >= b; --i)
#define cmax(a, b) a = max(a, b)
#define cmin(a, b) a = min(a, b)
#define cadd(a, b) a = add(a, b)
#define csub(a, b) a = subt(a, b)
#define cmul(a, b) a = mult(a, b)
#define mem(a, b) memset(a, b, sizeof(a))

#define vi vector<int>
#define vst vector<string>
#define vpii vector<pii>
#define sz(a) (int)(a).size()

#define all(v) v.begin(), v.end()
#define lb lower_bound
#define ub upper_bound
#define mxe max_element
#define mne min_element

#define srt(v) sort(all(v))
#define rsrt(v) sort(v.rbegin(), v.rend())

#define pii pair<int, int>
#define ff first
#define ss second

#define bs bitset
#define bpc(a) __builtin_popcount(a)
#define prec(a) fixed << setprecision(a)

#define mii map<int, int>
#define umii unordered_map<int, int>

#define si set<int>
#define usi unordered_set<int>
#define spii set<pii>

#define dbg(a, st, end)                   \
    f(i, st, end + 1) cerr << a[i] << sp; \
    cerr << nl;
#define pnt(a, st, end)                   \
    f(i, st, end + 1) cout << a[i] << sp; \
    cout << nl;
#define dbgc(a)          \
    for (auto y : a)     \
        cerr << y << sp; \
    cerr << nl;
#define dbgm(a)                            \
    for (auto y : a)                       \
        cerr << y.ff << "," << y.ss << sp; \
    cerr << nl;

#define trace(a) cerr << a << nl;
#define trace2(a, b) cerr << a << sp << b << nl;
#define trace3(a, b, c) cerr << a << sp << b << sp << c << nl;
#define trace4(a, b, c, d) cerr << a << sp << b << sp << c << sp << d << nl;

#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) ((a)*1ll * (b)) / gcd(a, b)

#define nl "\n"
#define sp " "

using namespace std;
using namespace std::chrono;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<pii, null_type, less<pii>, rb_tree_tag, tree_order_statistics_node_update>
#define ok order_of_key
#define fo find_by_order

ll md = 1000000007;
ld pi = 3.141592653;
//ll md = 998244353;

ll pw(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m);
        m = (m * m);
        b /= 2;
    }
    return c;
}

ll pwmd(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m) % md;
        m = (m * m) % md;
        b /= 2;
    }
    return c;
}

ll modinv(ll n)
{
    return pwmd(n, md - 2);
}

ll my_ceil(ll a, ll b)
{
    if (a % b == 0)
        return a / b;
    return a / b + 1;
}

ll nc2(ll n)
{
    return (1ll * n * (n - 1)) / 2;
}

ll nsum(ll n)
{
    return (1ll * n * (n + 1)) / 2;
}

int my_log(ll n, int b)
{
    ll i = 1;
    int ans = 0;
    while (1)
    {
        if (i > n / b)
            break;
        i *= b;
        ans++;
    }
    return ans;
}

inline int nc()
{
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}

inline int read()
{
    int ret = 0;
    bool f = 0;
    char ch = nc();
    while (ch > '9' || ch < '0')
        f ^= ch == '-', ch = nc();
    while (ch <= '9' && ch >= '0')
        ret = ret * 10 + ch - '0', ch = nc();
    return f ? -ret : ret;
}

inline int randint(int l, int r)
{
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<int>(l, r)(rng);
}

inline ll randll(ll l, ll r)
{
    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<ll>(l, r)(rng);
}

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

inline ll add(ll a, ll b) { return (((a >= md) ? a % md : a) + ((b >= md) ? b % md : b) + md) % md; }
inline ll subt(ll a, ll b) { return (a - b + md) % md; }
inline ll mult(ll a, ll b) { return (1ll * ((a >= md) ? a % md : a) * ((b >= md) ? b % md : b)) % md; }

inline int manhatten(pii p1, pii p2) { return abs(p1.ff - p2.ff) + abs(p1.ss - p2.ss); }

inline bool kthbit(ll n, int k) { return (n >> k) & 1; }
inline ll setkthbit(ll n, int k) { return n | (1ll << k); }
inline ll unsetkthbit(ll n, int k) { return n & ~(1ll << k); }
inline ll flipkthbit(ll n, int k) { return n ^ (1ll << k); }

//#define int long long //UNCOMMENT IF NEEDED
#define UNAGI

/*
    You have to stop the Q-Tip when there's resistance!
                                - Chandler Bing, S02E01
*/

const int N = 505;

vi adj[N];
int n, vis[N], alive[N];

bool topo(int spNode)
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    set<pair<bool, pii>> nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], {i != spNode, i}});
    int surplus = 0;
    while (!nodes.empty())
    {
        auto p = *nodes.begin();
        surplus += p.ff; //trace(p.ss.ss);
        if (surplus > 1)
            break;
        nodes.er(nodes.begin());
        for (auto y : adj[p.ss.ss])
        {
            if (nodes.find({indeg[y], {y != spNode, y}}) == nodes.end())
                continue;
            nodes.er({indeg[y], {y != spNode, y}});
            indeg[y]--;
            nodes.ins({indeg[y], {y != spNode, y}});
        }
    }
    //trace2(spNode,surplus);
    return surplus < 2;
}

bool solve()
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    spii nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], i});
    vi candidates;
    while (!nodes.empty())
    {
        pii p = *nodes.begin();
        if (p.ff)
        {
            for (auto y : nodes)
                if (y.ff == p.ff)
                    candidates.pb(y.ss);
            break;
        }
        nodes.er(p);
        for (auto y : adj[p.ss])
        {
            nodes.er({indeg[y], y});
            indeg[y]--;
            nodes.ins({indeg[y], y});
        }
    } //dbgc(candidates);
    bool ans = 0;
    for (auto y : candidates)
    {
        ans |= topo(y);
        if (ans)
            break;
    }
    return ans;
}

bool cycle(int node)
{
    vis[node] = alive[node] = 1;
    for (auto y : adj[node])
    {
        if (vis[y] && alive[y])
            return 1;
        if (vis[y])
            continue;
        if (cycle(y))
            return 1;
    }
    alive[node] = 0;
    return 0;
}

bool checkCycle()
{
    bool yes = 0;
    f(i, 1, 1 + n) if (!vis[i]) yes |= cycle(i);
    return yes;
}

int32_t main()
{
    fast;

#ifndef UNAGI
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int h, e, m, y, k;
    int x, q, l, r, c;

    string s, t;

    auto start = high_resolution_clock::now();

    int tcnt = 0;

    int tests = 1;
    //pre();
    //cin >> tests;

    while (tests--)
    {
        //cout << "Case #" << ++tcnt << ": ";

        cin >> n >> m;
        while (m--)
            cin >> l >> r, adj[l].pb(r);
        if (!checkCycle())
            cout << "YES";
        else
            cout << (solve() ? "YES" : "NO");

        // RESTORE SEGTREE SIZE
    }
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cerr << "Time taken: "
         << duration.count() / 1000000.0 << "seconds" << nl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <random>
#include <stack>
#include <iomanip>
#include <ctime>
#include <limits.h>
#include <chrono>

#define fast                          \
    ios_base::sync_with_stdio(false); \
    cin.tie(0);                       \
    cout.tie(0);

#define ll long long
#define ld long double

#define pb push_back
#define ins insert
#define er erase

#define f(i, a, b) for (int i = a; i < b; ++i)
#define rf(i, a, b) for (int i = a; i >= b; --i)
#define cmax(a, b) a = max(a, b)
#define cmin(a, b) a = min(a, b)
#define cadd(a, b) a = add(a, b)
#define csub(a, b) a = subt(a, b)
#define cmul(a, b) a = mult(a, b)
#define mem(a, b) memset(a, b, sizeof(a))

#define vi vector<int>
#define vst vector<string>
#define vpii vector<pii>
#define sz(a) (int)(a).size()

#define all(v) v.begin(), v.end()
#define lb lower_bound
#define ub upper_bound
#define mxe max_element
#define mne min_element

#define srt(v) sort(all(v))
#define rsrt(v) sort(v.rbegin(), v.rend())

#define pii pair<int, int>
#define ff first
#define ss second

#define bs bitset
#define bpc(a) __builtin_popcount(a)
#define prec(a) fixed << setprecision(a)

#define mii map<int, int>
#define umii unordered_map<int, int>

#define si set<int>
#define usi unordered_set<int>
#define spii set<pii>

#define dbg(a, st, end)                   \
    f(i, st, end + 1) cerr << a[i] << sp; \
    cerr << nl;
#define pnt(a, st, end)                   \
    f(i, st, end + 1) cout << a[i] << sp; \
    cout << nl;
#define dbgc(a)          \
    for (auto y : a)     \
        cerr << y << sp; \
    cerr << nl;
#define dbgm(a)                            \
    for (auto y : a)                       \
        cerr << y.ff << "," << y.ss << sp; \
    cerr << nl;

#define trace(a) cerr << a << nl;
#define trace2(a, b) cerr << a << sp << b << nl;
#define trace3(a, b, c) cerr << a << sp << b << sp << c << nl;
#define trace4(a, b, c, d) cerr << a << sp << b << sp << c << sp << d << nl;

#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) ((a)*1ll * (b)) / gcd(a, b)

#define nl "\n"
#define sp " "

using namespace std;
using namespace std::chrono;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<pii, null_type, less<pii>, rb_tree_tag, tree_order_statistics_node_update>
#define ok order_of_key
#define fo find_by_order

ll md = 1000000007;
ld pi = 3.141592653;
//ll md = 998244353;

ll pw(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m);
        m = (m * m);
        b /= 2;
    }
    return c;
}

ll pwmd(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m) % md;
        m = (m * m) % md;
        b /= 2;
    }
    return c;
}

ll modinv(ll n)
{
    return pwmd(n, md - 2);
}

ll my_ceil(ll a, ll b)
{
    if (a % b == 0)
        return a / b;
    return a / b + 1;
}

ll nc2(ll n)
{
    return (1ll * n * (n - 1)) / 2;
}

ll nsum(ll n)
{
    return (1ll * n * (n + 1)) / 2;
}

int my_log(ll n, int b)
{
    ll i = 1;
    int ans = 0;
    while (1)
    {
        if (i > n / b)
            break;
        i *= b;
        ans++;
    }
    return ans;
}

inline int nc()
{
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}

inline int read()
{
    int ret = 0;
    bool f = 0;
    char ch = nc();
    while (ch > '9' || ch < '0')
        f ^= ch == '-', ch = nc();
    while (ch <= '9' && ch >= '0')
        ret = ret * 10 + ch - '0', ch = nc();
    return f ? -ret : ret;
}

inline int randint(int l, int r)
{
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<int>(l, r)(rng);
}

inline ll randll(ll l, ll r)
{
    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<ll>(l, r)(rng);
}

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

inline ll add(ll a, ll b) { return (((a >= md) ? a % md : a) + ((b >= md) ? b % md : b) + md) % md; }
inline ll subt(ll a, ll b) { return (a - b + md) % md; }
inline ll mult(ll a, ll b) { return (1ll * ((a >= md) ? a % md : a) * ((b >= md) ? b % md : b)) % md; }

inline int manhatten(pii p1, pii p2) { return abs(p1.ff - p2.ff) + abs(p1.ss - p2.ss); }

inline bool kthbit(ll n, int k) { return (n >> k) & 1; }
inline ll setkthbit(ll n, int k) { return n | (1ll << k); }
inline ll unsetkthbit(ll n, int k) { return n & ~(1ll << k); }
inline ll flipkthbit(ll n, int k) { return n ^ (1ll << k); }

//#define int long long //UNCOMMENT IF NEEDED
#define UNAGI

/*
    You have to stop the Q-Tip when there's resistance!
                                - Chandler Bing, S02E01
*/

const int N = 505;

si adj[N];
vi radj[N];
int n, vis[N], alive[N];

bool cycle(int node)
{
    vis[node] = alive[node] = 1;
    for (auto y : adj[node])
    {
        if (vis[y] && alive[y])
            return 1;
        if (vis[y])
            continue;
        if (cycle(y))
            return 1;
    }
    alive[node] = 0;
    return 0;
}

bool checkCycle()
{
    mem(vis, 0);
    bool yes = 0;
    f(i, 1, 1 + n) if (!vis[i]) yes |= cycle(i);
    return yes;
}

bool solve()
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    spii nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], i});
    vpii candidates;
    while (!nodes.empty())
    {
        pii p = *nodes.begin();
        if (p.ff)
        {
            for (auto y : nodes)
                if (y.ff == p.ff)
                    candidates.pb({y.ss, radj[y.ss][0]});
            break;
        }
        nodes.er(p);
        for (auto y : adj[p.ss])
        {
            nodes.er({indeg[y], y});
            indeg[y]--;
            nodes.ins({indeg[y], y});
        }
    } //dbgm(candidates);
    bool no = 1;
    for (auto y : candidates)
    {
        adj[y.ss].er(y.ff);
        no &= checkCycle();
        adj[y.ss].ins(y.ff);
        if (!no)
            break;
    }
    no ^= 1;
    return no;
}

int32_t main()
{
    fast;

#ifndef UNAGI
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int h, e, m, y, k;
    int x, q, l, r, c;

    string s, t;

    auto start = high_resolution_clock::now();

    int tcnt = 0;

    int tests = 1;
    //pre();
    //cin >> tests;

    while (tests--)
    {
        //cout << "Case #" << ++tcnt << ": ";

        cin >> n >> m;
        while (m--)
            cin >> l >> r, adj[l].ins(r), radj[r].pb(l);
        if (!checkCycle())
            cout << "YES";
        else
            cout << (solve() ? "YES" : "NO");

        // RESTORE SEGTREE SIZE
    }
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cerr << "Time taken: "
         << duration.count() / 1000000.0 << "seconds" << nl;
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <random>
#include <stack>
#include <iomanip>
#include <ctime>
#include <limits.h>
#include <chrono>

#define fast                          \
    ios_base::sync_with_stdio(false); \
    cin.tie(0);                       \
    cout.tie(0);

#define ll long long
#define ld long double

#define pb push_back
#define ins insert
#define er erase

#define f(i, a, b) for (int i = a; i < b; ++i)
#define rf(i, a, b) for (int i = a; i >= b; --i)
#define cmax(a, b) a = max(a, b)
#define cmin(a, b) a = min(a, b)
#define cadd(a, b) a = add(a, b)
#define csub(a, b) a = subt(a, b)
#define cmul(a, b) a = mult(a, b)
#define mem(a, b) memset(a, b, sizeof(a))

#define vi vector<int>
#define vst vector<string>
#define vpii vector<pii>
#define sz(a) (int)(a).size()

#define all(v) v.begin(), v.end()
#define lb lower_bound
#define ub upper_bound
#define mxe max_element
#define mne min_element

#define srt(v) sort(all(v))
#define rsrt(v) sort(v.rbegin(), v.rend())

#define pii pair<int, int>
#define ff first
#define ss second

#define bs bitset
#define bpc(a) __builtin_popcount(a)
#define prec(a) fixed << setprecision(a)

#define mii map<int, int>
#define umii unordered_map<int, int>

#define si set<int>
#define usi unordered_set<int>
#define spii set<pii>

#define dbg(a, st, end)                   \
    f(i, st, end + 1) cerr << a[i] << sp; \
    cerr << nl;
#define pnt(a, st, end)                   \
    f(i, st, end + 1) cout << a[i] << sp; \
    cout << nl;
#define dbgc(a)          \
    for (auto y : a)     \
        cerr << y << sp; \
    cerr << nl;
#define dbgm(a)                            \
    for (auto y : a)                       \
        cerr << y.ff << "," << y.ss << sp; \
    cerr << nl;

#define trace(a) cerr << a << nl;
#define trace2(a, b) cerr << a << sp << b << nl;
#define trace3(a, b, c) cerr << a << sp << b << sp << c << nl;
#define trace4(a, b, c, d) cerr << a << sp << b << sp << c << sp << d << nl;

#define gcd(a, b) __gcd(a, b)
#define lcm(a, b) ((a)*1ll * (b)) / gcd(a, b)

#define nl "\n"
#define sp " "

using namespace std;
using namespace std::chrono;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<pii, null_type, less<pii>, rb_tree_tag, tree_order_statistics_node_update>
#define ok order_of_key
#define fo find_by_order

ll md = 1000000007;
ld pi = 3.141592653;
//ll md = 998244353;

ll pw(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m);
        m = (m * m);
        b /= 2;
    }
    return c;
}

ll pwmd(ll a, ll b)
{
    ll c = 1, m = a;
    while (b)
    {
        if (b & 1)
            c = (c * m) % md;
        m = (m * m) % md;
        b /= 2;
    }
    return c;
}

ll modinv(ll n)
{
    return pwmd(n, md - 2);
}

ll my_ceil(ll a, ll b)
{
    if (a % b == 0)
        return a / b;
    return a / b + 1;
}

ll nc2(ll n)
{
    return (1ll * n * (n - 1)) / 2;
}

ll nsum(ll n)
{
    return (1ll * n * (n + 1)) / 2;
}

int my_log(ll n, int b)
{
    ll i = 1;
    int ans = 0;
    while (1)
    {
        if (i > n / b)
            break;
        i *= b;
        ans++;
    }
    return ans;
}

inline int nc()
{
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}

inline int read()
{
    int ret = 0;
    bool f = 0;
    char ch = nc();
    while (ch > '9' || ch < '0')
        f ^= ch == '-', ch = nc();
    while (ch <= '9' && ch >= '0')
        ret = ret * 10 + ch - '0', ch = nc();
    return f ? -ret : ret;
}

inline int randint(int l, int r)
{
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<int>(l, r)(rng);
}

inline ll randll(ll l, ll r)
{
    mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
    return uniform_int_distribution<ll>(l, r)(rng);
}

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

inline ll add(ll a, ll b) { return (((a >= md) ? a % md : a) + ((b >= md) ? b % md : b) + md) % md; }
inline ll subt(ll a, ll b) { return (a - b + md) % md; }
inline ll mult(ll a, ll b) { return (1ll * ((a >= md) ? a % md : a) * ((b >= md) ? b % md : b)) % md; }

inline int manhatten(pii p1, pii p2) { return abs(p1.ff - p2.ff) + abs(p1.ss - p2.ss); }

inline bool kthbit(ll n, int k) { return (n >> k) & 1; }
inline ll setkthbit(ll n, int k) { return n | (1ll << k); }
inline ll unsetkthbit(ll n, int k) { return n & ~(1ll << k); }
inline ll flipkthbit(ll n, int k) { return n ^ (1ll << k); }

#define int long long //UNCOMMENT IF NEEDED
#define UNAGI

/*
    You have to stop the Q-Tip when there's resistance!
                                - Chandler Bing, S02E01
*/

const int N = 505;

vi adj[N];
int n, vis[N], alive[N];

bool topo(int spNode)
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    set<pair<bool, pii>> nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], {i != spNode, i}});
    int surplus = 0;
    while (!nodes.empty())
    {
        auto p = *nodes.begin();
        surplus += p.ff; //trace(p.ss.ss);
        nodes.er(nodes.begin());
        for (auto y : adj[p.ss.ss])
        {
            if (nodes.find({indeg[y], {y != spNode, y}}) == nodes.end())
                continue;
            nodes.er({indeg[y], {y != spNode, y}});
            indeg[y]--;
            nodes.ins({indeg[y], {y != spNode, y}});
        }
    }
    //trace2(spNode,surplus);
    return surplus < 2;
}

bool solve()
{
    int indeg[n + 1];
    mem(indeg, 0);
    f(i, 1, 1 + n) for (auto y : adj[i]) indeg[y]++;
    //dbgc(indeg);
    spii nodes;
    f(i, 1, 1 + n) nodes.ins({indeg[i], i});
    vi candidates;
    while (!nodes.empty())
    {
        pii p = *nodes.begin();
        if (p.ff)
        {
            for (auto y : nodes)
                if (y.ff == p.ff)
                    candidates.pb(y.ss);
            break;
        }
        nodes.er(p);
        for (auto y : adj[p.ss])
        {
            nodes.er({indeg[y], y});
            indeg[y]--;
            nodes.ins({indeg[y], y});
        }
    } //dbgc(candidates);
    bool ans = 0;
    for (auto y : candidates)
        ans |= topo(y);
    return ans;
}

bool cycle(int node)
{
    vis[node] = alive[node] = 1;
    for (auto y : adj[node])
    {
        if (vis[y] && alive[y])
            return 1;
        if (vis[y])
            continue;
        if (cycle(y))
            return 1;
    }
    alive[node] = 0;
    return 0;
}

bool checkCycle()
{
    bool yes = 0;
    f(i, 1, 1 + n) if (!vis[i]) yes |= cycle(i);
    return yes;
}

int32_t main()
{
    fast;

#ifndef UNAGI
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    int h, e, m, y, k;
    int x, q, l, r, c;

    string s, t;

    auto start = high_resolution_clock::now();

    int tcnt = 0;

    int tests = 1;
    //pre();
    //cin >> tests;

    while (tests--)
    {
        //cout << "Case #" << ++tcnt << ": ";

        cin >> n >> m;
        while (m--)
            cin >> l >> r, adj[l].pb(r);
        if (checkCycle())
            cout << "YES";
        else
            cout << (solve() ? "YES" : "NO");

        // RESTORE SEGTREE SIZE
    }
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<microseconds>(stop - start);
    cerr << "Time taken: "
         << duration.count() / 1000000.0 << "seconds" << nl;
    return 0;
}