#include <bits/stdc++.h>

using namespace std;

typedef pair <int , int> pii;
typedef long long ll;

const int N = 1e6+10;

//CHT it's a copied code
class CHT{
    typedef long long coef_t, coord_t, val_t;
//Line 'y=a*x+b' represented by 2 coefficients 'a' and 'b'
private:
    struct Line{
        coef_t a, b;
        double xLeft;
        enum Type {line, maxQuery, minQuery} type;
        coord_t val;
        explicit Line(coef_t aa=0, coef_t bb=0) : a(aa), b(bb), xLeft(-INFINITY), type(Type::line), val(0) {}
        val_t valueAt(coord_t x) const { return a*x+b; }
        friend bool areParallel(const Line& l1, const Line& l2) { return l1.a==l2.a; }
        friend double intersectX(const Line& l1, const Line& l2) { return areParallel(l1,l2)?INFINITY:1.0*(l2.b-l1.b)/(l1.a-l2.a); }
        bool operator<(const Line& l2) const{
            if (l2.type == line) return this->a < l2.a;
            if (l2.type == maxQuery) return this->xLeft < l2.val;
            if (l2.type == minQuery) return this->xLeft > l2.val;
            assert(0);
            return false;
        }
    };
private:
    bool            isMax; //whether or not saved envelope is top(search of max value)
    std::set<Line>  hull;  //envelope itself
private:
    bool hasPrev(std::set<Line>::iterator it) { return it!=hull.begin(); }
    bool hasNext(std::set<Line>::iterator it) { return it!=hull.end() && std::next(it)!=hull.end(); }
    bool irrelevant(const Line& l1, const Line& l2, const Line& l3) { return intersectX(l1,l3) <= intersectX(l1,l2); }
    bool irrelevant(std::set<Line>::iterator it){
        return hasPrev(it) && hasNext(it) && ((isMax && irrelevant(*std::prev(it), *it, *std::next(it)))
                                              || (!isMax && irrelevant(*std::next(it), *it, *std::prev(it))));
    }
    std::set<Line>::iterator updateLeftBorder(std::set<Line>::iterator it){
        if ((isMax && !hasPrev(it)) || (!isMax && !hasNext(it))) return it;
        double val = intersectX(*it, isMax?*std::prev(it):*std::next(it));
        Line buf(*it);
        it = hull.erase(it), buf.xLeft = val, it = hull.insert(it, buf);
        return it;
    }
public:
    explicit CHT(): isMax(true) {} // true is for max and false is for min
    void addLine(coef_t a, coef_t b){
        Line l3 = Line(a, b);
        auto it = hull.lower_bound(l3);
        if (it!=hull.end() && areParallel(*it, l3)){
            if ((isMax && it->b < b) || (!isMax && it->b > b)) it = hull.erase(it);
            else return;
        }
        it = hull.insert(it, l3);
        if (irrelevant(it)) { hull.erase(it); return; }
        while (hasPrev(it) && irrelevant(std::prev(it))) hull.erase(std::prev(it));
        while (hasNext(it) && irrelevant(std::next(it))) hull.erase(std::next(it));
        it = updateLeftBorder(it);
        if (hasPrev(it)) updateLeftBorder(std::prev(it));
        if (hasNext(it)) updateLeftBorder(std::next(it));
    }
    val_t getBest(coord_t x) const{
        Line q;
        q.val = x, q.type = isMax ? Line::Type::maxQuery : Line::Type::minQuery;
        auto bestLine = hull.lower_bound(q);
        if (isMax) --bestLine;
        return bestLine->valueAt(x);
    }
};
//CHT

int x[N] , y[N] , a[N];

