Problem: There is a strange peculiarity: if you connect the cities of Rostov, Taganrog and Shakhty, peculiarly, you get a triangle

«Unbelievable But True»

Students from many different parts of Russia and abroad come to Summer Informatics School. You marked the hometowns of the SIS participants on a map.

Now you decided to prepare an interesting infographic based on this map. The first thing you chose to do is to find three cities on this map, such that they form a triangle with area S.

Input

The first line of input contains two integers n and S (3 ≤ n ≤ 2000, 1 ≤ S ≤ 2 ⋅ 10^{18}) — the number of cities on the map and the area of the triangle to be found.

The next n lines contain descriptions of the cities, one per line. Each city is described by its integer coordinates x_i, y_i (-10^9 ≤ x_i, y_i ≤ 10^9). 

It is guaranteed that all cities are located at distinct points. It is also guaranteed that no three cities lie on the same line.

Output

If the solution doesn't exist — print «No».

Otherwise, print «Yes», followed by three pairs of coordinates (x, y) — the locations of the three cities, which form the triangle of area S.

Examples

Input

3 7
0 0
3 0
0 4


Output

No


Input

4 3
0 0
2 0
1 2
1 3


Output

Yes
0 0
1 3
2 0

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class D {
	static PrintWriter out = new PrintWriter(System.out);

	static int N;
	static long GOAL;
	static Vec ar[];
	static Vec pnts[];
	public static void main(String[] args) {
		FS in = new FS();
		N = in.nextInt();
		GOAL = in.nextLong()*2;
		ar = new Vec[N];
		for(int i = 0; i < N; i++) ar[i] = new Vec(in.nextLong(), in.nextLong(), i);
		Arrays.sort(ar);
		
		for(int i = 0; i < N; i++) ar[i].idInS = i;

		Seg segs[] = new Seg[(N*(N-1))/2];
		int idd = 0;
		for(int i = 0; i < N; i++)
			for(int j = i+1; j < N; j++)
				segs[idd++] = new Seg(ar[i],ar[j]).fix();
		
		Arrays.sort(segs);
		
		boolean found = false;
		for(int i = 0; i < segs.length; i++) {
			Seg cur = segs[i];
			swap(cur.a, cur.b);
			found |= bs(0, Math.min(cur.a.idInS, cur.b.idInS), cur.a, cur.b, false);
			found |= bs(Math.max(cur.a.idInS, cur.b.idInS), N-1, cur.a, cur.b, true);
		}
		if(found) {
			out.println("Yes");
			for(Vec v : pnts) out.println(v.x+" "+v.y);
		}
		else {
			out.println("No");
		}
		out.close();
	}
	
	static boolean bs(int lo, int hi, Vec a, Vec b, boolean hiLarger) {
		while(lo <= hi) {
			int mid = (lo+hi)>>1;
			long area = triAreaTimes2(ar[mid], a, b);
			if(area == GOAL) {
				pnts = new Vec[] {a,b,ar[mid]};
				return true;
			}
			if(area < GOAL) {
				if(hiLarger) lo = mid+1;
				else hi = mid-1;
			}
			else if(area > GOAL) {
				if(hiLarger) hi = mid-1;
				else lo = mid+1;
			}
		}
		return false;
	}
	
	static long triAreaTimes2(Vec a, Vec b, Vec c) {
		return (a.sub(c)).cross(b.sub(c));
	}
	
	
	static void swap(Vec lower, Vec higher) {
		if(lower.idInS >= higher.idInS) return;
		ar[lower.idInS] = higher;
		ar[higher.idInS] = lower;
		
		int tmp = higher.idInS;
		higher.idInS = lower.idInS;
		lower.idInS = tmp;
	}
	
	static class Vec implements Comparable<Vec>{
		long x,y;
		int id, idInS;
		public Vec(long xx, long yy) { x=xx; y=yy;}
		public Vec(long xx, long yy, int ii) {x=xx;y=yy;id=ii;}
		
		public Vec sub(Vec o) { return new Vec(x-o.x, y-o.y);}
		public Vec add(Vec o) { return new Vec(x+o.x, y+o.y);}
		public long cross(Vec o) { return x*o.y - y*o.x;}
		@Override
		public int compareTo(Vec o) {
			if(y != o.y) return Long.compare(y, o.y);
			return Long.compare(x, o.x);
		}
		@Override
		public String toString() {
			return "("+x+","+y+") s="+idInS;
		}
	}
	
	static class Seg implements Comparable<Seg>{
		Vec a, b, dir;
		public Seg(Vec aa, Vec bb) {
			a=aa;
			b=bb;
			dir=b.sub(a);
		}
		public Seg fix() {
			if(dir.y < 0 || (dir.y == 0 && dir.x < 0)) return new Seg(b,a);
			return this;
		}
		@Override
		public int compareTo(Seg o) {
			long c = dir.cross(o.dir);
			if(c > 0) return -1;
			if(c < 0) return 1;
			return 0;
		}
		@Override
		public String toString() {
			return "["+a+" -> "+b+"]";
		}
	}
	
	static class FS{
		BufferedReader br;
		StringTokenizer st;
		public FS() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}
		String next() {
			while(st == null || !st.hasMoreElements()) {
				try {st = new StringTokenizer(br.readLine());}
				catch(Exception e) { throw null;}
			}
			return st.nextToken();
		}
		int nextInt() { return Integer.parseInt(next());}
		double nextDouble() { return Double.parseDouble(next());}
		long nextLong() { return Long.parseLong(next());}
		int[] NIA(int n) {
			int r[] = new int[n];
			for(int i = 0; i < n; i++) r[i] = nextInt();
			return r;
		}
		long[] NLA(int n) {
			long r[] = new long[n];
			for(int i = 0; i < n; i++) r[i] = nextLong();
			return r;
		}
		char[][] grid(int r, int c){
			char res[][] = new char[r][c];
			for(int i = 0; i < r; i++) {
				char l[] = next().toCharArray();
				for(int j = 0; j < c; j++) {
					res[i][j] = l[j];
				}
			}
			return res;
		}
	}
	
}