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 Main
{
	static final boolean _DEBUG = true;

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner(BufferedReader _br) {
			br = _br;
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					e.printStackTrace();
					return "";
				}
			}
			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;
		}

	}

	static MyScanner   scan;
	static PrintWriter out;

	static int debugCount = 0;
	static void debug(String msg) {
		if (_DEBUG && debugCount < 200) {
			out.println(msg);
			out.flush();
			debugCount++;
		}
	}
	
    public static void main (String args[]) throws IOException {
//    	scan = new MyScanner(new BufferedReader(new FileReader("test.in")));
    	scan = new MyScanner(new BufferedReader(new InputStreamReader(System.in)));
    	out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        Main inst = new Main();
        inst.execute();
        out.close();
    }
    
    ArrayList<Node> cycle;
    int cycleStart;
    
    private class Node {
    	public int id;
    	public int index;
    	public HashSet<Node> childs;
    	public HashSet<Node> parents;
    	public int checked;
    	
    	public Node(int id) {
    		this.id = id;
    		index = -1;
    		childs = new HashSet<Node>();
    		parents = new HashSet<Node>();
    		checked = 0;
    	}
    }
    
    private void dfs1(Node node, int index) {
    	if (node.checked == 1) {
    		return;
    	}
    	node.checked = 1;
    	cycle.add(node);
    	node.index = index;
    	for (Node parent : node.parents) {
    		if (parent.checked == 0) {
    			dfs1(parent, index+1);
    			if (cycle.size() != index+1) {
    				return;
    			}
    		} else if (parent.index >= 0) {
    			cycleStart = parent.index;
    			return;
    		}
    	}
    	node.index = -1;
    	cycle.remove(index);
    }
    
    private boolean dfs2(Node node) {
    	if (node.checked == 3) {
    		return false;
    	} else if (node.checked == 2) {
    		return true;
    	}
    	node.checked = 2;
    	for (Node parent : node.parents) {
    		if (dfs2(parent)) {
    			return true;
    		}
    	}
    	node.checked = 3;
    	return false;
    }
    
    private void execute() throws IOException {
    	int N = scan.nextInt();
    	int M = scan.nextInt();
    	cycle = new ArrayList<Node>();
    	Node[] nodes = new Node[N];
    	for (int i = 0; i < N; i++) {
    		nodes[i] = new Node(i);
    	}
    	for (int i = 0; i < M; i++) {
    		Node node1 = nodes[scan.nextInt()-1];
    		Node node2 = nodes[scan.nextInt()-1];
    		node1.childs.add(node2);
    		node2.parents.add(node1);
    	}
    	for (int i = 0; i < N; i++) {
    		if (nodes[i].checked == 0) {
    			dfs1(nodes[i], 0);
    			if (cycle.size() > 0) {
    				break;
    			}
    		}
    	}
    	if (cycle.size() == 0) {
    		out.println("YES");
    		return;
    	}
    	for (int i = cycleStart; i < cycle.size(); i++) {
    		Node node = cycle.get(i);
    		Node next = cycle.get(Math.max((i+1)%cycle.size(), cycleStart));
//    		out.println(node.id+1+" "+next.id+1);
    		next.childs.remove(node);
    		node.parents.remove(next);
    		boolean cycle = false;
    		for (int j = 0; j < N; j++) {
    			if (dfs2(nodes[j])) {
    				cycle = true;
    				break;
    			}
    		}
    		for (int j = 0; j < N; j++) {
    			nodes[j].checked = 0;
    		}
    		if (!cycle) {
            	out.println("YES");
        		return;
    		}
    		next.childs.add(node);
    		node.parents.add(next);
    	}
    	out.println("NO");
    }
}
