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.lang.Math.*;
import java.util.*;

public final class AlmostAcyclic{

	public static void main(String args[]) throws Exception{

		int temp[] = Br.getIntA(2);
		int N = temp[0], M = temp[1];

		ArrayList<Integer> adj_list[] = new ArrayList[N+1];
		for(int i=1; i<N+1; i++) {
			adj_list[i] = new ArrayList<>();
		}

		for(int m=0; m<M; m++) {
			temp = Br.getIntA(2);
			adj_list[temp[0]].add(temp[1]);
		}

		ArrayList<Integer> cycle = new ArrayList<>();

		int t = 1;
		int n = 1;
		int s[] = new int[N+1];
		int e[] = new int[N+1];
		while(t != -2 && n <= N) {
			t = dfs(adj_list, n, t, s, e, cycle, -1, -1);
			n++;
		}

		// for(int i: cycle) {
		// 	System.out.print(i + " ");
		// }

		// System.out.println();

		if(isPossible(adj_list, cycle))
			println("YES");
		else
			println("NO");

	}

	// t : time available to assign
	// r_h, r_t = -1 if nothing to remove
	// return : next available time or -1 if cycle is found but nodes have to be added to cycle
	// 			or -2 if cycle is found and nodes have been added
	static int dfs(ArrayList<Integer> adj_list[], int cur, int t, int s[], int e[], ArrayList<Integer> cycle, 
					int r_h, int r_t) {
		if(e[cur] == 0) {
			s[cur] = t;
			t++;
			for(int nb : adj_list[cur]) {
				if(s[nb] != 0 && e[nb] == 0 && (r_h != cur || r_t != nb)) {
					cycle.add(nb);
					cycle.add(cur);
					return -1;
				}
			}

			for(int nb: adj_list[cur]) {
				if(r_h != cur || r_t != nb) {
					t = dfs(adj_list, nb, t, s, e, cycle, r_h, r_t);
					if(t == -1) {
						cycle.add(cur);
						return cycle.get(0) == cur ? -2 : -1;
					}

					if(t == -2) {
						return -2;
					}
				}
			}

			e[cur] = t;
			t++;
			return t;
		}

		return t;
	}

	static boolean isPossible(ArrayList<Integer> adj_list[], ArrayList<Integer> cycle) {
		if(cycle.size() == 0)
			return true;

		for(int i=1; i<cycle.size(); i++) {
			// System.out.println(cycle.get(i) + " " + cycle.get(i-1));
			int t = 1;
			int s[] = new int[adj_list.length];
			int e[] = new int[adj_list.length];
			ArrayList<Integer> cycle_new = new ArrayList<>();
			for(int n=1; n<adj_list.length; n++) {
				t = dfs(adj_list, n, t, s, e, cycle_new, cycle.get(i), cycle.get(i-1));
				if(t == -2)
					break;

			}

			// for(int j: cycle_new) {
			// 	System.out.print(j + " ");
			// }

			// System.out.println();

			if(t != -2)
				return true;

		}

		return false;
	}
 
	// class for Reader
	static class Br {

		final static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		static int getInt() throws IOException{
			return Integer.parseInt(br.readLine());
		}

		static long getLong() throws IOException{
			return Long.parseLong(br.readLine());
		}

		static double getDouble() throws IOException{
			return Double.parseDouble(br.readLine());
		}

		static int[] getIntA() throws IOException{
			String temp[] = br.readLine().split(" ");
			int l = temp.length;

			int a[] = new int[l];

			for(int i=0; i<l; i++){
				a[i] = Integer.parseInt(temp[i]);
			}

			return a;
		}

		static int[] getIntA(int l) throws IOException{
			String temp[] = br.readLine().split(" ");
			int a[] = new int[l];

			for(int i=0; i<l; i++){
				a[i] = Integer.parseInt(temp[i]);
			}

			return a;
		}

		static long[] getLongA(int l) throws IOException{
			String temp[] = br.readLine().split(" ");
			long a[] = new long[l];

			for(int i=0; i<l; i++){
				a[i] = Long.parseLong(temp[i]);
			}

			return a;
		}

		static String getString() throws IOException{
			return br.readLine();
		}

	}

	// class for MaTh libraries
	static class Mt{
		static double precision = 0.00001;

		static double sqrt(double a){
			return newton_raphson(a, a/2);
		}

		static double newton_raphson(double a, double guess){
			if(guess*guess - a <= precision)
				return guess;

			guess = guess - (guess * guess - a)/ (2 * guess);
			return newton_raphson(a, guess);
		}

		static long modPow(long a, long x, long p){

			long ans = 1;
			while(x > 0){
				if(x %2 !=0){
					ans = (ans*a)%p;
				}
				a = (a*a)%p;
				x/=2;
			}

			return (ans%p);
		}
	}

	static<T> void print(T s){
		System.out.print(s);
	}

	static<T> void println(T s){
		System.out.println(s);
	}
}