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.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.Stack;

public class AcyclicGraph {

	private static class Edge {
		int u, v;
		
		public Edge(int u, int v) {
			this.u = u;
			this.v = v;
		}
		
		@Override 
		public String toString() {
			return "" + u + " -> " + v;
		}
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		n = sc.nextInt();
		m = sc.nextInt();
		
		adj = new List[n+1];
		
		for(int i=0;i<m;i++) {
			int u = sc.nextInt();
			int v = sc.nextInt();
			
			if (adj[u] == null) {
				adj[u] =  new LinkedList<>();
			}
			adj[u].add(new Edge(u,v));
		}
		
		seen = new boolean[n+1];
		marker = new int[n+1];
		Arrays.fill(marker, 0);
		Stack<Edge> circle = null;
		// Find any cycle in graph
		for (int node=1; node<=n;node++) {
			circle = dfs(node);
			if (circle != null) {
				break;
			}
		}
		
		if (circle == null) {
			System.out.println("YES");
			return;
		}
		
		Edge end = circle.pop();
		int endNode = end.v;
		
		List<Edge> toTest = new LinkedList<>();
		toTest.add(end);
		while (!circle.isEmpty()) {
			Edge current = circle.pop();
			toTest.add(current);
			if (current.u == end.v) {
				break;
			}
		}
		
		for (Edge blocked : toTest) {
			if (isAcyclic(blocked)) {
				System.out.println("YES");
				return;
			}
		}
		System.out.println("NO");
		

	}
	private static int n;
	private static int m;
	private static List<Edge>[] adj;
	private static boolean[] seen;
	private static Stack<Edge> path = new Stack<>();
	private static int[] marker;
	
	private static Stack<Edge> dfs(int currentNode) {
		if (!seen[currentNode] && marker[currentNode] != 2) {
			seen[currentNode] = true;
			
			marker[currentNode] = 1;
			if (adj[currentNode] != null) {
				for(Edge e: adj[currentNode]) {
					path.push(e);
					Stack<Edge> res = dfs(e.v); 
					if(res != null) {
						return res;
					}
					path.pop();
				}
			}
			marker[currentNode] = 2;
			return null;
			
		} else {
			if (marker[currentNode] == 1) {
				return path;
			} else {
				return null;
			}
		}
	}
	
	private static boolean isAcyclic(Edge blocked) {
		Arrays.fill(marker, 0);
		
		for(int node=1;node <=n; node++) {
			if (!isAcyclic(node, blocked)) {
				return false;
			}
		}
		return true;
	}
	
	private static boolean isAcyclic(int node, Edge blocked) {
		if (marker[node] == 2) {
			return true;
		} else if (marker[node] == 1) {
			return false;
		} else {
			marker[node] = 1;
			if (adj[node] != null) {
				for (Edge e : adj[node]) {
					if (e != blocked) {
						if (!isAcyclic(e.v, blocked)) {
							return false;
						}
					}
				}
			}
			marker[node] = 2;
			return true;
		}		
	}

}
