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.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

/*
 public class _915D {

 }

 */
public class _915D {
  public void solve() throws FileNotFoundException {
    InputStream inputStream = System.in;

    InputHelper in = new InputHelper(inputStream);

    // actual solution
    int n = in.readInteger();
    int m = in.readInteger();

    Set[] g = new Set[n];

    for (int i = 0; i < n; i++) {
      g[i] = new HashSet<Integer>();
    }

    for (int i = 0; i < m; i++) {
      int x = in.readInteger() - 1;
      int y = in.readInteger() - 1;

      g[x].add(y);
    }

    boolean[] iss = new boolean[n];
    ArrayDeque<Integer> dq = new ArrayDeque<Integer>();
    boolean[] vis = new boolean[n];

    for (int i = 0; i < n; i++) {
      if (!vis[i] && !fc)
        cycle(i, g, iss, dq, vis);
    }

    if (!fc) {
      System.out.println("YES");
      return;
    } else {
      Iterator<Integer> dqit = cycle.iterator();
      int p = -1;
      int first = -1;
      while (dqit.hasNext()) {
        int ele = dqit.next();

        if (p == -1) {
          first = ele;
          p = ele;
          continue;
        }

        g[p].remove(ele);

        iss = new boolean[n];
        dq = new ArrayDeque<Integer>();
        vis = new boolean[n];

        boolean isc = false;
        for (int i = 0; i < n; i++) {
          if (!vis[i])
            isc |= iscycle(i, g, iss, dq, vis);
        }

        if (!isc) {
          System.out.println("YES");
          return;
        }

        g[p].add(ele);
        p = ele;
      }

      g[p].remove(first);

      iss = new boolean[n];
      dq = new ArrayDeque<Integer>();
      vis = new boolean[n];

      boolean isc = false;
      for (int i = 0; i < n; i++) {
        if (!vis[i])
          isc |= iscycle(i, g, iss, dq, vis);
      }

      if (!isc) {
        System.out.println("YES");
        return;
      }
    }

    System.out.println("NO");
    // end here
  }

  boolean fc = false;
  Deque<Integer> cycle = new ArrayDeque<Integer>();

  boolean iscycle(int u, Set[] g, boolean[] iss, ArrayDeque<Integer> dq, boolean[] vis) {
    iss[u] = true;

    vis[u] = true;

    boolean ans = false;
    for (Integer v : (HashSet<Integer>) g[u]) {
      if (iss[v]) {
        ans = true;
      }

      if (!vis[v]) {
        ans |= iscycle(v, g, iss, dq, vis);
      }
    }

    iss[u] = false;

    return ans;
  }

  void cycle(int u, Set[] g, boolean[] iss, ArrayDeque<Integer> dq, boolean[] vis) {
    iss[u] = true;
    dq.addLast(u);

    vis[u] = true;

    for (Integer v : (HashSet<Integer>) g[u]) {

      if (iss[v] && !fc) {
        Iterator<Integer> dqit = dq.iterator();
        boolean fv = false;
        while (dqit.hasNext()) {
          int ele = dqit.next();
          if (ele == v || fv) {
            cycle.add(ele);
            fv = true;
          }
        }
        fc = true;
        return;
      }

      if (!vis[v]) {
        cycle(v, g, iss, dq, vis);
      }
    }

    iss[u] = false;
    dq.removeLast();
  }

  public static void main(String[] args) throws FileNotFoundException {
    (new _915D()).solve();
  }

  class InputHelper {
    StringTokenizer tokenizer = null;
    private BufferedReader bufferedReader;

    public InputHelper(InputStream inputStream) {
      InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
      bufferedReader = new BufferedReader(inputStreamReader, 16384);
    }

    public String read() {
      while (tokenizer == null || !tokenizer.hasMoreTokens()) {
        try {
          String line = bufferedReader.readLine();
          if (line == null) {
            return null;
          }
          tokenizer = new StringTokenizer(line);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }

      return tokenizer.nextToken();
    }

    public Integer readInteger() {
      return Integer.parseInt(read());
    }

    public Long readLong() {
      return Long.parseLong(read());
    }
  }
}
