Problem: Iahub has drawn a set of n points in the cartesian plane which he calls "special points". A quadrilateral is a simple polygon without self-intersections with four sides (also called edges) and four vertices (also called corners). Please note that a quadrilateral doesn't have to be convex. A special quadrilateral is one which has all four vertices in the set of special points. Given the set of special points, please calculate the maximal area of a special quadrilateral. 

Input

The first line contains integer n (4 ≤ n ≤ 300). Each of the next n lines contains two integers: xi, yi ( - 1000 ≤ xi, yi ≤ 1000) — the cartesian coordinates of ith special point. It is guaranteed that no three points are on the same line. It is guaranteed that no two points coincide. 

Output

Output a single real number — the maximal area of a special quadrilateral. The answer will be considered correct if its absolute or relative error does't exceed 10 - 9.

Examples

Input

5
0 0
0 4
4 0
4 4
2 3


Output

16.000000

Note

In the test example we can choose first 4 points to be the vertices of the quadrilateral. They form a square by side 4, so the area is 4·4 = 16.

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Classy {
	static double ans;
	static Vector[] four;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int N = sc.nextInt();
		Vector[] array = new Vector[N];
		for(int a=0;a<N;a++){
			array[a]=new Vector(sc.nextDouble(),sc.nextDouble());
		}
		ans = 0;
		four = new Vector[4];
		for(int aa=0;aa<N;aa++){
			for(int bb=aa+1;bb<N;bb++){
				int P = 0;
				int M = 0;
				double pA = 0;
				double mA = 0;
				Vector BA = array[aa].sub(array[bb]);
				for(int cc=0;cc<N;cc++){
					if(cc==aa)continue;
					if(cc==bb)continue;
					Vector CA = array[aa].sub(array[cc]);
					double area = Math.abs(CA.cross(BA));
					if(CA.cross(BA)>0){
						if(area>pA){
							pA=area;
							P=cc;
						}
					}
					else{
						if(area>mA){
							mA=area;
							M=cc;
						}
					}
				}
				if(mA==0||pA==0)continue;
				four[0]=array[aa];
				four[1]=array[bb];
				four[2]=array[P];
				four[3]=array[M];
				permute(new int[4],0,new boolean[4],4);
			}
		}
		
		
		
		
		out.println(ans);
		out.close();
	}
	static void permute(int perm[], int pos, boolean[] used, int n) {
		if (pos == n) {
			Vector[] temp = new Vector[4];
			for(int a=0;a<4;a++){
				temp[a]=four[perm[a]];
			}
			double area = area(temp);
			if(area>ans)ans=area;
			return;
		}
		for (int pick = 0; pick < n; pick++) {
			if (!used[pick]) {
				perm[pos] = pick;
				used[pick] = true;
				permute(perm, pos + 1, used, n);
				used[pick] = false;
			}
		}
	}
	static double area(Vector[] p) {
		int n = p.length;
		double a = 0;
		for (int i = 0; i < n; i++)
			a += p[i].cross(p[(i + 1) % n]);
		return Math.abs(a / 2);
	}
	
	static class Vector implements Comparable<Vector> {
		double x, y;

		public Vector(double _x, double _y) {
			x = _x;
			y = _y;
		}

		public Vector sub(Vector p) {
			return new Vector(x - p.x, y - p.y);
		}

		public Vector add(Vector p) {
			return new Vector(x + p.x, y + p.y);
		}

		public Vector scale(double s) {
			return new Vector(x * s, y * s);
		}

		public Vector rot(double t) { // Rotate t radians counter-clockwise
			double c = Math.cos(t);
			double s = Math.sin(t);
			return new Vector(x * c - y * s, x * s + y * c);
		}

		public Vector orthoCCW() { // Rotate 90 degrees counter-clockwise
			return new Vector(-y, x);
		}

		public Vector norm() { // Return a vector with same angle and magnitude
								// 1
			return new Vector(x / mag(), y / mag());
		}

		public Vector project(Vector p) { // Return projection of this onto p
			return p.scale(dot(p) / p.dot(p));
		}

		public double dot(Vector p) {
			return x * p.x + y * p.y;
		}

		public double cross(Vector p) {
			return x * p.y - y * p.x;
		}

		public double mag() {
			return Math.sqrt(x * x + y * y);
		}

		public double mag2() {
			return x * x + y * y;
		}

		public double dis(Vector p) {
			return sub(p).mag();
		}

		public double ang() {
			return (Math.atan2(y, x) + 2 * Math.PI) % (2 * Math.PI);
		}

		public double angBetween(Vector p) { // Returns inner angle between two
												// vectors
			double d = Math.abs(ang() - p.ang());
			return Math.min(d, 2 * Math.PI - d);
		}

		public int compareTo(Vector p) {
			if (p.x == x)
				return (int) Math.signum(y - p.y);
			return (int) Math.signum(x - p.x);
		}

		public String toString() {
			return String.format("(%.3f, %.3f)", x, y);
		}
	}

	static class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(InputStream in) throws Exception {
			br = new BufferedReader(new InputStreamReader(in));
			st = new StringTokenizer(br.readLine().trim());
		}

		public int numTokens() throws Exception {
			if (!st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine().trim());
				return numTokens();
			}
			return st.countTokens();
		}

		public boolean hasNext() throws Exception {
			if (!st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine().trim());
				return hasNext();
			}
			return true;
		}

		public String next() throws Exception {
			if (!st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine().trim());
				return next();
			}
			return st.nextToken();
		}

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

		public float nextFloat() throws Exception {
			return Float.parseFloat(next());
		}

		public long nextLong() throws Exception {
			return Long.parseLong(next());
		}

		public int nextInt() throws Exception {
			return Integer.parseInt(next());
		}

		public String nextLine() throws Exception {
			return br.readLine();
		}
	}

}