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.*;
import java.util.*;

public class D_AlmostAcyclicGraph {
    private static class Solver {
        Set<Integer>[] map;
        int n, m;
        boolean[] been;
        boolean[] inpath;

        public void solve(Reader in, PrintWriter out) throws IOException {
            n = in.nextInt();
            m = in.nextInt();
            map = new Set[n+1];
            for (int i = 0; i < m; i++) {
                int u = in.nextInt();
                int v = in.nextInt();
                if (map[u] == null) map[u] = new HashSet<>();
                map[u].add(v);
            }

            been = new boolean[n+1];
            inpath = new boolean[n+1];
            List<Integer> cycle = findCycle();
            if (cycle.isEmpty()) {
                out.print("YES");
                return;
            }

            for (int i = cycle.size() - 2; i >= 0; i--) {
               int u = cycle.get(i + 1);
               int v = cycle.get(i);
               map[u].remove(v);
               if (!checkCycle()) {
                   out.print("YES");
                   return;
               }
               map[u].add(v);
            }

            out.print("NO");
        }

        private List<Integer> findCycle() {
            Arrays.fill(been, false);
            Arrays.fill(inpath, false);
            List<Integer> cycle = new ArrayList<>();
            for (int i = 1; i <= n; i++) {
                if (been[i]) continue;
                if (dfs(i, been, inpath, cycle)) break;
            }
            return cycle;
        }

        private boolean dfs(int u, boolean[] been, boolean[] inpath, List<Integer> cycle) {
            if (inpath[u]) {
                cycle.add(u);
                return true;
            }
            if (been[u]) return false;

            been[u] = true;
            if (map[u] == null) return false;

            inpath[u] = true;
            for (int v : map[u]) {
                if (dfs(v, been, inpath, cycle)) {
                    cycle.add(u);
                    return true;
                }
            }
            inpath[u] = false;
            return false;
        }

        private boolean checkCycle() {
            Arrays.fill(been, false);
            Arrays.fill(inpath, false);
            for (int i = 1; i <= n; i++) {
                if (been[i]) continue;
                if (dfs2(i, been, inpath)) return true;
            }
            return false;
        }

        private boolean dfs2(int u, boolean[] been, boolean[] inpath) {
            if (inpath[u]) return true;
            if (been[u]) return false;

            been[u] = true;
            if (map[u] == null) return false;

            inpath[u] = true;
            for (int v : map[u]) {
                if (dfs2(v, been, inpath)) return true;
            }
            inpath[u] = false;
            return false;
        }
    }

    /***********************************************************************************************
     *                                           TEMPLATE                                          *
     ***********************************************************************************************/
    private final static boolean DEBUG = false;
    private final static String DEBUG_INPUT = "5 6\n" +
            "1 2\n" +
            "2 3\n" +
            "3 2\n" +
            "3 1\n" +
            "2 1\n" +
            "4 5";

    public static void main(String[] args) throws IOException {
        if (DEBUG) {
            InputStream debugInput = new ByteArrayInputStream(DEBUG_INPUT.getBytes());
            Reader in = new Reader(debugInput);
            PrintWriter out = new PrintWriter(System.out);
            long start = System.currentTimeMillis();
            new Solver().solve(in, out);
            out.flush();
            long end = System.currentTimeMillis();
            System.out.println();
            System.out.println("=============================");
            System.out.println("Took: " + (end - start) + "ms");
        } else {
            Reader in = new Reader(System.in);
            PrintWriter out = new PrintWriter(System.out);
            new Solver().solve(in, out);
            out.flush();
        }
    }

    private static class Reader {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        public Reader(InputStream input) {
            reader = new BufferedReader(
                    new InputStreamReader(input));
            tokenizer = new StringTokenizer("");
        }

        private String nextWord() throws IOException {
            while (!tokenizer.hasMoreTokens()) {
                tokenizer = new StringTokenizer(reader.readLine());
            }
            return tokenizer.nextToken();
        }

        private int nextInt() throws IOException {
            return Integer.parseInt(nextWord());
        }

        private long nextLong() throws IOException {
            return Long.parseLong(nextWord());
        }

        private double nextDouble() throws IOException {
            return Double.parseDouble(nextWord());
        }
    }

}
