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.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.util.InputMismatchException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.util.LinkedList;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Darkhan Imangaliyev
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        QuickScanner in = new QuickScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        int n;
        int m;
        List<Integer>[] g;
        int[] color;
        int[] from;
        List<Integer> path;

        @SuppressWarnings("unchecked")
        public void solve(int testNumber, QuickScanner in, PrintWriter out) {
            n = in.nextInt();
            m = in.nextInt();
            g = new LinkedList[n];
            for (int i = 0; i < n; ++i) {
                g[i] = new LinkedList<>();
            }
            for (int i = 0; i < m; ++i) {
                int v = in.nextInt() - 1, u = in.nextInt() - 1;
                g[v].add(u);
            }
            color = new int[n];
            if (!hasCycles(-1, -1)) {
                out.println("YES");
                return;
            }

            Arrays.fill(color, -1);
            from = new int[n];
            Arrays.fill(from, -1);
            path = new ArrayList<>();
            for (int i = 0; i < n; ++i) {
                if (color[i] == -1) {
                    if (findAnyCycle(i)) {
                        break;
                    }
                }
            }
            Collections.reverse(path);
//        System.out.println(path);
            int N = path.size();
            for (int i = 0; i < N; ++i) {
                Arrays.fill(color, -1);
//            System.out.println("Removing " + path.get(i) + " " + path.get((i + 1) % N));
//            System.out.println(cycles);
                if (!hasCycles(path.get(i), path.get((i + 1) % N))) {
                    out.println("YES");
                    return;
                }
            }
            out.println("NO");
        }

        private boolean hasCycles(int from, int to) {
            Arrays.fill(color, -1);
            for (int i = 0; i < n; ++i) {
                if (color[i] == -1) {
                    if (cycle(i, from, to)) {
                        return true;
                    }
                }
            }
            return false;
        }

        private boolean cycle(int v, int from, int to) {
            color[v] = 1;
            for (int i : g[v]) {
                if (from == v && to == i) {
                    continue;
                }
                if (color[i] == -1) {
                    if (cycle(i, from, to)) {
                        color[v] = 2;
                        return true;
                    }
                } else if (color[i] == 1) {
                    color[v] = 2;
                    return true;
                }
            }
            color[v] = 2;
            return false;
        }

        private boolean findAnyCycle(int v) {
            color[v] = 1;
            for (int i : g[v]) {
                if (color[i] == -1) {
                    from[i] = v;
                    if (findAnyCycle(i)) {
                        color[v] = 2;
                        return true;
                    }
                } else if (color[i] == 1) {
                    int cur = v;
                    while (cur != i) {
                        path.add(cur);
                        cur = from[cur];
                    }
                    path.add(i);
                    color[v] = 2;
                    return true;
                }
            }
            color[v] = 2;
            return false;
        }

    }

    static class QuickScanner {
        BufferedReader in;
        StringTokenizer token;
        String delim;

        public QuickScanner(InputStream inputStream) {
            this.in = new BufferedReader(new InputStreamReader(inputStream));
            this.delim = " \n\t";
            this.token = new StringTokenizer("", delim);
        }

        public QuickScanner(InputStream inputStream, String delim) {
            this.in = new BufferedReader(new InputStreamReader(inputStream));
            this.delim = delim;
            this.token = new StringTokenizer("", delim);
        }

        public boolean hasNext() {
            while (!token.hasMoreTokens()) {
                try {
                    String s = in.readLine();
                    if (s == null) return false;
                    token = new StringTokenizer(s, delim);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
            }
            return true;
        }

        public String next() {
            hasNext();
            return token.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

