You are given a [directed graph](https://en.wikipedia.org/wiki/Directed_graph) consisting of n vertices and m edges (each edge is directed, so it can be traversed in only one direction). You are allowed to remove at most one edge from it.

Can you make this graph [acyclic](https://en.wikipedia.org/wiki/Directed_acyclic_graph) by removing at most one edge from it? A directed graph is called acyclic iff it doesn't contain any cycle (a non-empty path that starts and ends in the same vertex).

Input

The first line contains two integers n and m (2 ≤ n ≤ 500, 1 ≤ m ≤ min(n(n - 1), 100000)) — the number of vertices and the number of edges, respectively.

Then m lines follow. Each line contains two integers u and v denoting a directed edge going from vertex u to vertex v (1 ≤ u, v ≤ n, u ≠ v). Each ordered pair (u, v) is listed at most once (there is at most one directed edge from u to v).

Output

If it is possible to make this graph acyclic by removing at most one edge, print YES. Otherwise, print NO.

Examples

Input

3 4
1 2
2 3
3 2
3 1


Output

YES


Input

5 6
1 2
2 3
3 2
3 1
2 1
4 5


Output

NO

Note

In the first example you can remove edge <image>, and the graph becomes acyclic.

In the second example you have to remove at least two edges (for example, <image> and <image>) in order to make the graph acyclic.
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
inline long long getint() {
  long long _x = 0, _tmp = 1;
  char _tc = getchar();
  while ((_tc < '0' || _tc > '9') && _tc != '-') _tc = getchar();
  if (_tc == '-') _tc = getchar(), _tmp = -1;
  while (_tc >= '0' && _tc <= '9') _x *= 10, _x += (_tc - '0'), _tc = getchar();
  return _x * _tmp;
}
inline long long add(long long _x, long long _y,
                     long long _mod = 1000000007LL) {
  _x += _y;
  return _x >= _mod ? _x - _mod : _x;
}
inline long long sub(long long _x, long long _y,
                     long long _mod = 1000000007LL) {
  _x -= _y;
  return _x < 0 ? _x + _mod : _x;
}
inline long long mul(long long _x, long long _y,
                     long long _mod = 1000000007LL) {
  _x *= _y;
  return _x >= _mod ? _x % _mod : _x;
}
long long mypow(long long _a, long long _x, long long _mod) {
  if (_x == 0) return 1LL;
  long long _ret = mypow(mul(_a, _a, _mod), _x >> 1, _mod);
  if (_x & 1) _ret = mul(_ret, _a, _mod);
  return _ret;
}
long long mymul(long long _a, long long _x, long long _mod) {
  if (_x == 0) return 0LL;
  long long _ret = mymul(add(_a, _a, _mod), _x >> 1, _mod);
  if (_x & 1) _ret = add(_ret, _a, _mod);
  return _ret;
}
inline bool equal(double _x, double _y) {
  return _x > _y - 1e-9 && _x < _y + 1e-9;
}
void sleep(double sec = 1021) {
  clock_t s = clock();
  while (clock() - s < CLOCKS_PER_SEC * sec)
    ;
}
int __ = 1, _cs;
struct Arc {
  int to, nxt;
  Arc() {}
  Arc(int _to, int _nxt) {
    to = _to;
    nxt = _nxt;
  }
} r[101010];
void build() {}
int n, m, from[514], id[514][514], ind[514];
void init() {
  n = getint();
  m = getint();
  for (int i = 1; i <= m; i++) {
    int ui = getint();
    int vi = getint();
    r[i] = Arc(vi, from[ui]);
    from[ui] = i;
    id[ui][vi] = i;
    ind[vi]++;
  }
}
vector<int> cand;
bool vst[514], instk[514];
int who[514];
void go(int now, int sz) {
  vst[now] = true;
  instk[now] = true;
  who[sz] = now;
  for (int i = from[now]; i and cand.empty(); i = r[i].nxt)
    if (instk[r[i].to]) {
      cand.push_back(i);
      for (int j = sz; j; j--)
        if (who[j] == r[i].to)
          break;
        else
          cand.push_back(id[who[j - 1]][who[j]]);
      break;
    } else if (not vst[r[i].to])
      go(r[i].to, sz + 1);
  instk[now] = false;
}
void yes() {
  puts("YES");
  exit(0);
}
int block, tind[514];
void gogo() {
  if (block == 0) return;
  for (int i = 1; i <= n; i++) tind[i] = ind[i];
  tind[r[block].to]--;
  queue<int> Q;
  for (int i = 1; i <= n; i++)
    if (tind[i] == 0) Q.push(i);
  int gt = 0;
  while (Q.size()) {
    int tn = Q.front();
    Q.pop();
    gt++;
    for (int i = from[tn]; i; i = r[i].nxt) {
      if (i == block) continue;
      tind[r[i].to]--;
      if (tind[r[i].to] == 0) Q.push(r[i].to);
    }
  }
  if (gt == n) yes();
}
void solve() {
  for (int i = 1; i <= n and cand.empty(); i++)
    if (ind[i] == 0 and not vst[i]) go(i, 0);
  for (int i = 1; i <= n and cand.empty(); i++)
    if (not vst[i]) go(i, 0);
  if (cand.empty()) yes();
  for (int i : cand) {
    block = i;
    gogo();
  }
  puts("NO");
}
int main() {
  build();
  while (__--) {
    init();
    solve();
  }
}
