The Fair Nut got stacked in planar world. He should solve this task to get out.

You are given n rectangles with vertexes in (0, 0), (x_i, 0), (x_i, y_i), (0, y_i). For each rectangle, you are also given a number a_i. Choose some of them that the area of union minus sum of a_i of the chosen ones is maximum.

It is guaranteed that there are no nested rectangles.

Nut has no idea how to find the answer, so he asked for your help.

Input

The first line contains one integer n (1 ≤ n ≤ 10^6) — the number of rectangles.

Each of the next n lines contains three integers x_i, y_i and a_i (1 ≤ x_i, y_i ≤ 10^9, 0 ≤ a_i ≤ x_i ⋅ y_i).

It is guaranteed that there are no nested rectangles.

Output

In a single line print the answer to the problem — the maximum value which you can achieve.

Examples

Input


3
4 4 8
1 5 0
5 2 10


Output


9

Input


4
6 2 4
1 6 2
2 4 3
5 3 8


Output


10

Note

In the first example, the right answer can be achieved by choosing the first and the second rectangles.

In the second example, the right answer can also be achieved by choosing the first and the second rectangles.
import java.io.*;
import java.util.*;

public class gym{
	static class convexHullMax{
		LinkedList<long[]> hull;
		convexHullMax(){
			hull=new LinkedList<long[]>();
		}
		//inserting lines ax+b , where cur[0]=a,cur[1]=b
		//insertion should be in decreasing order of a
		void add_line(long[]cur) {
			while(!hull.isEmpty() && cur[0]==hull.getLast()[0]) {
				hull.pollLast();
			}
		    while(hull.size()>=2) {
		    	long[]mid=hull.pollLast();
		    	if(check(cur,mid,hull.getLast())) {
		    		hull.addLast(mid);
		    		break;
		    	}
		    }
		    hull.addLast(cur);
		}
		
		//intersection of mid and small should be before intersection of mid and big
		static boolean check(long[]small,long[]mid,long[]big) {
			return (small[1]-mid[1])/(mid[0]-small[0])<(mid[1]-big[1])/(big[0]-mid[0]);
			
		}
		
		//queries should be in decreasing order
		long getMax(long x) {
		    while(hull.size()>=2) {
		    	long[]first=hull.pollFirst();
		    	if(first[0]*x+first[1]>hull.getFirst()[0]*x+hull.getFirst()[1]) {
		    		hull.addFirst(first);
		    		break;
		    	}
		    }
		    
		    long[]bestLine=hull.getFirst();
		    long a=bestLine[0],b=bestLine[1];//the line that has the maximum value at x
		    return (a*x+b);
		}
		
	}
	static void main() throws Exception{
		int n=sc.nextInt();
		long[][]in=new long[n][];
		for(int i=0;i<n;i++)in[i]=sc.longArr(3);
		Arrays.sort(in,(x,y)->Long.compare(x[0], y[0]));
		convexHullMax ch=new convexHullMax();
		ch.add_line(new long[] {0,0});
		long ans=Long.MIN_VALUE;
		for(int i=0;i<n;i++) {
			long dpi=in[i][0]*in[i][1]-in[i][2]+ch.getMax(in[i][1]);
			ans=Math.max(ans, dpi);
			ch.add_line(new long[] {-in[i][0],dpi});
		}
		pw.println(ans);
	}
	public static void main(String[] args) throws Exception{
		sc=new MScanner(System.in);
		pw = new PrintWriter(System.out);
		int tc=1;
//		tc=sc.nextInt();
		while(tc-->0)
			main();
		pw.flush();
	}
	static PrintWriter pw;
	static MScanner  sc;
	static class MScanner {
		StringTokenizer st;
		BufferedReader br;
		public MScanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}
 
		public MScanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}
 
		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public int[] intArr(int n) throws IOException {
	        int[]in=new int[n];for(int i=0;i<n;i++)in[i]=nextInt();
	        return in;
		}
		public long[] longArr(int n) throws IOException {
	        long[]in=new long[n];for(int i=0;i<n;i++)in[i]=nextLong();
	        return in;
		}
		public int[] intSortedArr(int n) throws IOException {
	        int[]in=new int[n];for(int i=0;i<n;i++)in[i]=nextInt();
	        shuffle(in);
	        Arrays.sort(in);
	        return in;
		}
		public long[] longSortedArr(int n) throws IOException {
	        long[]in=new long[n];for(int i=0;i<n;i++)in[i]=nextLong();
	        shuffle(in);
	        Arrays.sort(in);
	        return in;
		}
		public Integer[] IntegerArr(int n) throws IOException {
	        Integer[]in=new Integer[n];for(int i=0;i<n;i++)in[i]=nextInt();
	        return in;
		}
		public Long[] LongArr(int n) throws IOException {
	        Long[]in=new Long[n];for(int i=0;i<n;i++)in[i]=nextLong();
	        return in;
		}
		public String nextLine() throws IOException {
			return br.readLine();
		}
 
		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}
 
		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}
 
		public char nextChar() throws IOException {
			return next().charAt(0);
		}
 
		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}
 
		public boolean ready() throws IOException {
			return br.ready();
		}
 
		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
	static void shuffle(int[]in) {
		for(int i=0;i<in.length;i++) {
			int idx=(int)(Math.random()*in.length);
			int tmp=in[i];
			in[i]=in[idx];
			in[idx]=tmp;
		}
	}
	static void shuffle(long[]in) {
		for(int i=0;i<in.length;i++) {
			int idx=(int)(Math.random()*in.length);
			long tmp=in[i];
			in[i]=in[idx];
			in[idx]=tmp;
		}
	}
}