You are given n points on Cartesian plane. Every point is a lattice point (i. e. both of its coordinates are integers), and all points are distinct.

You may draw two straight lines (not necessarily distinct). Is it possible to do this in such a way that every point lies on at least one of these lines?

Input

The first line contains one integer n (1 ≤ n ≤ 105) — the number of points you are given.

Then n lines follow, each line containing two integers xi and yi (|xi|, |yi| ≤ 109)— coordinates of i-th point. All n points are distinct.

Output

If it is possible to draw two straight lines in such a way that each of given points belongs to at least one of these lines, print YES. Otherwise, print NO.

Examples

Input

5
0 0
0 1
1 1
1 -1
2 2


Output

YES


Input

5
0 0
1 0
2 1
1 1
2 3


Output

NO

Note

In the first example it is possible to draw two lines, the one containing the points 1, 3 and 5, and another one containing two remaining points.

<image>
import java.io.*;
import java.util.*;

public class Main {
	FastReader scn;
	PrintWriter out;
	String INPUT = "5\r\n" + "\r\n" + "0 0\r\n" + "\r\n" + "0 1\r\n" + "\r\n" + "1 1\r\n" + "\r\n" + "1 -1\r\n" + "\r\n"
			+ "2 2\r\n" + "";

	class point {
		int x, y, ind;

		@Override
		public boolean equals(Object c) {
			point p = (point) c;
			return p.ind == this.ind;
		}
	}

	class slope {
		long x, y;
		int code;

		public void get() {
			code = (int) ((39 * x + 97 * y) % 1000000007);
		}

		@Override
		public int hashCode() {
			get();
			return code;
		}

		@Override
		public boolean equals(Object o) {
			slope s = (slope) o;
			return this.x == s.x && this.y == s.y;
		}
	}

	point[] shuffle(point[] arr) {
		Random r = new Random();
		for (int i = 2; i < arr.length; i++) {
			int j = r.nextInt(i) + 1;
			point p = arr[i];
			arr[i] = arr[j];
			arr[j] = p;
		}
		return arr;
	}

	void solve() {
		int n = scn.nextInt();

		point[] arr = new point[n + 1];
		for (int i = 1; i <= n; i++) {
			arr[i] = new point();
			arr[i].ind = i;
			arr[i].x = scn.nextInt();
			arr[i].y = scn.nextInt();
		}

		if (n <= 4) {
			System.out.println("YES");
			return;
		}
		
		boolean ans = func(arr, n) || func(arr, n) || func(arr, n) || func(arr, n);
		if(ans) {
			out.println("YES");
		} else {
			out.println("NO");
		}
	}

	boolean func(point[] arr, int n) {
		arr = shuffle(arr);

		slope[] sl = new slope[n + 1];
		HashMap<slope, Integer> list = new HashMap<>();
		ArrayList<Integer>[] gr = new ArrayList[n + 1];

		for (int i = 0; i <= n; i++) {
			gr[i] = new ArrayList<>();
			sl[i] = new slope();
		}

		for (int i = 2; i <= n; i++) {
			long x = arr[i].x - arr[1].x, y = arr[i].y - arr[1].y;
			if (y == 0) {
				sl[i].x = 1;
				sl[i].y = 0;
			} else {
				long g = gcd(x, y);
				x /= g;
				y /= g;
				sl[i].x = x;
				sl[i].y = y;
			}

			slope s = new slope();
			s.x = sl[i].x;
			s.y = sl[i].y;

			if (list.containsKey(s)) {
				gr[list.get(s)].add(i);
			} else {
				list.put(s, i);
				gr[list.get(s)].add(i);
			}
		}

		if (list.size() == 2) {
			return true;
		}

		boolean[] mark = new boolean[n + 1];
		mark[1] = true;
		int max = 0, k = -1;
		for (int i = 1; i <= n; i++) {
			if (gr[i].size() > max) {
				k = i;
				max = gr[i].size();
			}
		}

		for (int z : gr[k]) {
			mark[z] = true;
		}

		int in = -1;
		for (int i = 1; i <= n; i++) {
			if (!mark[i]) {
				in = i;
				break;
			}
		}

		list = new HashMap<>();

		for (int i = 1; i <= n; i++) {
			if (mark[i] || in == i) {
				continue;
			}
			long x = arr[i].x - arr[in].x, y = arr[i].y - arr[in].y;
			if (y == 0) {
				sl[i].x = 1;
				sl[i].y = 0;
			} else {
				long g = gcd(x, y);
				x /= g;
				y /= g;
				sl[i].x = x;
				sl[i].y = y;
			}

			slope s = new slope();
			s.x = sl[i].x;
			s.y = sl[i].y;

			if (list.containsKey(s)) {
				gr[list.get(s)].add(i);
			} else {
				list.put(s, i);
			}
		}

		if (list.size() > 1) {
			return false;
		} else {
			return true;
		}
	}

	long gcd(long a, long b) {
		return b == 0 ? a : gcd(b, a % b);
	}

	void run() throws Exception {
		boolean onlineJudge = System.getProperty("ONLINE_JUDGE") != null;
		out = new PrintWriter(System.out);
		scn = new FastReader(onlineJudge);
		long time = System.currentTimeMillis();
		solve();
		out.flush();
		if (!onlineJudge) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	class FastReader {
		InputStream is;

		public FastReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		}

		byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		char nextChar() {
			return (char) skip();
		}

		String next() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		char[] next(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		int nextInt() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		long nextLong() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		char[][] nextMatrix(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = next(m);
			return map;
		}

		int[] nextArray(int n, boolean isOneInd) {
			int k = isOneInd ? 1 : 0;
			int[] a = new int[n + k];
			for (int i = k; i < n + k; i++)
				a[i] = nextInt();
			return a;
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				arr[i] = arr[i] ^ arr[j];
				arr[j] = arr[i] ^ arr[j];
				arr[i] = arr[i] ^ arr[j];
			}
			return arr;
		}
	}
}