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 CF915D
{
	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)));
        CF915D inst = new CF915D();
        inst.execute();
        out.close();
    }
    
    class Node {
    	int id;
    	ArrayList<Edge> nbs = new ArrayList<Edge>();
    	boolean visited = false;
    	boolean inStack = false;
    	public Node(int _id) {
    		id = _id;
    	}
    	boolean dfs1(Stack<Edge> cur) {
    		if (inStack) return true;
    		if (visited) return false;
    		visited = true;
    		inStack = true;
    		for (Edge edge : nbs) {
    			cur.push(edge);
    			if (edge.b.dfs1(cur)) {
    				return true;
    			}    				
    			cur.pop();
    		}
    		inStack = false;
    		return false;
    	}
    	
    	boolean dfs2() {
    		if (inStack) return true;
    		if (visited) return false;
    		visited = true;
    		inStack = true;
    		for (Edge edge : nbs) {
    			if (edge.disabled) continue;
    			if (edge.b.dfs2()) {
    				return true;
    			}    				
    		}
    		inStack = false;
    		return false;
    	}
    }
    
    class Edge {
    	Node a, b;
    	boolean disabled = false;
    	public Edge(Node _a, Node _b) {
    		a = _a;
    		b = _b;
    	}
    	public String toString() {
    		return (a.id + 1) + "->" + (b.id + 1);
    	}
    }
    
    void execute() throws IOException {
    	int n = scan.nextInt();
    	int m = scan.nextInt();
    	Node[] nodes = new Node[n];
    	Edge[] edges = new Edge[m];
    	for (int i = 0; i < n; i++) {
    		nodes[i] = new Node(i);
    	}
    	for (int i = 0; i < m; i++) {
    		Node a = nodes[scan.nextInt() - 1];
    		Node b = nodes[scan.nextInt() - 1];
    		edges[i] = new Edge(a, b);
    		a.nbs.add(edges[i]);
    	}
    	
    	boolean isCycle = false;
    	Stack<Edge> candidates = new Stack<Edge>();
    	for (int i = 0; i < n && !isCycle; i++) {
			candidates.clear();
			isCycle = nodes[i].dfs1(candidates);
    	}
    	
    	if (!isCycle) {
    		out.println("YES");
    		return;
    	}
    	
//    	debug(candidates.toString());
    	
    	while (!candidates.isEmpty()) {
    		Edge edge = candidates.pop();
//    		debug("Test " + edge);
    		edge.disabled = true;
    		for (Node node : nodes) {
    			node.visited = false;
    			node.inStack = false;
    		}
    		isCycle = false;
        	for (int i = 0; i < n && !isCycle; i++) {
    			isCycle = nodes[i].dfs2();
        	}
        	if (!isCycle) {
        		out.println("YES");
        		return;        		
        	}
    		
    		edge.disabled = false;
    	}
		out.println("NO");
    }
}