int32_t main()
{
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n;
    cin >> n;
    vector <pii> v;
    for(int i = 0 ; i < n ; i++){
        cin >> x[i] >> y[i] >> a[i];
        v.push_back({y[i] , i});
    }
    sort(v.rbegin() , v.rend());
    ll ans = 0;
    CHT cht;
    cht.addLine(0 , 0);
    for(int i = 0 ; i < n ; i++){
        int id = v[i].second;
        ll val = 1ll * x[id] * y[id] - a[id] + cht.getBest(y[id]);
        ans = max(ans , val);
        cht.addLine(-x[id] , val);
    }
    cout << ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair <int , int> pii;

const int N = 1e6+10 , mod = 1e9+7;

 double intersect(pair <int , ll> x , pair <int , ll> y){
   return (double)(y.second - x.second) / (x.first - y.first);
}

int32_t main(){
   ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
   int n;
   cin >> n;
   vector < pair <pii , ll> > v;
   for(int i = 0 ; i < n ; i++){
      int x , y;
      ll a;
      cin >> x >> y >> a;
      v.push_back({{x , y} , a});
   }
   ll ans = 0;
   sort(v.begin() , v.end());
   set < pair <int , ll> > s;
   for(int i = 0 ; i < n ; i++){
      int x = v[i].first.first , y = v[i].first.second;
      ll a = v[i].second;
      while(s.size() > 1){
         auto it = s.begin();
         auto xx = *it;
         it++;
         auto yy = *it;
         xx.first = -xx.first;
         yy.first = -yy.first;
         if(intersect(xx , yy) >= y){
            s.erase(s.begin());
         }
         else
            break;
      }
      ll dp = 1ll * x * y - a;
      if(s.size()){
         auto xx = *s.begin();
         dp = max(dp , xx.second - 1ll * xx.first * y + 1ll * x * y - a);
      }
      while(s.size() > 1){
         auto it = s.end();
         it--;
         auto xx = *it;
         it--;
         auto yy = *it;
         xx.first = -xx.first;
         yy.first = -yy.first;
         if(intersect({-x , dp} , yy) >= intersect(xx , yy)){
            it++;
            s.erase(it);
         }
         else
            break;
      }
      /*
      s.insert({x , dp});
      cout << i << ":" << endl;
      for(auto xxx : s)
         cout << xxx.first << " " << xxx.second << endl;*/
      ans = max(ans , dp);
   }
   cout << ans;
   return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair <int , int> pii;

const int N = 1e6+10 , mod = 1e9+7;

double intersect(pair <int , ll> x , pair <int , ll> y){
   return (double)(y.second - x.second) / (x.first - y.first);
}

int32_t main(){
   ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
   int n;
   cin >> n;
   vector < pair <pii , ll> > v;
   for(int i = 0 ; i < n ; i++){
      int x , y;
      ll a;
      cin >> x >> y >> a;
      v.push_back({{x , y} , a});
   }
   ll ans = 0;
   sort(v.begin() , v.end());
   set < pair <int , ll> > s;
   for(int i = 0 ; i < n ; i++){
      int x = v[i].first.first , y = v[i].first.second;
      ll a = v[i].second;
      ll dp = 1ll * x * y - a;
      if(s.size()){
         auto xx = *s.begin();
         dp = max(dp , xx.second - 1ll * xx.first * y + 1ll * x * y - a);
      }
      while(s.size() > 1){
         auto it = s.end();
         it--;
         auto xx = *it;
         it--;
         auto yy = *it;
         xx.first = -xx.first;
         yy.first = -yy.first;
         if(intersect({-x , dp} , yy) >= intersect(xx , yy)){
            it++;
            s.erase(it);
         }
         else
            break;
      }
      s.insert({x , dp});
      //cout << dp << endl;
      ans = max(ans , dp);
   }
   cout << ans;
   return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair <int , int> pii;

const int N = 1e6+10 , mod = 1e9+7;

int32_t main(){
   ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
   int n;
   cin >> n;
   vector < pair <pii , ll> > v;
   for(int i = 0 ; i < n ; i++){
      int x , y;
      ll a;
      cin >> x >> y >> a;
      v.push_back({{x , y} , a});
   }
   ll ans = 0;
   sort(v.begin() , v.end());
   set < pair <int , ll> > s;
   for(int i = 0 ; i < n ; i++){
      int x = v[i].first.first , y = v[i].first.second;
      ll a = v[i].second;
      while(s.size() > 1){
         auto it = s.begin();
         auto xx = *it;
         it++;
         auto yy = *it;
         if(yy.second - 1ll * yy.first * y >= xx.second + 1ll * xx.first * y)
            s.erase(s.begin());
         else
            break;
      }
      ll dp = 1ll * x * y - a;
      if(s.size()){
         auto xx = *s.begin();
         dp = max(dp , xx.second - 1ll * xx.first * y + 1ll * x * y - a);
      }
      if(s.empty() || (*s.rbegin()).second < dp)
         s.insert({x , dp});
      //cout << dp << endl;
      ans = max(ans , dp);
   }
   cout << ans;
   return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2,tune=native")
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define fst first
#define snd second
#define rep(i, st, ed) for(int i=st; i<(int)ed; i++)
#define repn(i, st, ed) for(int i=st; i<=(int)ed; i++)
#define repb(i, ed, st) for(int i=ed; i>=(int)st; i--)
#define trav(x, v) for(auto &x: v)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define RANDOM_GEN(st, ed)  uniform_int_distribution<int>(st, ed)(rng)
#define sz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound
#define popb pop_back

using ll = long long;
using ld = long double;

using pi = pair<int,int>;
using pl = pair<ll, ll>;
using pd = pair<ld, ld>;

using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<ld>;
using vpi = vector<pi>;

const int N = 2e5 + 10;
const int M = 1e9 + 7;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;

template <class T> using oset = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;
template<class T> void chmax(T &a,T b) { if (a<b) a=b;}
template<class T> void chmin(T &a,T b) { if (a>b) a=b;}
template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;
template<typename T>
using maxpq = priority_queue<T>;

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << to_string(H) << endl;
  debug_out(T...);
}
#define LOCAL 3
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

class ConvexHullDynamic
{
    struct Line
    {
        long long a, b;
        long double xLeft;
        enum Type {line, maxQuery, minQuery} type;
        long long val;
        explicit Line(long long aa=0, long long bb=0) : a(aa), b(bb), xLeft(-INFINITY), type(Type::line), val(0) {}
        long long valueAt(long long x) const { return a*x+b; }
        friend bool areParallel(const Line& l1, const Line& l2) { return l1.a==l2.a; }
        friend long double intersectX(const Line& l1, const Line& l2) { return areParallel(l1,l2)?INFINITY:1.0*(l2.b-l1.b)/(l1.a-l2.a); }
        bool operator<(const Line& l2) const
        {
            if (l2.type == line)
                return this->a < l2.a;
            if (l2.type == maxQuery)
                return this->xLeft < l2.val;
            if (l2.type == minQuery)
                return this->xLeft > l2.val;
            return false;
        }
    };
    bool isMax;
    set<Line>  hull;
    bool hasPrev(set<Line>::iterator it) { return it!=hull.begin(); }
    bool hasNext(set<Line>::iterator it) { return it!=hull.end() && next(it)!=hull.end(); }
    bool irrelevant(const Line& l1, const Line& l2, const Line& l3) { return intersectX(l1,l3) <= intersectX(l1,l2); }
    bool irrelevant(set<Line>::iterator it)
    {
        return hasPrev(it) && hasNext(it) && ((isMax && irrelevant(*prev(it), *it, *next(it)))
                       || (!isMax && irrelevant(*next(it), *it, *prev(it))) );
    }
    set<Line>::iterator updateLeftBorder(set<Line>::iterator it)
    {
        if ((isMax && !hasPrev(it)) || (!isMax && !hasNext(it))) return it;
        long double val = intersectX(*it, isMax?*prev(it):*next(it));
        Line buf(*it);
        it = hull.erase(it);
        buf.xLeft = val;
        it = hull.insert(it, buf);
        return it;
    }
public:
    explicit ConvexHullDynamic(bool _isMax): isMax(_isMax) {}
    void addLine(long long a, long long b)
    {
        Line l3 = Line(a, b);
        auto it = hull.lower_bound(l3);
        if (it!=hull.end() && areParallel(*it, l3))
        {
            if ((isMax && it->b < b) || (!isMax && it->b > b))
                it = hull.erase(it);
            else
                return;
        }
        it = hull.insert(it, l3);
        if (irrelevant(it)) { hull.erase(it); return; }
        while (hasPrev(it) && irrelevant(prev(it))) hull.erase(prev(it));
        while (hasNext(it) && irrelevant(next(it))) hull.erase(next(it));
        it = updateLeftBorder(it);
        if (hasPrev(it))
            updateLeftBorder(prev(it));
        if (hasNext(it))
            updateLeftBorder(next(it));
    }
    long long getBest(long long x) const
    {
        Line q;
        q.val = x;
        q.type = isMax ? Line::Type::maxQuery : Line::Type::minQuery;
        auto bestLine = hull.lower_bound(q);
        if (isMax) --bestLine;
        return bestLine->valueAt(x);
    }
};
ConvexHullDynamic hull(1);

void solve()
{
	int n;
	scanf("%d", &n);
	vector<pair<pl,ll>> vp;
	rep(i, 0, n){
		int x, y, a;
		scanf("%d %d %d", &x, &y, &a);
		vp.pb(mp(mp(x, y), a));
	}
	sort(all(vp), [&](pair<pl,ll> a, pair<pl, ll> b){
		if(a.fst.fst == b.fst.fst) return a.fst.snd > b.fst.snd;
		return a.fst.fst < b.fst.fst;
		});
	hull.addLine(0, 0);
	ll ans = 0;
	rep(i, 0, n){
		ll cx = vp[i].fst.fst;
		ll cy = vp[i].fst.snd;
		ll a = vp[i].snd;
		ll z = hull.getBest(cy) + cx*cy - a;
		hull.addLine(-cx, z);
		chmax(ans, z);
	}
	printf("%I64d", ans);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cout << fixed;
	cout << setprecision(12);

	// Write code before test cases

	// solving test cases

	int tests = 1;
	//cin >> tests;
	while(tests--) solve();

#ifndef ONLINE_JUDGE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int dp[N];

int getval(int m, int c, int x)
{
	return m*x + c;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		int n = vp.size() - 1;
		int v1 = getval(vp.back().first, vp.back().second, y);
		int v2 = getval(vp[n-1].first, vp[n-1].second, y);
		if(v1 < v2) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	int i1 = (b.second - a.second)*(b.first - c.first);
	int i2 = (a.first - b.first)*(c.second - b.second);
	return i1 < i2;
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

signed main()
{
	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	sort(p.begin(), p.end());
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = cx*cy - a + c + m*cy;
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(-cx, dp[i+1]));
	}
	//for(int i=0; i<=n; i++) cout << dp[i] << " ";
	//cout << '\n';
	cout << ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int dp[N];

int getval(int m, int c, int x)
{
	return m*x + c;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		int n = vp.size() - 1;
		int v1 = getval(vp.back().first, vp.back().second, y);
		int v2 = getval(vp[n-1].first, vp[n-1].second, y);
		if(v1 < v2) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	int i1 = (b.second - a.second)*(b.first - c.first);
	int i2 = (a.first - b.first)*(c.second - b.second);
	return i1 < i2;
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	sort(p.begin(), p.end());
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = cx*cy - a + c + m*cy;
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(-cx, dp[i+1]));
	}
	//for(int i=0; i<=n; i++) cout << dp[i] << " ";
	//cout << '\n';
	cout << ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int dp[N];
int INF = 1e18;
int check(int m1, int m2, int c1, int c2, int x)
{
	int aa = (m1 - m2) * x;
	int bb = c2 - c1;
	return aa > bb;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		if(check(vp[0].first, vp[1].first, vp[0].second, vp[1].second, y)) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	double i1 = (b.second - a.second)/(double)(a.first - b.first);
	double i2 = (c.second - b.second)/(double)(b.first - c.first);
	return (i1 > i2);
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	auto cmp = [&](pair<pair<int,int>,int> a, pair<pair<int,int>,int> b){
		if(a.first.first == b.first.first) return a.first.second < b.first.second;
		return a.first.first < b.first.first;
	};
	sort(p.begin(), p.end(), cmp);
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, -cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = (cx-m)*cy - a + c;
		dp[i+1] = max(dp[i+1], -INF);
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(cx, dp[i+1]));
		//cout << i << ": \n";
		//for(auto point: vp){
			//cout << point.first << " " << point.second << '\n';
		//}
	}
	//for(int i=0; i<=n; i++) cout << dp[i] << " ";
	//cout << '\n';
	cout << ans << '\n';
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2,tune=native")
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define fst first
#define snd second
#define rep(i, st, ed) for(int i=st; i<(int)ed; i++)
#define repn(i, st, ed) for(int i=st; i<=(int)ed; i++)
#define repb(i, ed, st) for(int i=ed; i>=(int)st; i--)
#define trav(x, v) for(auto &x: v)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define RANDOM_GEN(st, ed)  uniform_int_distribution<int>(st, ed)(rng)
#define sz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound
#define popb pop_back

using ll = long long;
using ld = long double;

using pi = pair<int,int>;
using pl = pair<ll, ll>;
using pd = pair<ld, ld>;

using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<ld>;
using vpi = vector<pi>;

const int N = 2e5 + 10;
const int M = 1e9 + 7;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;

template <class T> using oset = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;
template<class T> void chmax(T &a,T b) { if (a<b) a=b;}
template<class T> void chmin(T &a,T b) { if (a>b) a=b;}
template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;
template<typename T>
using maxpq = priority_queue<T>;

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << to_string(H) << endl;
  debug_out(T...);
}
#define LOCAL 3
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

class ConvexHullDynamic
{
    struct Line
    {
        long long a, b;
        long double xLeft;
        enum Type {line, maxQuery, minQuery} type;
        long long val;
        explicit Line(long long aa=0, long long bb=0) : a(aa), b(bb), xLeft(-INFINITY), type(Type::line), val(0) {}
        long long valueAt(long long x) const { return a*x+b; }
        friend bool areParallel(const Line& l1, const Line& l2) { return l1.a==l2.a; }
        friend long double intersectX(const Line& l1, const Line& l2) { return areParallel(l1,l2)?INFINITY:1.0*(l2.b-l1.b)/(l1.a-l2.a); }
        bool operator<(const Line& l2) const
        {
            if (l2.type == line)
                return this->a < l2.a;
            if (l2.type == maxQuery)
                return this->xLeft < l2.val;
            if (l2.type == minQuery)
                return this->xLeft > l2.val;
            return false;
        }
    };
    bool isMax;
    set<Line>  hull;
    bool hasPrev(set<Line>::iterator it) { return it!=hull.begin(); }
    bool hasNext(set<Line>::iterator it) { return it!=hull.end() && next(it)!=hull.end(); }
    bool irrelevant(const Line& l1, const Line& l2, const Line& l3) { return intersectX(l1,l3) <= intersectX(l1,l2); }
    bool irrelevant(set<Line>::iterator it)
    {
        return hasPrev(it) && hasNext(it) && ((isMax && irrelevant(*prev(it), *it, *next(it)))
                       || (!isMax && irrelevant(*next(it), *it, *prev(it))) );
    }
    set<Line>::iterator updateLeftBorder(set<Line>::iterator it)
    {
        if ((isMax && !hasPrev(it)) || (!isMax && !hasNext(it))) return it;
        long double val = intersectX(*it, isMax?*prev(it):*next(it));
        Line buf(*it);
        it = hull.erase(it);
        buf.xLeft = val;
        it = hull.insert(it, buf);
        return it;
    }
public:
    explicit ConvexHullDynamic(bool _isMax): isMax(_isMax) {}
    void addLine(long long a, long long b)
    {
        Line l3 = Line(a, b);
        auto it = hull.lower_bound(l3);
        if (it!=hull.end() && areParallel(*it, l3))
        {
            if ((isMax && it->b < b) || (!isMax && it->b > b))
                it = hull.erase(it);
            else
                return;
        }
        it = hull.insert(it, l3);
        if (irrelevant(it)) { hull.erase(it); return; }
        while (hasPrev(it) && irrelevant(prev(it))) hull.erase(prev(it));
        while (hasNext(it) && irrelevant(next(it))) hull.erase(next(it));
        it = updateLeftBorder(it);
        if (hasPrev(it))
            updateLeftBorder(prev(it));
        if (hasNext(it))
            updateLeftBorder(next(it));
    }
    long long getBest(long long x) const
    {
        Line q;
        q.val = x;
        q.type = isMax ? Line::Type::maxQuery : Line::Type::minQuery;
        auto bestLine = hull.lower_bound(q);
        if (isMax) --bestLine;
        return bestLine->valueAt(x);
    }
};
ConvexHullDynamic hull(1);

void solve()
{
	ll n;
	cin >> n;
	vector<pair<pl,ll>> vp;
	rep(i, 0, n){
		ll x, y, a;
		cin >> x >> y >> a;
		vp.pb(mp(mp(x, y), a));
	}
	sort(all(vp), [&](pair<pl,ll> a, pair<pl, ll> b){
		if(a.fst.fst == b.fst.fst) return a.fst.snd > b.fst.snd;
		return a.fst.fst < b.fst.fst;
		});
	hull.addLine(0, 0);
	ll ans = 0;
	rep(i, 0, n){
		ll cx = vp[i].fst.fst;
		ll cy = vp[i].fst.snd;
		ll a = vp[i].snd;
		ll z = hull.getBest(cy) + cx*cy - a;
		hull.addLine(-cx, z);
		chmax(ans, z);
	}
	cout << ans << endl;
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cout << fixed;
	cout << setprecision(12);

	// Write code before test cases

	// solving test cases

	int tests = 1;
	//cin >> tests;
	while(tests--) solve();

#ifndef ONLINE_JUDGE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2,tune=native")
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define fst first
#define snd second
#define rep(i, st, ed) for(int i=st; i<(int)ed; i++)
#define repn(i, st, ed) for(int i=st; i<=(int)ed; i++)
#define repb(i, ed, st) for(int i=ed; i>=(int)st; i--)
#define trav(x, v) for(auto &x: v)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define RANDOM_GEN(st, ed)  uniform_int_distribution<int>(st, ed)(rng)
#define sz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound
#define popb pop_back

using ll = long long;
using ld = long double;

using pi = pair<int,int>;
using pl = pair<ll, ll>;
using pd = pair<ld, ld>;

using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<ld>;
using vpi = vector<pi>;

const int N = 2e5 + 10;
const int M = 1e9 + 7;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;

template <class T> using oset = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;
template<class T> void chmax(T &a,T b) { if (a<b) a=b;}
template<class T> void chmin(T &a,T b) { if (a>b) a=b;}
template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;
template<typename T>
using maxpq = priority_queue<T>;

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << to_string(H) << endl;
  debug_out(T...);
}
#define LOCAL 3
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

class ConvexHullDynamic
{
    struct Line
    {
        long long a, b;
        long double xLeft;
        enum Type {line, maxQuery, minQuery} type;
        long long val;
        explicit Line(long long aa=0, long long bb=0) : a(aa), b(bb), xLeft(-INFINITY), type(Type::line), val(0) {}
        long long valueAt(long long x) const { return a*x+b; }
        friend bool areParallel(const Line& l1, const Line& l2) { return l1.a==l2.a; }
        friend long double intersectX(const Line& l1, const Line& l2) { return areParallel(l1,l2)?INFINITY:1.0*(l2.b-l1.b)/(l1.a-l2.a); }
        bool operator<(const Line& l2) const
        {
            if (l2.type == line)
                return this->a < l2.a;
            if (l2.type == maxQuery)
                return this->xLeft < l2.val;
            if (l2.type == minQuery)
                return this->xLeft > l2.val;
            return false;
        }
    };
    bool isMax;
    set<Line>  hull;
    bool hasPrev(set<Line>::iterator it) { return it!=hull.begin(); }
    bool hasNext(set<Line>::iterator it) { return it!=hull.end() && next(it)!=hull.end(); }
    bool irrelevant(const Line& l1, const Line& l2, const Line& l3) { return intersectX(l1,l3) <= intersectX(l1,l2); }
    bool irrelevant(set<Line>::iterator it)
    {
        return hasPrev(it) && hasNext(it) && ((isMax && irrelevant(*prev(it), *it, *next(it)))
                       || (!isMax && irrelevant(*next(it), *it, *prev(it))) );
    }
    set<Line>::iterator updateLeftBorder(set<Line>::iterator it)
    {
        if ((isMax && !hasPrev(it)) || (!isMax && !hasNext(it))) return it;
        long double val = intersectX(*it, isMax?*prev(it):*next(it));
        Line buf(*it);
        it = hull.erase(it);
        buf.xLeft = val;
        it = hull.insert(it, buf);
        return it;
    }
public:
    explicit ConvexHullDynamic(bool _isMax): isMax(_isMax) {}
    void addLine(long long a, long long b)
    {
        Line l3 = Line(a, b);
        auto it = hull.lower_bound(l3);
        if (it!=hull.end() && areParallel(*it, l3))
        {
            if ((isMax && it->b < b) || (!isMax && it->b > b))
                it = hull.erase(it);
            else
                return;
        }
        it = hull.insert(it, l3);
        if (irrelevant(it)) { hull.erase(it); return; }
        while (hasPrev(it) && irrelevant(prev(it))) hull.erase(prev(it));
        while (hasNext(it) && irrelevant(next(it))) hull.erase(next(it));
        it = updateLeftBorder(it);
        if (hasPrev(it))
            updateLeftBorder(prev(it));
        if (hasNext(it))
            updateLeftBorder(next(it));
    }
    long long getBest(long long x) const
    {
        Line q;
        q.val = x;
        q.type = isMax ? Line::Type::maxQuery : Line::Type::minQuery;
        auto bestLine = hull.lower_bound(q);
        if (isMax) --bestLine;
        return bestLine->valueAt(x);
    }
};
ConvexHullDynamic hull(1);

ll dp[N];

void solve()
{
	ll n;
	cin >> n;
	vector<pair<pl,ll>> vp;
	rep(i, 0, n){
		ll x, y, a;
		cin >> x >> y >> a;
		vp.pb(mp(mp(x, y), a));
	}
	sort(all(vp), [&](pair<pl,ll> a, pair<pl, ll> b){
		if(a.fst.fst == b.fst.fst) return a.fst.snd > b.fst.snd;
		return a.fst.fst < b.fst.fst;
		});
	hull.addLine(0, 0);
	dp[0] = 0;
	ll ans = 0;
	rep(i, 0, n){
		ll cx = vp[i].fst.fst;
		ll cy = vp[i].fst.snd;
		ll a = vp[i].snd;
		dp[i+1] = hull.getBest(cy) + cx*cy - a;
		hull.addLine(-cx, dp[i+1]);
		chmax(ans, dp[i+1]);
	}
	cout << ans << endl;
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cout << fixed;
	cout << setprecision(12);

	// Write code before test cases

	// solving test cases

	int tests = 1;
	//cin >> tests;
	while(tests--) solve();

#ifndef ONLINE_JUDGE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2,tune=native")
#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define fst first
#define snd second
#define rep(i, st, ed) for(int i=st; i<(int)ed; i++)
#define repn(i, st, ed) for(int i=st; i<=(int)ed; i++)
#define repb(i, ed, st) for(int i=ed; i>=(int)st; i--)
#define trav(x, v) for(auto &x: v)
#define all(v) v.begin(), v.end()
#define mp make_pair
#define pb push_back
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define RANDOM_GEN(st, ed)  uniform_int_distribution<int>(st, ed)(rng)
#define sz(x) (int)x.size()
#define lb lower_bound
#define ub upper_bound
#define popb pop_back

using ll = long long;
using ld = long double;

using pi = pair<int,int>;
using pl = pair<ll, ll>;
using pd = pair<ld, ld>;

using vi = vector<int>;
using vl = vector<ll>;
using vd = vector<ld>;
using vpi = vector<pi>;

const int N = 2e5 + 10;
const int M = 1e9 + 7;
const ll infl = 0x3f3f3f3f3f3f3f3fLL;
const int infi = 0x3f3f3f3f;

template <class T> using oset = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;
template<class T> void chmax(T &a,T b) { if (a<b) a=b;}
template<class T> void chmin(T &a,T b) { if (a>b) a=b;}
template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;
template<typename T>
using maxpq = priority_queue<T>;

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}

template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << to_string(H) << endl;
  debug_out(T...);
}
#define LOCAL 3
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

