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 AlmostAcyclicGraph {

	public static void main(String[] args) throws Exception {
		FastScanner sc = new FastScanner(System.in);
		PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		run(sc, out);
		out.close();
	}

	public static void run(FastScanner sc, PrintWriter out) throws Exception {
		int N = sc.nextInt();
		int M = sc.nextInt();
		Node[] arr = new Node[N];
		for (int i = 0; i < N; i++) {
			arr[i] = new Node(i);
		}
		for (int i = 0; i < M; i++) {
			arr[sc.nextInt() - 1].add(sc.nextInt() - 1, arr);
		}
		LinkedList<Node> queue = new LinkedList<>();
		for (int i = 0; i < N; i++) {
			if (arr[i].indeg == 0) {
				queue.add(arr[i]);
			}
		}
		while (!queue.isEmpty()) {
			Node cur = queue.remove();
			for (Node c : cur.adj) {
				if (--c.indeg == 0) {
					queue.add(c);
				}
			}
		}
		boolean done = true;
		int[] indeg = new int[N];
		for (int i = 0; i < N; i++) {
			if (arr[i].indeg != 0) {
				done = false;
			}
			indeg[i] = arr[i].indeg;
		}
		if (done) {
			System.out.println("YES");
			return;
		}
		int[] temp = new int[N];
		for (int i = 0; i < N; i++) {
			if (indeg[i] == 1) {
				System.arraycopy(indeg, 0, temp, 0, N);
				temp[i]--;
				queue.clear();
				queue.add(arr[i]);
				while (!queue.isEmpty()) {
					Node cur = queue.remove();
					for (Node c : cur.adj) {
						if (--temp[c.index] == 0) {
							queue.add(c);
						}
					}
				}
				temp[i]++;
				done = true;
				for (int j = 0; j < N; j++) {
					if (temp[j] != 0) {
						done = false;
						break;
					}
				}
				if (done) {
					System.out.println("YES");
					return;
				}
			}
		}
		System.out.println("NO");
	}

	static class Node {
		int index;
		ArrayList<Node> adj;
		int indeg = 0;

		public Node(int index) {
			super();
			this.index = index;
			adj = new ArrayList<>();
		}

		public void add(int i, Node[] arr) {
			adj.add(arr[i]);
			arr[i].indeg++;
		}
	}

	static class FastScanner {
		final private int BUFFER_SIZE = 1 << 20;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public FastScanner(InputStream stream) {
			din = new DataInputStream(stream);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public FastScanner(String file_name) throws IOException {
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		String nextLine() throws IOException {
			int c = read();
			while (c != -1 && isEndline(c))
				c = read();
			if (c == -1) {
				return null;
			}
			StringBuilder res = new StringBuilder();
			do {
				if (c >= 0) {
					res.appendCodePoint(c);
				}
				c = read();
			} while (!isEndline(c));
			return res.toString();
		}

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

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

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

		public int nextInt() throws IOException {
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg) c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (neg) return -ret;
			return ret;
		}

		public long nextLong() throws IOException {
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg) c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');
			if (neg) return -ret;
			return ret;
		}

		public double nextDouble() throws IOException {
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg) c = read();

			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (c == '.') {
				while ((c = read()) >= '0' && c <= '9') {
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg) return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException {
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1) buffer[0] = -1;
		}

		private byte read() throws IOException {
			if (bufferPointer == bytesRead) fillBuffer();
			return buffer[bufferPointer++];
		}

		private int readOutSpaces() throws IOException {
			while (true) {
				if (bufferPointer == bytesRead) fillBuffer();
				int c = buffer[bufferPointer++];
				if (!isSpaceChar(c)) {
					return c;
				}
			}
		}

		public void close() throws IOException {
			if (din == null) return;
			din.close();
		}
	}

}