#include <bits/stdc++.h>
using namespace std;
const int limit = 1000005;
void die() {
  cout << "NO" << endl;
  exit(0);
}
void computereachable(int u, int code, vector<int> g[limit],
                      int reachable[limit]) {
  if (reachable[u] & code) return;
  reachable[u] |= code;
  vector<int> &ar = g[u];
  for (int i = 0; i < int(ar.size()); i++)
    computereachable(ar[i], code, g, reachable);
}
int n, m;
vector<int> g[limit], ginv[limit];
int reachdir[limit];
int reachinv[limit];
int nsink;
int nsour;
int listsour[limit];
int norder;
int order[limit];
int seen[limit];
void generatepostorder(int u) {
  if (seen[u]) return;
  seen[u] = 1;
  vector<int> &ar = ginv[u];
  for (int i = 0; i < int(ar.size()); i++) generatepostorder(ar[i]);
  order[norder++] = u;
}
void traverse(int u) {
  if (seen[u]) return;
  seen[u] = 1;
  vector<int> &ar = g[u];
  for (int i = 0; i < int(ar.size()); i++) traverse(ar[i]);
}
void checkalreadystrong() {
  for (int u = 1; u <= n; u++) generatepostorder(u);
  reverse(order, order + norder);
  for (int u = 1; u <= n; u++) seen[u] = 0;
  traverse(order[0]);
  for (int u = 1; u <= n; u++)
    if (not seen[u]) die();
  cout << "YES" << endl;
  exit(0);
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    ginv[v].push_back(u);
  }
  for (int u = 1; u <= n; u++) {
    if (int(g[u].size()) == 0) {
      computereachable(u, 1 << (nsink++), ginv, reachinv);
    }
    if (int(ginv[u].size()) == 0) {
      computereachable(u, 1, g, reachdir);
      listsour[nsour++] = u;
    }
  }
  if (nsour == 0) checkalreadystrong();
  for (int u = 1; u <= n; u++)
    if (not reachdir[u] or not reachinv[u]) die();
  for (int c = 1; c < (1 << nsour) - 1; c++) {
    int creach = 0;
    for (int b = 0; b < nsour; b++)
      if (c & (1 << b)) creach |= reachinv[listsour[b]];
    if (__builtin_popcount(creach) <= __builtin_popcount(c)) die();
  }
  cout << "YES" << endl;
}