class ConvexHullDynamic
{
    struct Line
    {
        long long a, b;
        long double xLeft;
        enum Type {line, maxQuery, minQuery} type;
        long long val;
        explicit Line(long long aa=0, long long bb=0) : a(aa), b(bb), xLeft(-INFINITY), type(Type::line), val(0) {}
        long long valueAt(long long x) const { return a*x+b; }
        friend bool areParallel(const Line& l1, const Line& l2) { return l1.a==l2.a; }
        friend long double intersectX(const Line& l1, const Line& l2) { return areParallel(l1,l2)?INFINITY:1.0*(l2.b-l1.b)/(l1.a-l2.a); }
        bool operator<(const Line& l2) const
        {
            if (l2.type == line)
                return this->a < l2.a;
            if (l2.type == maxQuery)
                return this->xLeft < l2.val;
            if (l2.type == minQuery)
                return this->xLeft > l2.val;
            return false;
        }
    };
    bool isMax;
    set<Line>  hull;
    bool hasPrev(set<Line>::iterator it) { return it!=hull.begin(); }
    bool hasNext(set<Line>::iterator it) { return it!=hull.end() && next(it)!=hull.end(); }
    bool irrelevant(const Line& l1, const Line& l2, const Line& l3) { return intersectX(l1,l3) <= intersectX(l1,l2); }
    bool irrelevant(set<Line>::iterator it)
    {
        return hasPrev(it) && hasNext(it) && ((isMax && irrelevant(*prev(it), *it, *next(it)))
                       || (!isMax && irrelevant(*next(it), *it, *prev(it))) );
    }
    set<Line>::iterator updateLeftBorder(set<Line>::iterator it)
    {
        if ((isMax && !hasPrev(it)) || (!isMax && !hasNext(it))) return it;
        long double val = intersectX(*it, isMax?*prev(it):*next(it));
        Line buf(*it);
        it = hull.erase(it);
        buf.xLeft = val;
        it = hull.insert(it, buf);
        return it;
    }
public:
    explicit ConvexHullDynamic(bool _isMax): isMax(_isMax) {}
    void addLine(long long a, long long b)
    {
        Line l3 = Line(a, b);
        auto it = hull.lower_bound(l3);
        if (it!=hull.end() && areParallel(*it, l3))
        {
            if ((isMax && it->b < b) || (!isMax && it->b > b))
                it = hull.erase(it);
            else
                return;
        }
        it = hull.insert(it, l3);
        if (irrelevant(it)) { hull.erase(it); return; }
        while (hasPrev(it) && irrelevant(prev(it))) hull.erase(prev(it));
        while (hasNext(it) && irrelevant(next(it))) hull.erase(next(it));
        it = updateLeftBorder(it);
        if (hasPrev(it))
            updateLeftBorder(prev(it));
        if (hasNext(it))
            updateLeftBorder(next(it));
    }
    long long getBest(long long x) const
    {
        Line q;
        q.val = x;
        q.type = isMax ? Line::Type::maxQuery : Line::Type::minQuery;
        auto bestLine = hull.lower_bound(q);
        if (isMax) --bestLine;
        return bestLine->valueAt(x);
    }
};
ConvexHullDynamic hull(1);

