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.
//package com.company;
 
import java.io.*;
import java.util.*;
 
public class Main {
    public static class Task {
        // dp[i] = max(dp[j] - a[i] + (y[i] - y[j]) * x[i]), j < i
        // dp[i] = max(dp[j] - x[i] * y[j]) - a[i] + x[i] * y[i]
        // (-y[j], dp[j])
        public class ConvexHullTrick {
            long[] A;
            long[] B; // Ax + b, A, negative, is decreasing, query point is always positive, decreasing
            int totalSize, queryPointAt;
            public ConvexHullTrick(int n) {
                A = new long[n];
                B = new long[n];
                totalSize = queryPointAt = 0;
            }
 
            public void insert(long a, long b) {
                while (totalSize > queryPointAt + 1 &&
                        (B[totalSize - 2] - B[totalSize - 1]) / (A[totalSize - 1] - A[totalSize - 2])  <=
                                (B[totalSize - 1] - b) / (a - A[totalSize - 1])) {
                    totalSize -= 1;
                }
                A[totalSize] = a;
                B[totalSize] = b;
                totalSize++;
            }
 
            public long evaluate(long a, long b, long x) {
                return a * x + b;
            }
 
            public long query(long x) {
                if (totalSize == queryPointAt) throw new RuntimeException();
                while (queryPointAt < totalSize - 1 && evaluate(A[queryPointAt], B[queryPointAt], x) <
                        evaluate(A[queryPointAt + 1], B[queryPointAt + 1], x)) {
                    queryPointAt++;
                }
                return evaluate(A[queryPointAt], B[queryPointAt], x);
            }
 
        }
        public void solve(Scanner sc, PrintWriter pw) throws IOException {
            int n = sc.nextInt();
            long[][] lines = new long[n][3];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < 3; j++) {
                    lines[i][j] = sc.nextLong();
                }
            }
            Arrays.sort(lines, new Comparator<long[]>() {
                @Override
                public int compare(long[] o1, long[] o2) {
                    return Long.compare(o2[0], o1[0]);
                }
            });
            long[] dp = new long[n];
            ConvexHullTrick cvt = new ConvexHullTrick(n);
            long initialDPVal = -lines[0][2] + lines[0][0] * lines[0][1];
            dp[0] = initialDPVal;
            cvt.insert(-lines[0][1], dp[0]);
            for (int i = 1; i < n; i++) {
                dp[i] = Math.max(0, cvt.query(lines[i][0])) - lines[i][2] + lines[i][0] * lines[i][1];
                initialDPVal = Math.max(initialDPVal, dp[i]);
                cvt.insert(-lines[i][1], dp[i]);
            }
            System.out.println(initialDPVal);
        }
    }
 
    static long TIME_START, TIME_END;
 
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
//        Scanner sc = new Scanner(new FileInputStream("input"));
        PrintWriter pw = new PrintWriter(new BufferedOutputStream(System.out));
//        PrintWriter pw = new PrintWriter(new FileOutputStream("output"));
 
        Runtime runtime = Runtime.getRuntime();
        long usedMemoryBefore = runtime.totalMemory() - runtime.freeMemory();
        TIME_START = System.currentTimeMillis();
        Task t = new Task();
        t.solve(sc, pw);
        TIME_END = System.currentTimeMillis();
        long usedMemoryAfter = runtime.totalMemory() - runtime.freeMemory();
        pw.close();
        System.err.println("Memory increased: " + (usedMemoryAfter - usedMemoryBefore) / 1000000);
        System.err.println("Time used: " + (TIME_END - TIME_START) + ".");
    }
 
    static class Scanner {
        StringTokenizer st;
        BufferedReader br;
 
        public Scanner(InputStream s) {
            br = new BufferedReader(new InputStreamReader(s));
        }
 
        public Scanner(FileReader s) throws FileNotFoundException {
            br = new BufferedReader(s);
        }
 
        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }
 
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
 
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
 
        public String nextLine() throws IOException {
            return br.readLine();
        }
 
        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }
 
        public boolean ready() throws IOException {
            return br.ready();
        }
    }
}
		 			    	 			 	 	 	   	 	 	 	