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.
#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int grand(int x) { return uniform_int_distribution<int>(0, x - 1)(rng); }
const int maxn = 1e6 + 7;
const long long md = 1e9 + 7;
long long gcd(long long x, long long y) {
  if (x < y) return gcd(y, x);
  if (y == 0) return x;
  return gcd(y, x % y);
}
const long double inf = 1e18;
struct chtDynamic {
  struct line {
    long long m, b;
    long double x;
    long long val;
    bool isQuery;
    line(long long _m = 0, long long _b = 0)
        : m(_m), b(_b), val(0), x(-inf), isQuery(false) {}
    long long eval(long long x) const { return m * x + b; }
    bool parallel(const line &l) const { return m == l.m; }
    long double intersect(const line &l) const {
      return parallel(l) ? inf : 1.0 * (l.b - b) / (m - l.m);
    }
    bool operator<(const line &l) const {
      if (l.isQuery)
        return x < l.val;
      else
        return m < l.m;
    }
  };
  set<line> hull;
  bool cPrev(set<line>::iterator it) { return it != hull.begin(); }
  bool cNext(set<line>::iterator it) {
    return it != hull.end() && next(it) != hull.end();
  }
  bool bad(const line &l1, const line &l2, const line &l3) {
    return l1.intersect(l3) <= l1.intersect(l2);
  }
  bool bad(set<line>::iterator it) {
    return cPrev(it) && cNext(it) && bad(*prev(it), *it, *next(it));
  }
  set<line>::iterator update(set<line>::iterator it) {
    if (!cPrev(it)) return it;
    long double x = it->intersect(*prev(it));
    line tmp(*it);
    tmp.x = x;
    it = hull.erase(it);
    return hull.insert(it, tmp);
  }
  void addLine(long long m, long long b) {
    line l(m, b);
    set<line>::iterator it = hull.lower_bound(l);
    if (it != hull.end() && l.parallel(*it)) {
      if (it->b < b)
        it = hull.erase(it);
      else
        return;
    }
    it = hull.insert(it, l);
    if (bad(it)) return (void)hull.erase(it);
    while (cPrev(it) && bad(prev(it))) hull.erase(prev(it));
    while (cNext(it) && bad(next(it))) hull.erase(next(it));
    it = update(it);
    if (cPrev(it)) update(prev(it));
    if (cNext(it)) update(next(it));
  }
  long long query(long long x) const {
    if (hull.empty()) return -inf;
    line q;
    q.val = x, q.isQuery = 1;
    set<line>::iterator it = --hull.lower_bound(q);
    return it->eval(x);
  }
} ds;
pair<pair<long long, long long>, long long> A[maxn];
long long dp[maxn];
int main() {
  {
    ios ::sync_with_stdio(false);
    cin.tie(0);
  };
  int n;
  cin >> n;
  for (int j = 1; j <= n; j++) {
    cin >> A[j].first.first >> A[j].first.second >> A[j].second;
    A[j].second = A[j].first.first * A[j].first.second - A[j].second;
  }
  sort(A + 1, A + n + 1);
  long long ans = 0;
  ds.addLine(0, 0);
  for (int j = n; j >= 1; j--) {
    dp[j] = ds.query(A[j].first.first) + A[j].second;
    ds.addLine(-A[j].first.second, dp[j]);
    ans = max(ans, dp[j]);
  }
  cout << ans << "\n";
}