void solve()
{
	int n;
	scanf("%d", &n);
	vector<pair<pl,ll>> vp;
	rep(i, 0, n){
		ll x, y, a;
		scanf("%lld %lld %lld", &x, &y, &a);
		vp.pb(mp(mp(x, y), a));
	}
	sort(all(vp), [&](pair<pl,ll> a, pair<pl, ll> b){
		if(a.fst.fst == b.fst.fst) return a.fst.snd > b.fst.snd;
		return a.fst.fst < b.fst.fst;
		});
	hull.addLine(0, 0);
	ll ans = 0;
	rep(i, 0, n){
		ll cx = vp[i].fst.fst;
		ll cy = vp[i].fst.snd;
		ll a = vp[i].snd;
		ll z = hull.getBest(cy) + cx*cy - a;
		hull.addLine(-cx, z);
		chmax(ans, z);
	}
	printf("%I64d", ans);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cout << fixed;
	cout << setprecision(12);

	// Write code before test cases

	// solving test cases

	int tests = 1;
	//cin >> tests;
	while(tests--) solve();

#ifndef ONLINE_JUDGE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int dp[N];

int getval(int m, int c, int x)
{
	return m*x + c;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		int v1 = getval(vp.front().first, vp.front().second, y);
		int v2 = getval(vp[1].first, vp[1].second, y);
		if(v1 > v2) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	int i1 = (b.second - a.second)*(b.first - c.first);
	int i2 = (a.first - b.first)*(c.second - b.second);
	return i1 < i2;
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	auto cmp = [&](pair<pair<int,int>,int> a, pair<pair<int,int>,int> b){
		if(a.first.first == b.first.first) return a.first.second > b.first.second;
		return a.first.first < b.first.first;
	};
	sort(p.begin(), p.end(), cmp);
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = cx*cy - a + c + m*cy;
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(-cx, dp[i+1]));
	}
	//for(int i=0; i<=n; i++) cout << dp[i] << " ";
	//cout << '\n';
	cout << ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int dp[N];

