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.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

public class DEditorial {

    static final long MODULO = (long) (1e9 + 7);
    private static ListInt[] adj;
    private static int[] visited;
    private static int[] parent;
    private static List<Integer> cycle;
    private static int[] removed;
    private static int visitToken;

    public static void main(String[] args) {
        BufferedScanner scanner = new BufferedScanner();
        PrintWriter writer = new PrintWriter(new BufferedOutputStream(System.out));

        int t = 1;//scanner.nextInt();
        for (int tc = 0; tc < t; tc++) {
            int n = scanner.nextInt();
            int m = scanner.nextInt();
            adj = new ListInt[n];
            for (int i = 0; i < n; i++) {
                adj[i] = new ListInt();
            }
            for (int i = 0; i < m; i++) {
                int u = scanner.nextInt() - 1;
                int v = scanner.nextInt() - 1;
                adj[u].add(v);
            }
            visited = new int[n];
            parent = new int[n];
            Arrays.fill(parent, -1);
            removed = new int[]{-1, -1};
            visitToken++;
            for (int i = 0; i < n; i++) {
                if (visited[i] != visitToken) {
                    parent[i] = i;
                    dfs(i, true);
                    if (cycle != null) {
                        break;
                    }
                    parent[i] = -1;
                }
            }
            boolean ans = false;
            if (cycle == null) {
                ans = true;
            } else {
                int prev = cycle.get(cycle.size() - 1);
                for (int node : cycle) {
                    removed[0] = prev;
                    removed[1] = node;
                    System.err.println("try remove " + prev + " " + node);
                    boolean noCycle = true;
                    visitToken++;
                    for (int i = 0; i < n; i++) {
                        if (visited[i] != visitToken) {
                            parent[i] = i;
                            if (dfs(i, false)) {
                                noCycle = false;
                                break;
                            }
                            parent[i] = -1;
                        }
                    }
                    if (noCycle) {
                        ans = true;
                        break;
                    }
                    prev = node;
                }
            }
            if (ans) {
                writer.println("YES");
            } else {
                writer.println("NO");
            }
        }

        scanner.close();
        writer.flush();
        writer.close();
    }

    private static boolean dfs(int node, boolean detail) {
        visited[node] = visitToken;
        boolean ans = false;
        for (int to : adj[node]) {
            if (to == removed[0] && node == removed[1] || node == removed[0] && to == removed[1]) {
                continue;
            }
            if (visited[to] == visitToken) {
                if (parent[to] != -1) {
                    if (detail) {
                        cycle = new ArrayList<>();
                        int x = node;
                        while (x != to) {
                            cycle.add(x);
                            x = parent[x];
                        }
                        cycle.add(to);
                    }
                    ans = true;
                }
            } else {
                parent[to] = node;
                if (dfs(to, detail)) {
                    ans = true;
                }
                parent[to] = -1;
            }
            if (ans) {
                break;
            }
        }
        return ans;
    }

    static class ListInt extends ArrayList<Integer> {}

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    static long add(long a, long b) {
        a += b;
        if (a >= MODULO) {
            a -= MODULO;
        }
        return a;
    }

    static long sub(long a, long b) {
        a -= b;
        if (a < 0) {
            a += MODULO;
        }
        return a;
    }

    static long mul(long a, long b) {
        return a * b % MODULO;
    }

    static long div(long a, long b) {
        return a * inverse(b, MODULO) % MODULO;
    }

    static class Comb {
        final long modulo;
        final long[] fac, fnv;

        Comb(int limit, long modulo) {
            fac = new long[limit + 1];
            fnv = new long[limit + 1];
            fac[0] = 1;
            fnv[0] = 1;
            for (int i = 1; i <= limit; i++) {
                fac[i] = mul(fac[i - 1], i);
                fnv[i] = div(fnv[i - 1], i);
            }
            this.modulo = modulo;
        }

        long c(int total, int choose) {
            if (total < choose) {
                return 0;
            }
            if (total == 0 || total == choose) {
                return 1;
            }
            return mul(mul(fac[total], fnv[choose]), fnv[total - choose]);
        }
    }

}
