#include <bits/stdc++.h>
using namespace std;
void find_sink(vector<vector<int> > &adj, int s, int N, int K,
               vector<int> &sink, set<int> &reach_sink) {
  int i, j, k, u, v;
  vector<int> visited;
  stack<int> st;
  visited.resize(N + 1);
  for (i = 1; i <= N; ++i) visited[i] = 0;
  st.push(s);
  visited[s] = 1;
  while (!st.empty()) {
    u = st.top();
    st.pop();
    for (i = 0; i < (int)adj[u].size(); ++i) {
      v = adj[u][i];
      if (!visited[v]) {
        visited[v] = 1;
        st.push(v);
      }
    }
  }
  for (i = 0; i < K; ++i)
    if (visited[sink[i]]) reach_sink.insert(i);
}
bool strongly_connected(vector<int> &source, vector<int> &sink, int K,
                        set<int> *reach_sink) {
  int bit, i, count;
  bool ans = true;
  set<int> st;
  set<int>::iterator p;
  for (bit = 1; bit < (1 << K) - 1; ++bit) {
    st.clear();
    count = 0;
    for (i = 0; i < K; ++i)
      if ((1 << i) & bit) {
        ++count;
        for (p = reach_sink[i].begin(); p != reach_sink[i].end(); ++p)
          st.insert(*p);
      }
    if ((int)st.size() <= count) ans = false;
  }
  return ans;
}
int main() {
  int N, M, i, j, k, u, v, K;
  vector<vector<int> > adj;
  vector<int> indeg, outdeg;
  vector<int> source, sink;
  set<int> reach_sink[30];
  scanf("%d%d", &N, &M);
  adj.resize(N + 1);
  indeg.resize(N + 1);
  outdeg.resize(N + 1);
  for (i = 1; i <= N; ++i) {
    indeg[i] = 0;
    outdeg[i] = 0;
  }
  for (j = 1; j <= M; ++j) {
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    outdeg[u]++;
    indeg[v]++;
  }
  for (i = 1; i <= N; ++i)
    if (indeg[i] == 0) source.push_back(i);
  for (i = 1; i <= N; ++i)
    if (outdeg[i] == 0) sink.push_back(i);
  K = (int)source.size();
  for (i = 0; i < K; ++i) find_sink(adj, source[i], N, K, sink, reach_sink[i]);
  if (strongly_connected(source, sink, K, reach_sink))
    printf("YES\n");
  else
    printf("NO\n");
  return 0;
}