int check(int m1, int m2, int c1, int c2, int x)
{
	int aa = (m1 - m2) * x;
	int bb = c2 - c1;
	return aa > bb;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		if(check(vp[0].first, vp[1].first, vp[0].second, vp[1].second, y)) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	int i1 = (b.second - a.second)*(b.first - c.first);
	int i2 = (a.first - b.first)*(c.second - b.second);
	return i1 > i2;
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	auto cmp = [&](pair<pair<int,int>,int> a, pair<pair<int,int>,int> b){
		if(a.first.first == b.first.first) return a.first.second > b.first.second;
		return a.first.first < b.first.first;
	};
	sort(p.begin(), p.end(), cmp);
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, -cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = (cx-m)*cy - a + c;
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(cx, dp[i+1]));
	}
	//for(int i=0; i<=n; i++) cout << dp[i] << " ";
	//cout << '\n';
	cout << ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int dp[N];

int getval(int m, int c, int x)
{
	return m*x + c;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		int n = vp.size() - 1;
		int v1 = getval(vp.back().first, vp.back().second, y);
		int v2 = getval(vp[n-1].first, vp[n-1].second, y);
		if(v1 < v2) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	int i1 = (b.second - a.second)*(b.first - c.first);
	int i2 = (a.first - b.first)*(c.second - b.second);
	return i1 < i2;
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

int main()
{
	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	sort(p.begin(), p.end());
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = cx*cy - a + c + m*cy;
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(-cx, dp[i+1]));
	}
	//for(int i=0; i<=n; i++) cout << dp[i] << " ";
	//cout << '\n';
	cout << ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int dp[N];

int getval(int m, int c, int x)
{
	return m*x + c;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		int n = vp.size() - 1;
		int v1 = getval(vp.back().first, vp.back().second, y);
		int v2 = getval(vp[n-1].first, vp[n-1].second, y);
		if(v1 < v2) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	int i1 = (b.second - a.second)*(b.first - c.first);
	int i2 = (a.first - b.first)*(c.second - b.second);
	return i1 < i2;
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	auto cmp = [&](pair<pair<int,int>,int> a, pair<pair<int,int>,int> b){
		if(a.first.first == b.first.first) return a.first.second > b.first.second;
		return a.first.first < b.first.first;
	};
	sort(p.begin(), p.end(), cmp);
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = cx*cy - a + c + m*cy;
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(-cx, dp[i+1]));
	}
	//for(int i=0; i<=n; i++) cout << dp[i] << " ";
	//cout << '\n';
	cout << ans << '\n';
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 10;
int dp[N];

int getval(int m, int c, int x)
{
	return m*x + c;
}

void fix(vector<pair<int,int>> &vp, int y)
{
	while(true)
	{
		if(vp.size() == 1) break;
		int v1 = getval(vp.front().first, vp.front().second, y);
		int v2 = getval(vp[1].first, vp[1].second, y);
		if(v1 > v2) break;
		vp.erase(vp.begin());
	}
}

int intersect(pair<int,int> a, pair<int,int> b, pair<int,int> c)
{
	int i1 = (b.second - a.second)*(b.first - c.first);
	int i2 = (a.first - b.first)*(c.second - b.second);
	return i1 < i2;
}

