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.
// package cf915;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Supplier;

import static java.util.Arrays.stream;

public class CFD {
    FastScanner sc;
    int[] a;
    Node cycleRoot;
    boolean cycled = false;
    Deque<Node> cycle = new ArrayDeque<>();
    List<Node> cycle2 = new ArrayList<>();

    static int WHITE = 0;
    static int GRAY =  1;
    static int BLACK = 2;

    public static void main(String[] args) { new CFD().run(); }

    public void run() {
        sc = new FastScanner(System.in);

        int n = sc.nextInt();
        int m = sc.nextInt();

        Node[] nodes = new Node[n];
        for (int i = 0; i < n; i++) nodes[i] = new Node(i+1);

        for (int i = 0; i < m; i++) {
            int u = sc.nextInt();
            int v = sc.nextInt();
            nodes[u-1].children.add(nodes[v-1]);
        }

        for (Node node : nodes) {
            if (node.col == WHITE) {
                if (cycles(node)) {
                    break;
                }
            }
        }

        if (cycleRoot == null) {
            System.out.println("YES"); //no cycles
            return;
        }
        
        Node cur = cycleRoot;
        for (Node cnode : cycle) {
            clean(nodes);
            cycled = false;
            for (Node node : nodes) {
                if (node.col == WHITE) {
                    if (cycles(node, cur, cnode)) {
                        cycled = true;
                    }
                }
            }
            if (!cycled) {
                System.out.println("YES");
                return;
            }
            cur = cnode;
        }
        System.out.println("NO");
    }

    private void clean(Node[] nodes) {
        stream(nodes).forEach(node -> node.col = WHITE);
    }

    boolean cycles(Node node) {
        node.col = GRAY;
        for (Node child : node.children) {
            if (child.col == WHITE) {
                if (cycles(child)) {
                    if (cycled) {
                        if (child == cycleRoot) cycled = false;
                        else cycle.addFirst(child);
                    }
                    return true;
                }
            }
            if (child.col == GRAY) {
                cycle.add(child);
                cycleRoot = child;
                cycled = true;
                return true;
            }
        }
        node.col = BLACK;
        return false;
    }

    boolean cycles(Node node, Node from, Node to) {
        node.col = GRAY;
        for (Node child : node.children) {
            if (node == from && child == to) continue;

            if (child.col == WHITE) {
                if (cycles(child, from, to)) return true;
            }
            if (child.col == GRAY) {
                return true;
            }
        }
        node.col = BLACK;
        return false;
    }

    static class Node {
        int n;
        int col;
        List<Node> children = new ArrayList<>();

        Node(int n) {
            this.n = n;
            col = WHITE;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "n=" + n +
                    ", col=" + col +
                    '}';
        }
    }

    //********************************************************************************************
    //********************************************************************************************
    //********************************************************************************************

    private static int ceil(double d) {
        int ret = (int) d;
        return ret == d ? ret : ret + 1;
    }

    private static int round(double d) {
        return (int) (d + 0.5);
    }

    private static <T> T elvis(T obj, Supplier<T> defValue) {
        return obj == null ? defValue.get() : obj;
    }

    @SuppressWarnings("SameParameterValue")
    private static <T> T elvis(T obj, T defValue) {
        return obj == null ? defValue : obj;
    }

    private static int gcd(int a, int b) {
        BigInteger b1 = BigInteger.valueOf(a);
        BigInteger b2 = BigInteger.valueOf(b);
        BigInteger gcd = b1.gcd(b2);
        return gcd.intValue();
    }

    private int[] readIntArray(int n) {
        int[] res = new int[n];
        for (int i = 0; i < n; i++) {
            res[i] = sc.nextInt();
        }
        return res;
    }

    private long[] readLongArray(int n) {
        long[] res = new long[n];
        for (int i = 0; i < n; i++) {
            res[i] = sc.nextLong();
        }
        return res;
    }

    @SuppressWarnings("unused")
    static class FastScanner {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        FastScanner(InputStream stream) {
            this.stream = stream;
        }

        int read() {
            if (numChars == -1)
                throw new InputMismatchException();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) return -1;
            }
            return buf[curChar++];
        }

        boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        boolean isEndline(int c) {
            return c == '\n' || c == '\r' || c == -1;
        }

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

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

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

        public String next() {
            int c = read();
            while (isSpaceChar(c)) c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));
            return res.toString();
        }

        public String nextLine() {
            int c = read();
            while (isEndline(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isEndline(c));
            return res.toString();
        }
    }
}