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.*;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class D {

	static class loop{
		int v1, v2;
		public loop(int aa, int bb) {
			v1 = aa;
			v2 = bb;
		}
		@Override
		public String toString() {
			return v1+"-"+v2;
		}
	}
	static class path{
		int v1, v2;
		public path(int aa, int bb) {
			v1 = aa;
			v2 = bb;
		}
	}
	static ArrayList<Integer> adj[];
	static ArrayList<ArrayList<path>> cyc = new ArrayList<ArrayList<path>>();
	static int N;
	//static boolean vis[];
	static HashMap<Integer, Integer> mm = new HashMap<Integer, Integer>();

	static int gggg;
	
	public static void main(String[] args) {
		FastScanner in = new FastScanner();
		int n = in.nextInt();
		int m = in.nextInt();
		N = n;
		adj = new ArrayList[n];
gggg=0;
		
		for(int i = 0; i < n; i++) adj[i] = new ArrayList<Integer>();
		
		for(int i = 0; i < m; i++) {
			int v1 = in.nextInt()-1;
			int v2 = in.nextInt()-1;
			adj[v1].add(v2);
		}
		int prev = -1;
		for(int i = 0; i < N; i++) {
			//System.out.println("i: "+i);
			bfs(new state(i, new ArrayList<path>()));
			int size = cyc.size();
			for(int go = prev+1; go < size; go++){
				//System.out.println("new path    size: "+size);
				boolean good = false;
				ArrayList<path> res = cyc.get(go);
				prev = go;
				for(path p : res) {
					int map = map(p.v1, p.v2);
					//System.out.println(p.v1+" -> "+p.v2);
					if(!mm.containsKey(map)) mm.put(map, 1);
					else {
						mm.put(map, mm.get(map)+1);
					}
					if(mm.get(map) == go+1) good = true;
					//System.out.println("  "+mm.get(map));
				}
				if(!good){
					System.out.println("NO");
					return;
				}
			}
			

		}
		

		 System.out.println("YES");

		


		
		
	}
	
	static int map(int x1, int x2) {
		return x1*N + x2;
	}
	
	static class state{
		int cur;
		ArrayList<path> set = new ArrayList<path>();
		public state(int cc, ArrayList<path> ss) {
			cur=cc;
			set = ss;
		}
		
	}
	
	static void bfs(state start) {
		ArrayDeque<state> q = new ArrayDeque<state>();
		boolean vis[] = new boolean[N];
		Arrays.fill(vis, false);
		q.add(start);
		vis[start.cur] = true;
		while(!q.isEmpty()) {
			state v = q.poll();
			
			
			for(int next : adj[v.cur]) {
				if(next == start.cur) {
					ArrayList<path> add = new ArrayList<path>();
					add.addAll(v.set);
					add.add(new path(v.cur, next));
					cyc.add(add);
					gggg++;
				}
				if(!vis[next]) {
					vis[next] = true;
					ArrayList<path> newlist = new ArrayList<path>();
					newlist.addAll(v.set);
					newlist.add(new path(v.cur, next));
					q.add(new state(next, newlist));
				}
			}
			
		}
		
	}

	
	static class FastScanner{
		BufferedReader br;
		StringTokenizer st;
		public FastScanner(String s) {
			try{
				br = new BufferedReader(new FileReader(s));
			}
			catch(FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		public FastScanner(){
			br = new BufferedReader(new InputStreamReader(System.in));
		}
		
		String nextToken()	{
			while(st == null ||!st.hasMoreElements()){
				try {
				st = new StringTokenizer(br.readLine());}
				catch(IOException e) {
					e.printStackTrace();
				}			
			}
			return st.nextToken();
		}
		
		int nextInt() {
			return Integer.parseInt(nextToken());
		}
		long nextLong() {
			return Long.parseLong(nextToken());
		}
		double nextDouble() {
			return Double.parseDouble(nextToken());
		}
		String next() {
			return nextToken();
		}
		
	}
}