void insert(vector<pair<int,int>> &vp, pair<int,int> l)
{
	while(true){
		if(vp.size() == 1) break;
		int n = vp.size() - 1;

		if(intersect(l, vp[n], vp[n-1])) break;
		vp.pop_back();
	}
	vp.push_back(l);
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	int n;
	cin >> n;
	vector<pair<pair<int,int>,int>> p;
	for(int i=0; i<n; i++){
		int x, y, a;
		cin >> x >> y >> a;
		p.push_back({{x, y}, a});
	}
	auto cmp = [&](pair<pair<int,int>,int> a, pair<pair<int,int>,int> b){
		if(a.first.first == b.first.first) return a.first.second > b.first.second;
		return a.first.first < b.first.first;
	};
	sort(p.begin(), p.end(), cmp);
	vector<pair<int,int>> vp;
	vp.emplace_back(0, 0);
	dp[0] = 0;
	int ans = 0;
	for(int i=0; i<n; i++){
		int cx = p[i].first.first;
		int cy = p[i].first.second;
		int a = p[i].second;
		fix(vp, cy);
		int m = 0, c = 0;
		if(!vp.empty()){
			m = vp.front().first;
			c = vp.front().second;
		}
		dp[i+1] = cx*cy - a + c + m*cy;
		ans = max(ans, dp[i+1]);
		insert(vp, make_pair(-cx, dp[i+1]));
	}
	for(int i=0; i<=n; i++) cout << dp[i] << " ";
	cout << '\n';
	cout << ans << '\n';
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh;
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) > (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	idx = min(idx, (int)cvh.size() - 1);
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	cvh.push_back({ 0,0 });
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	int s = 0, e = cvh.size() - 2;
	while (s <= e) {
		int m = (s + e) >> 1;
		if (cvh[m].first*y + cvh[m].second <= cvh[m + 1].first*y + cvh[m + 1].second) {
			s = m + 1;
		}
		else {
			e = m;
		}
	}
	ret = cvh[s].first*y + cvh[s].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) >= (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh;
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) < (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	idx = min(idx, (int)cvh.size() - 1);
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	cvh.push_back({ 0,0 });
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh;
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) > (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 2].first)) {
		cvh.pop_back();
	}
	idx = min(idx, (int)cvh.size() - 1);
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	cvh.push_back({ 0,0 });
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	int s = 0, e = cvh.size() - 2;
	while (s <= e) {
		int m = (s + e) >> 1;
		if (cvh[m].first*y + cvh[m].second <= cvh[m + 1].first*y + cvh[m + 1].second) {
			s = m + 1;
		}
		else {
			e = m - 1;
		}
	}
	ret = cvh[s].first*y + cvh[s].second + 1LL * x*y - a;
	while (cvh.size() > 1 && double(cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) / (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first) > double(cvh[cvh.size() - 1].second - ret) / (cvh[cvh.size() - 1].first - A)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#define tout cerr
#else
#define TEST(n) ((void)0)
#define tout cin
#endif

using namespace std;

struct lichao
{
	int l, r;
	long long A, B;
	lichao() : l(0), r(0), A(-0x7fffffff), B(-0x7fffffff) {}
};

vector<tuple<int,int,long long>> A;
lichao tree[6000000];
int cp=1;

int get_sign(long long a)
{
	return a<0 ? -1:a>0;
}

void update(long long A, long long B, int p=1, double s=1, double e=1e9)
{
	double m=(s+e)/2;
	long long &cA=tree[p].A, &cB=tree[p].B;
	if(cA*m+cB<A*m+B) {
		swap(cA,A);
		swap(cB,B);
	}
	if(cA*s+cB>=A*s+B && cA*e+cB>=A*e+B) return;
	if(get_sign(cA*s+cB-(A*s+B))*get_sign(cA*m+cB-(A*m+B))<=0) {
		if(tree[p].l==0) tree[p].l=++cp;
		update(A,B,tree[p].l,s,m);
	}
	else {
		if(tree[p].r==0) tree[p].r=++cp;
		update(A,B,tree[p].r,m,e);
	}
}

long long query(int x, int p=1, double s=1, double e=1e9)
{
	double m=(s+e)/2;
	if(p==0) return -0x7fffffffffffffffLL;
	return max(tree[p].A*x+tree[p].B,x<=m ? query(x,tree[p].l,s,m):query(x,tree[p].r,m,e));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N, x, y;
	long long a, ans=0;
	cin>>N;
	A.resize(N);
	for(int i=0;i<N;i++) {
		cin>>x>>y>>a;
		A[i]=make_tuple(x,y,a);
	}
	sort(A.begin(),A.end());
	update(0,0);
	for(int i=0;i<N;i++) {
		tie(x,y,a)=A[i];
		long long D=query(y)+1LL*x*y-a;
		update(-x,D);
		ans=max(ans,D);
	}
	cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#define tout cerr
#else
#define TEST(n) ((void)0)
#define tout cin
#endif

using namespace std;

struct lichao
{
	int l, r;
	long long A, B;
	lichao() : l(0), r(0), A(-0x7fffffff), B(-0x7fffffff) {}
};

vector<tuple<int,int,long long>> A;
lichao tree[6000000];
int cp=1;

int get_sign(long long a)
{
	return a<0 ? -1:a>0;
}

void update(long long A, long long B, int p=1, int s=1, int e=1e9)
{
	double m=(s+e)/2;
	long long &cA=tree[p].A, &cB=tree[p].B;
	if(cA*m+cB<A*m+B) {
		swap(cA,A);
		swap(cB,B);
	}
	if(cA*s+cB>=A*s+B && cA*e+cB>=A*e+B) return;
	if(get_sign(cA*s+cB-(A*s+B))*get_sign(cA*m+cB-(A*m+B))<=0) {
		if(tree[p].l==0) tree[p].l=++cp;
		update(A,B,tree[p].l,s,m);
	}
	else {
		if(tree[p].r==0) tree[p].r=++cp;
		update(A,B,tree[p].r,m,e);
	}
}

long long query(int x, int p=1, double s=1, double e=1e9)
{
	double m=(s+e)/2;
	if(p==0) return -0x7fffffffffffffffLL;
	return max(tree[p].A*x+tree[p].B,x<=m ? query(x,tree[p].l,s,m):query(x,tree[p].r,m,e));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N, x, y;
	long long a, ans=0;
	cin>>N;
	A.resize(N);
	for(int i=0;i<N;i++) {
		cin>>x>>y>>a;
		A[i]=make_tuple(x,y,a);
	}
	sort(A.begin(),A.end());
	update(0,0);
	for(int i=0;i<N;i++) {
		tie(x,y,a)=A[i];
		long long D=query(y)+1LL*x*y-a;
		update(-x,D);
		ans=max(ans,D);
	}
	cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -y, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*x + cvh[idx].second <= cvh[idx + 1].first*x + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*x + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) >= (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	idx = min(idx, (int)cvh.size() - 1);
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#define tout cerr
#else
#define TEST(n) ((void)0)
#define tout cin
#endif

using namespace std;

struct lichao
{
	int l, r;
	long long A, B;
	lichao() : l(0), r(0), A(-0x7fffffff), B(-0x7fffffff) {}
};

vector<tuple<int,int,long long>> A;
lichao tree[30000000];
int cp=1;

int get_sign(long long a)
{
	return a<0 ? -1:a>0;
}

void update(long long A, long long B, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	long long &cA=tree[p].A, &cB=tree[p].B;
	if(cA*m+cB<A*m+B) {
		swap(cA,A);
		swap(cB,B);
	}
	if(cA*s+cB>=A*s+B && cA*e+cB>=A*e+B) return;
	if(get_sign(cA*s+cB-(A*s+B))*get_sign(cA*m+cB-(A*m+B))<=0) {
		if(tree[p].l==0) tree[p].l=++cp;
		update(A,B,tree[p].l,s,m);
	}
	else {
		if(tree[p].r==0) tree[p].r=++cp;
		update(A,B,tree[p].r,m+1,e);
	}
}

long long query(int x, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	if(p==0) return -0x7fffffffffffffffLL;
	return max(tree[p].A*x+tree[p].B,x<=m ? query(x,tree[p].l,s,m):query(x,tree[p].r,m+1,e));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N, x, y;
	long long a, ans=0;
	cin>>N;
	A.resize(N);
	for(int i=0;i<N;i++) {
		cin>>x>>y>>a;
		A[i]=make_tuple(x,y,a);
	}
	sort(A.begin(),A.end());
	update(0,0);
	for(int i=0;i<N;i++) {
		tie(x,y,a)=A[i];
		long long D=query(y)+1LL*x*y-a;
		update(-x,D);
		ans=max(ans,D);
	}
	cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second <= cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) >= (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	idx = min(idx, (int)cvh.size() - 1);
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	int s = 0, e = cvh.size() - 2;
	while (s <= e) {
		int m = (s + e) >> 1;
		if (cvh[m].first*y + cvh[m].second <= cvh[m + 1].first*y + cvh[m + 1].second) {
			s = m + 1;
		}
		else {
			e = m - 1;
		}
	}
	ret = cvh[s].first*y + cvh[s].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) >= (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#define tout cerr
#else
#define TEST(n) ((void)0)
#define tout cin
#endif

using namespace std;

struct lichao
{
	int l, r;
	long long A, B;
	lichao() : l(0), r(0), A(-0x7fffffff), B(-0x7fffffff) {}
};

vector<tuple<int,int,long long>> A;
lichao tree[6000000];
int cp=1;

int get_sign(long long a)
{
	return a<0 ? -1:a>0;
}

void update(long long A, long long B, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	long long &cA=tree[p].A, &cB=tree[p].B;
	if(cA*m+cB<A*m+B) {
		swap(cA,A);
		swap(cB,B);
	}
	if(cA*s+cB>=A*s+B && cA*e+cB>=A*e+B) return;
	if(get_sign(cA*s+cB-(A*s+B))*get_sign(cA*m+cB-(A*m+B))<=0) {
		if(tree[p].l==0) tree[p].l=++cp;
		update(A,B,tree[p].l,s,m);
	}
	else {
		if(tree[p].r==0) tree[p].r=++cp;
		update(A,B,tree[p].r,m+1,e);
	}
}

long long query(int x, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	if(p==0) return -0x7fffffffffffffffLL;
	return max(tree[p].A*x+tree[p].B,x<=m ? query(x,tree[p].l,s,m):query(x,tree[p].r,m+1,e));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N, x, y;
	long long a, ans=0;
	cin>>N;
	A.resize(N);
	for(int i=0;i<N;i++) {
		cin>>x>>y>>a;
		A[i]=make_tuple(x,y,a);
	}
	sort(A.begin(),A.end());
	update(0,0);
	for(int i=0;i<N;i++) {
		tie(x,y,a)=A[i];
		long long D=query(y)+1LL*x*y-a;
		update(-x,D);
		ans=max(ans,D);
	}
	cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	int s = 0, e = cvh.size() - 1;
	while (s <= e) {
		int m = (s + e) >> 1;
		if (cvh[m].first*y + cvh[m].second <= cvh[m + 1].first*y + cvh[m + 1].second) {
			s = m + 1;
		}
		else {
			e = m - 1;
		}
	}
	ret = cvh[s].first*y + cvh[s].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) >= (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#define tout cerr
#else
#define TEST(n) ((void)0)
#define tout cin
#endif

using namespace std;

struct lichao
{
	int l, r;
	long long A, B;
	lichao() : l(0), r(0), A(-0x7fffffff), B(-0x7fffffff) {}
};

vector<tuple<int,int,int>> A;
vector<lichao> tree(2);

int get_sign(long long a)
{
	return a<0 ? -1:a>0;
}

void update(long long A, long long B, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	long long &cA=tree[p].A, &cB=tree[p].B;
	if(cA*m+cB<A*m+B) {
		swap(cA,A);
		swap(cB,B);
	}
	if(cA*s+cB>=A*s+B && cA*e+cB>=A*e+B) return;
	if(get_sign(cA*s+cB-(A*s+B))*get_sign(cA*m+cB-(A*m+B))<=0) {
		if(tree[p].l==0) tree[p].l=tree.size(), tree.push_back(lichao());
		update(A,B,tree[p].l,s,m);
	}
	else {
		if(tree[p].r==0) tree[p].r=tree.size(), tree.push_back(lichao());
		update(A,B,tree[p].r,m+1,e);
	}
}

long long query(int x, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	if(p==0) return -0x7fffffffffffffffLL;
	return max(tree[p].A*x+tree[p].B,x<=m ? query(x,tree[p].l,s,m):query(x,tree[p].r,m+1,e));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N, x, y, a;
	long long ans=0;
	cin>>N;
	A.resize(N);
	for(int i=0;i<N;i++) {
		cin>>x>>y>>a;
		A[i]=make_tuple(x,y,a);
	}
	sort(A.begin(),A.end());
	update(0,0);
	for(int i=0;i<N;i++) {
		tie(x,y,a)=A[i];
		long long D=query(y)+1LL*x*y-a;
		update(-x,D);
		ans=max(ans,D);
	}
	cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#define tout cerr
#else
#define TEST(n) ((void)0)
#define tout cin
#endif

using namespace std;

struct lichao
{
	int l, r;
	long long A, B;
	lichao() : l(0), r(0), A(-0x7fffffff), B(-0x7fffffff) {}
};

vector<tuple<int,int,long long>> A;
lichao tree[6000000];
int cp=1;

int get_sign(double a)
{
	return a<0 ? -1:a>0;
}

void update(long long A, long long B, int p=1, double s=1, double e=1e9)
{
	double m=(s+e)/2;
	long long &cA=tree[p].A, &cB=tree[p].B;
	if(cA*m+cB<A*m+B) {
		swap(cA,A);
		swap(cB,B);
	}
	if(cA*s+cB>=A*s+B && cA*e+cB>=A*e+B) return;
	if(get_sign(cA*s+cB-(A*s+B))*get_sign(cA*m+cB-(A*m+B))<=0) {
		if(tree[p].l==0) tree[p].l=++cp;
		update(A,B,tree[p].l,s,m);
	}
	else {
		if(tree[p].r==0) tree[p].r=++cp;
		update(A,B,tree[p].r,m,e);
	}
}

long long query(int x, int p=1, double s=1, double e=1e9)
{
	double m=(s+e)/2;
	if(p==0) return -0x7fffffffffffffffLL;
	return max(tree[p].A*x+tree[p].B,x<=m ? query(x,tree[p].l,s,m):query(x,tree[p].r,m,e));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N, x, y;
	long long a, ans=0;
	cin>>N;
	A.resize(N);
	for(int i=0;i<N;i++) {
		cin>>x>>y>>a;
		A[i]=make_tuple(x,y,a);
	}
	sort(A.begin(),A.end());
	update(0,0);
	for(int i=0;i<N;i++) {
		tie(x,y,a)=A[i];
		long long D=query(y)+1LL*x*y-a;
		update(-x,D);
		ans=max(ans,D);
	}
	cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	int s = 0, e = cvh.size() - 2;
	while (s <= e) {
		int m = (s + e) >> 1;
		if (cvh[m].first*y + cvh[m].second <= cvh[m + 1].first*y + cvh[m + 1].second) {
			s = m + 1;
		}
		else {
			e = m - 1;
		}
	}
	ret = cvh[s].first*y + cvh[s].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) >= (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh;
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) > (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	idx = min(idx, (int)cvh.size() - 1);
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	cvh.push_back({ 0,0 });
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, int>> P;
vector<pair<long long, long long>> cvh;
int idx;

long long solve(int x, int y, int a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) > (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 2].first)) {
		cvh.pop_back();
	}
	idx = min(idx, (int)cvh.size() - 1);
	cvh.push_back({ A,ret });
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	cvh.push_back({ 0,0 });
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#define tout cerr
#else
#define TEST(n) ((void)0)
#define tout cin
#endif

using namespace std;

struct lichao
{
	int l, r;
	long long A, B;
	lichao() : l(0), r(0), A(-0x7fffffff), B(-0x7fffffff) {}
};

vector<tuple<int,int,long long>> A;
vector<lichao> tree(2);

int get_sign(long long a)
{
	return a<0 ? -1:a>0;
}

void update(long long A, long long B, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	long long &cA=tree[p].A, &cB=tree[p].B;
	if(cA*m+cB<A*m+B) {
		swap(cA,A);
		swap(cB,B);
	}
	if(cA*s+cB>=A*s+B && cA*e+cB>=A*e+B) return;
	if(get_sign(cA*s+cB-(A*s+B))*get_sign(cA*m+cB-(A*m+B))<=0) {
		if(tree[p].l==0) tree[p].l=tree.size(), tree.push_back(lichao());
		update(A,B,tree[p].l,s,m);
	}
	else {
		if(tree[p].r==0) tree[p].r=tree.size(), tree.push_back(lichao());
		update(A,B,tree[p].r,m+1,e);
	}
}

long long query(int x, int p=1, int s=1, int e=1000000000)
{
	int m=(s+e)>>1;
	if(p==0) return -0x7fffffffffffffffLL;
	return max(tree[p].A*x+tree[p].B,x<=m ? query(x,tree[p].l,s,m):query(x,tree[p].r,m+1,e));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N, x, y;
	long long a, ans=0;
	cin>>N;
	A.resize(N);
	for(int i=0;i<N;i++) {
		cin>>x>>y>>a;
		A[i]=make_tuple(x,y,a);
	}
	sort(A.begin(),A.end());
	update(0,0);
	for(int i=0;i<N;i++) {
		tie(x,y,a)=A[i];
		long long D=query(y)+1LL*x*y-a;
		update(-x,D);
		ans=max(ans,D);
	}
	cout<<ans<<'\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh;
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && (cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) * (cvh[cvh.size() - 1].first - A) > (cvh[cvh.size() - 1].second - ret) * (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	//idx = min(idx, (int)cvh.size() - 1);
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	cvh.push_back({ 0,0 });
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && double(cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) / (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first) > double(cvh[cvh.size() - 1].second - ret) / (cvh[cvh.size() - 1].first - A)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	idx = min(idx, (int)cvh.size() - 1);
	return ret;
}

int main()
{
    ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <bits/stdc++.h>

#ifdef NON_SUBMIT
#define TEST(n) (n)
#else
#define TEST(n) ((void)0)
#endif

using namespace std;

vector<tuple<int, int, long long>> P;
vector<pair<long long, long long>> cvh(1);
int idx;

long long solve(int x, int y, long long a)
{
	long long A = -x, ret;
	while (idx + 1 < cvh.size() && cvh[idx].first*y + cvh[idx].second < cvh[idx + 1].first*y + cvh[idx + 1].second) idx++;
	ret = cvh[idx].first*y + cvh[idx].second + 1LL * x*y - a;
	while (cvh.size() > 1 && double(cvh[cvh.size() - 2].second - cvh[cvh.size() - 1].second) / (cvh[cvh.size() - 2].first - cvh[cvh.size() - 1].first) > double(cvh[cvh.size() - 1].second - ret) / (cvh[cvh.size() - 1].first - A)) {
		cvh.pop_back();
	}
	cvh.push_back({ A,ret });
	idx = min(idx, (int)cvh.size() - 1);
	return ret;
}

int main()
{
	TEST(freopen("input.txt", "r", stdin));
	TEST(freopen("output.txt", "w", stdout));
	TEST(freopen("debug.txt", "w", stderr));
	int N;
	long long ans = 0;
	cin >> N;
	P.resize(N);
	for (auto &[x, y, a] : P) cin >> x >> y >> a;
	sort(P.begin(), P.end());
	for (auto[x, y, a] : P) {
		ans = max(ans, solve(x, y, a));
	}
	cout << ans << '\n';
	return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    float tmp1 = (float)(B[l3]-B[l1]) / (float)(B[l2]-B[l1]);
    float tmp2 = (float)(A[l1]-A[l3]) / (float)(A[l1]-A[l2]);
    return tmp1 <= tmp2;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
const float EPSILON = 1e-9;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    return (B[l3]-B[l1])*(A[l1]-A[l2]) - (B[l2]-B[l1])*(A[l1]-A[l3]) >= EPSILON;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
const float EPSILON = 1e-9;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    return (B[l3]-B[l1])*(A[l1]-A[L2]) - (B[l2]-B[l1])*(A[l1]-A[l3]) > EPSILON;
    return tmp1 >= tmp2;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
const int N = 1e6+5;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    float tmp1 = (float)(B[l3]-B[l1]) / (float)(B[l2]-B[l1]);
    float tmp2 = (float)(A[l1]-A[l3]) / (float)(A[l1]-A[l2]);
    return tmp1 < tmp2;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, dp[N], x, y, a;
re rect[N];

signed main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> x >> y >> a; rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    cout << mx;
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
const float EPSILON = 1e-9;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    return (float)(B[l3]-B[l1])/(float)(A[l1]-A[l3]) + EPSILON > (float)(B[l2]-B[l1])/(float)(A[l1]-A[l2]);
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    //dp[0] = rect[0].x*rect[0].y - rect[0].a;
    //add(-rect[0].x,dp[0]);
    add(0,0);
    for (int i = 0; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
const float EPSILON = 1e-9;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    return (B[l3]-B[l1])*(A[l1]-A[l2]) - (B[l2]-B[l1])*(A[l1]-A[l3]) > EPSILON;
    return tmp1 >= tmp2;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
const float EPSILON = 1e-9;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    return (B[l3]-B[l1])/(A[l1]-A[l3])+EPSILON > (B[l2]-B[l1])/(A[l1]-A[l2]);
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    //dp[0] = rect[0].x*rect[0].y - rect[0].a;
    //add(-rect[0].x,dp[0]);
    add(0,0);
    for (int i = 0; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
const float EPSILON = 1e-9;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    return (B[l3]-B[l1])/(A[l1]-A[l3)+EPSILON > (B[l2]-B[l1])/(A[l1]-A[l2]);
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    //dp[0] = rect[0].x*rect[0].y - rect[0].a;
    //add(-rect[0].x,dp[0]);
    add(0,0);
    for (int i = 0; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    float tmp1 = (float)(B[l3]-B[l1]) / (float)(A[l1]-A[l3]);
    float tmp2 = (float)(B[l2]-B[l1]) / (float)(A[l1]-A[l2]);
    return tmp1 >= tmp2;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
const float EPSILON = 1e-9;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    return (B[l3]-B[l1])*(A[l1]-A[l2]) - (B[l2]-B[l1])*(A[l1]-A[l3]) >= EPSILON;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    //dp[0] = rect[0].x*rect[0].y - rect[0].a;
    //add(-rect[0].x,dp[0]);
    add(0,0);
    for (int i = 0; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    float tmp1 = (float)(B[l3]-B[l1]) / (float)(B[l2]-B[l1]);
    float tmp2 = (float)(A[l1]-A[l3]) / (float)(A[l1]-A[l2]);
    return tmp1 >= tmp2;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define int long long
#define float long double
#define push_back emplace_back
const int N = 1e6+5;
struct re
{
    int x, y, a;
    bool operator < (const re &o) const
    {
        return x < o.x;
    }
};

vector<int> A, B;
int pointer;

bool bad(int l1, int l2, int l3)
{
    float tmp1 = (float)(B[l3]-B[l1]) / (float)(B[l2]-B[l1]);
    float tmp2 = (float)(A[l1]-A[l3]) / (float)(A[l1]-A[l2]);
    return tmp1 < tmp2;
}

void add(int a, int b)
{
    A.push_back(a);
    B.push_back(b);
    while(A.size() >= 3 && bad(A.size()-3,A.size()-2,A.size()-1))
    {
        A.erase(A.end()-2);
        B.erase(B.end()-2);
    }
}

int query(int x)
{
    if (pointer >= A.size())
        pointer = A.size()-1;
    while(pointer < A.size()-1 && A[pointer]*x + B[pointer] < A[pointer+1]*x + B[pointer+1])
        pointer++;
    return A[pointer]*x+B[pointer];
}

int n, x, y, a;
long long dp[N];
re rect[N];

signed main()
{
    scanf("%lld",&n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld %lld %lld",&x,&y,&a);
        rect[i] = {x,y,a};
    }
    sort(rect,rect+n);
    //for (int i = 0; i < n; i++)
    //    cout << rect[i].x << ' ' << rect[i].y << ' ' << rect[i].a << endl;
    dp[0] = rect[0].x*rect[0].y - rect[0].a;
    add(-rect[0].x,dp[0]);
    for (int i = 1; i < n; i++)
    {
        dp[i] = query(rect[i].y) + rect[i].x*rect[i].y - rect[i].a;
        //cout << rect[i].y + rect[i].x*rect[i].y - rect[i].a << endl;
        //cout << dp[i] << endl;
        add(-rect[i].x,dp[i]);
    }
    int mx = 0;
    for (int i = 0; i < n; i++)
        mx = max(mx,dp[i]);
    printf("%lld",mx);
}