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 final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static final PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    private static StringTokenizer st;

    private static int readInt() throws IOException {
        while (st == null || !st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
        return Integer.parseInt(st.nextToken());
    }

    public static void main(String[] args) throws IOException {
        pw.println(solve() ? "YES" : "NO");
        pw.close();
    }

    private static boolean solve() throws IOException {
        int n = readInt();
        int m = readInt();
        ArrayList<Integer>[] adj = new ArrayList[n + 1];
        for (int i = 1; i <= n; i++) adj[i] = new ArrayList<>();
        for (int i = 0; i < m; i++) {
            int a = readInt();
            int b = readInt();
            adj[a].add(b);
        }

        Graph g = new Graph(adj);
        return g.isAlmostAcyclic();
    }

    static class Graph {
        final int n;
        final ArrayList<Integer>[] adj;

        boolean[] visited, recStack;
        boolean isCyclic;

        int[] parent;
        int circleStart;

        public Graph(ArrayList<Integer>[] adj) {
            this.adj = adj;
            this.n = adj.length - 1;
        }

        private void computeIsCycle(int i) {
            if (isCyclic) return;

            if (recStack[i]) {
                isCyclic = true;
                return;
            }

            if (visited[i]) return;

            recStack[i] = true;
            visited[i] = true;

            for (int c : adj[i]) {
                computeIsCycle(c);
            }
            recStack[i] = false;
        }

        void computeIsCycle() {
            isCyclic = false;
            // None of the vertices is visited nor part of recursion stack
            visited = new boolean[n + 1];
            recStack = new boolean[n + 1];

            for (int i = 1; i <= n; i++) {
                computeIsCycle(i);
                if (isCyclic) return;
            }
        }

        private void computeIsCycleInitially(int i) {
            if (isCyclic) return;

            if (recStack[i]) {
                isCyclic = true;
                return;
            }

            if (visited[i]) return;

            recStack[i] = true;
            visited[i] = true;

            for (int c : adj[i]) {
                parent[c] = i;
                computeIsCycleInitially(c);
                if (isCyclic) {
                    if (circleStart == 0) {
                        circleStart = c;
                    }
                    return;
                }
            }
            recStack[i] = false;
        }

        void computeIsCycleInitially() {
            isCyclic = false;
            // None of the vertices is visited nor part of recursion stack
            visited = new boolean[n + 1];
            recStack = new boolean[n + 1];
            parent = new int[n + 1];

            for (int i = 1; i <= n; i++) {
                computeIsCycleInitially(i);
                if (isCyclic) return;
            }
        }

        boolean isAlmostAcyclic() {
            computeIsCycleInitially();
            if (!isCyclic) return true;
            // parent[] and circleStart must have been set up.

            int edgeRemovedEnd = circleStart;
            boolean circleTraversed = false;
            do {
                ArrayList<Integer> adjOfEdgeRemovedStart = adj[parent[edgeRemovedEnd]];
                // must be boxed to apply the particular overloaded version.
                adjOfEdgeRemovedStart.remove(Integer.valueOf(edgeRemovedEnd));

                computeIsCycle();
                if (!isCyclic) return true;

                adjOfEdgeRemovedStart.add(edgeRemovedEnd);
                edgeRemovedEnd = parent[edgeRemovedEnd];
            } while (parent[edgeRemovedEnd] != circleStart || (!circleTraversed && (circleTraversed = true)));

            return false;
        }
    }
}
