#include <bits/stdc++.h>
using namespace std;
const long long INF = 1LL << 55;
const long long mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T>
T Max(T &a, T b) {
  return a = max(a, b);
}
template <class T>
T Min(T &a, T b) {
  return a = min(a, b);
}
class TSort {
 public:
  long long V;
  vector<set<long long> > in, out;
  vector<long long> sorted;
  TSort() { V = -1; }
  TSort(long long V) {
    in.resize(V);
    out.resize(V);
    this->V = V;
  }
  void add_edge(long long from, long long to) {
    assert(from < V && to < V);
    assert(out[from].count(to) == 0);
    assert(in[to].count(from) == 0);
    out[from].insert(to);
    in[to].insert(from);
  }
  void erase_edge(long long from, long long to) {
    out[from].erase(to);
    in[to].erase(from);
  }
  void sort() {
    sorted.clear();
    queue<long long> Q;
    for (long long i = 0; i < V; i++)
      if (in[i].empty()) Q.push(i);
    while (!Q.empty()) {
      long long v = Q.front();
      Q.pop();
      sorted.push_back(v);
      for (long long nx : out[v]) {
        if (in[nx].size() == 1) Q.push(nx);
        in[nx].erase(v);
      }
    }
    for (long long i = 0; i < V; i++)
      if (!in[i].empty()) sorted.clear();
  }
};
class Bridges {
 public:
  struct edgeB {
    long long u, v;
  };
  long long V;
  vector<long long> G[1000];
  vector<edgeB> bridges;
  long long ord[1000];
  long long low[1000];
  Bridges() { V = -1; }
  Bridges(long long V) { this->V = V; }
  void add_edge(long long a, long long b) {
    G[a].push_back(b);
    G[b].push_back(a);
  }
  void erase_edge(long long a, long long b) {
    for (long long i = 0; i < (long long)G[a].size(); i++)
      if (G[a][i] == b) G[a].erase(G[a].begin() + i);
    for (long long i = 0; i < (long long)G[b].size(); i++)
      if (G[b][i] == a) G[b].erase(G[b].begin() + i);
  }
  void dfs(long long u, long long p, long long &c) {
    ord[u] = low[u] = c++;
    for (long long i = 0; i < G[u].size(); i++) {
      long long v = G[u][i];
      if (v == p) continue;
      if (ord[v] == -1) {
        dfs(v, u, c);
        low[u] = min(low[u], low[v]);
      } else
        low[u] = min(low[u], ord[v]);
      if (ord[u] < low[v]) bridges.push_back((edgeB){u, v});
    }
  }
  void bridge() {
    assert(V >= 0);
    bridges.clear();
    long long c = 0;
    memset(ord, -1, sizeof(ord));
    memset(low, 0, sizeof(low));
    for (long long i = 0; i < V; i++)
      if (ord[i] == -1) dfs(i, -1, c);
  }
  bool isBridge(long long u, long long v) {
    for (edgeB e : bridges)
      if (e.u == u && e.v == v) return 1;
    swap(u, v);
    for (edgeB e : bridges)
      if (e.u == u && e.v == v) return 1;
    return 0;
  }
};
set<long long> G[1000];
signed main() {
  long long n, m;
  cin >> n >> m;
  TSort T(n);
  Bridges B(n);
  for (long long i = 0; i < m; i++) {
    long long a, b;
    cin >> a >> b;
    a--, b--;
    T.add_edge(a, b);
    B.add_edge(a, b);
    G[a].insert(b);
  }
  long long ans = 0;
  for (long long from = 0; from < n; from++)
    for (long long to : G[from]) {
      B.bridge();
      if (B.isBridge(from, to)) continue;
      T.erase_edge(from, to);
      B.erase_edge(from, to);
      T.sort();
      B.bridge();
      if (T.sorted.size() && (long long)B.bridges.size() >= 2) ans = 1;
      T.add_edge(from, to);
      B.add_edge(from, to);
    }
  cout << (ans ? "YES" : "NO") << endl;
  return 0;
}
