Problem:
I: 視程
問題
ある街には $N$ 個のビルが等間隔に $1$ 列に並んでいます。それぞれのビルの高さは $H_i$ $(1 \leq i \leq N)$ で与えられます。アライグマのアライくんは、あるビルの屋上からできるだけ遠くのビルを見下ろしたいと考えました。
アライくんは、全てのビルの屋上に登ってどれだけ遠くのビルを見下ろせるかを調べます。最大で何棟隣のビルまで見下ろすことができるでしょうか。
ただしビル $i,j$ ($i \lt j$ とする) のいずれかからもう一方を見下ろせるとは、$i$ と $j$ が以下の条件を満たすことを言います。
任意の $k(i \lt k \lt j)$ について 点 $(i,H_i)$ と点 $(j,H_j)$ を結ぶ線分と 点 $(k,0)$ と $(k,H_k)$ を結ぶ端点を含まない線分が交わらない
入力形式
$N$
$H_1$ $\ldots$ $H_N$
$1 \leq N \leq 100{,}000$
$1 \leq H_i \leq 10^{9}$
入力は全て整数で与えられる。
出力形式
答えを一行で出力し、最後に改行をしてください。
入力例 1
3
1 2 3
出力例 1
2
入力例 2
5
2 2 2 2 2
出力例 2
4
入力例 3
5
2 8 6 4 3
出力例 3
3

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define all(p) p.begin(),p.end()

std::vector<std::pair<long long,long long>> convex_hull(std::vector<std::pair<long long,long long>> P){
    /*
    Copyright (c) 2021 0214sh7
    https://github.com/0214sh7/library/
    */
    if(P.size()<=2){
        return P;
    }
    std::vector<std::pair<long long,long long>> H,L,R;
    sort(P.begin(),P.end());

    //下半分
    for(int i=0;i<(int)P.size();i++){
        int j=L.size();
        while(j>=2 && (L[j-1].first-L[j-2].first)*(P[i].second-L[j-2].second)<=(L[j-1].second-L[j-2].second)*(P[i].first-L[j-2].first)){
            L.pop_back();
            j--;
        }
        L.push_back(P[i]);
    }

    //上半分
    for(int i=(int)P.size()-1;i>=0;i--){
        int j=H.size();
        while(j>=2 && (H[j-1].first-H[j-2].first)*(P[i].second-H[j-2].second)<=(H[j-1].second-H[j-2].second)*(P[i].first-H[j-2].first)){
            H.pop_back();
            j--;
        }
        H.push_back(P[i]);
    }


    R=L;
    for(int i=1;i<H.size()-1;i++){
        R.push_back(H[i]);
    }

    return R;
}
void solve();
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t = 1;
    // cin >> t;
    rep(i, 0, t) solve();
}

void solve(){
    int N;
    cin >> N;
    vector<pair<ll, ll>> p(N);
    rep(i, 0, N) cin >> p[i].second, p[i].first = i;
    p.push_back({0, 0});
    p.push_back({N - 1, 0});
    auto R = convex_hull(p);
    R.push_back(R.front());
    ll ans = 0;
    rep(i, 1, R.size()){
        if (min(R[i].second, R[i - 1].second)) ans = max(ans, abs(R[i].first - R[i - 1].first));
    }
    cout << ans << "\n";
}
accuracy: 1
time_ms: 10
memory_kb: 7656
final_rank: 7

code_snippet: /*
 * @uni_kakurenbo
 * https://github.com/uni-kakurenbo/competitive-programming-workspace
 *
 * CC0 1.0  http://creativecommons.org/publicdomain/zero/1.0/deed.ja
 */
/* #language C++ 20 GCC */
// #define DEBUGGER_ENABLED

// #include "template/standard.hpp"

#include <bits/stdc++.h>

void solve();

signed main() {
    // debug(__cplusplus);
    int $ = 1;
    // std::cin >> $;
    for(int _ = 0; _ < $; ++_) {
        // debug_("Case: #" + std::to_string(_));
        solve();
    }
    return 0;
}

#include <atcoder/lazysegtree.hpp>
/* [begin]: template/warnings.hpp */
#pragma GCC diagnostic warning "-Wshadow=local"
/* [end]: template/warnings.hpp*/

long op(long a, long b) { return a + b; }
long e() { return 0; }
long id() { return 0; }
long comp(long x, long y) { return x + y; }
long map(long f, long x) { return f + x; }

std::vector<std::pair<long long,long long>> convex_hull(std::vector<std::pair<long long,long long>> P){

    if(P.size()<=2){
        return P;
    }
    std::vector<std::pair<long long,long long>> H,L,R;
    sort(P.begin(),P.end());

    for(int i=0;i<P.size();i++){
        int j=L.size();
        while(j>=2 && (L[j-1].first-L[j-2].first)*(P[i].second-L[j-2].second)<=(L[j-1].second-L[j-2].second)*(P[i].first-L[j-2].first)){
            L.pop_back();
            j--;
        }
        L.push_back(P[i]);
    }
    for(int i=P.size()-1;i>=0;i--){
        int j=H.size();
        while(j>=2 && (H[j-1].first-H[j-2].first)*(P[i].second-H[j-2].second)<=(H[j-1].second-H[j-2].second)*(P[i].first-H[j-2].first)){
            H.pop_back();
            j--;
        }
        H.push_back(P[i]);
    }


    R=L;
    for(int i=1;i<H.size()-1;i++){
        R.push_back(H[i]);
    }

    return R;
}

void solve() {
    int n; std::cin >> n;
    std::vector<long> h(n);
    for(auto& v : h) std::cin >> v;

    using P = std::pair<long long, long long>;
    std::vector<P> ps;
    for(int i : std::views::iota(0, n)) {
        ps.emplace_back(i, 0);
        ps.emplace_back(i, h[i]);
    }

    auto convex = convex_hull(ps);
    int m = convex.size();

    long long ans = 0;

    for(int i : std::views::iota(0, m)) {
        auto a = convex[i];
        auto b = convex[(i + 1) % m];

        if(a.second == 0 || b.second == 0) continue;

        ans = std::max(ans, std::abs(a.first - b.first));
    }

    std::cout << ans << "\n";
}
accuracy: 1
time_ms: 20
memory_kb: 11304
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); i++)
#define all(a) (a).begin(), (a).end()
using Real = ll;
using Point = complex<Real>;
const Real EPS = 1e-8, PI = acos(-1);

istream& operator>>(istream& is, Point& p) {
   Real a, b;
   is >> a >> b;
   p = Point(a, b);
   return is;
}
ostream& operator<<(ostream& os, Point p) { return os << fixed << p.real() << " " << p.imag(); }

Point operator*(Point p, Real d) { return Point(real(p) * d, imag(p) * d); }

Point operator/(Point p, Real d) { return Point(real(p) / d, imag(p) / d); }

inline bool equal(Real a, Real b) { return fabs(a - b) < EPS; }

Point unit(Point a) { return a / abs(a); }

Point normal(Point a) { return a * Point(0, 1); }

Point normalUnit(Point a) { return unit(normal(a)); }

Real dot(Point a, Point b) { return a.real() * b.real() + a.imag() * b.imag(); }

Real cross(Point a, Point b) { return (a.real() * b.imag() - a.imag() * b.real()); }

// 直線を含めない場合は <=-EPS を <EPS に変更する
vector<Point> convexHull(vector<Point>& p) {
   int n = (int)p.size(), k = 0;
   sort(all(p),
        [](const Point& a, const Point& b) { return (real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b)); });
   vector<Point> ch(2 * n);
   for(int i = 0; i < n; ch[k++] = p[i++]) {
      while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) >= 0) --k;
   }
   ch.resize(k);
   return ch;
}

int main(){
    int n;
    cin >> n;
    vector<int> h(n);
    rep(i, 0, n){
        cin >> h[i];
    }
    
    vector<Point> ps;
    rep(i, 0, n){
        ps.push_back(Point(i, h[i]));
    }


    auto res = convexHull(ps);

    ll ans = 0;
    rep(i, 0, res.size() - 1){
        ans = max(ans, res[i+1].real() - res[i].real());
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 9048
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define int long long
using namespace std;
long double slope(int x1, int y1, int x2, int y2) {
    return 1.0*(y2 - y1) / (x2 - x1);
}
signed main() {
    int n;
    cin >> n;
    vector <int> h;
    for(int i = 1;i <= n;i++) {
        int x;
        cin >> x;
        h.push_back(x);
    }
    int mx = 0;
    for (int dir = 1; dir >= -1; dir -= 2) {
        stack<int> s;
        for (int i = (dir == 1 ? 0 : n - 1); (dir == 1 ? i < n : i >= 0); i += dir) {
            while (s.size() >= 2) {
                int top1 = s.top(); s.pop();
                int top2 = s.top();
                if ((dir == 1 && slope(top2, h[top2], top1, h[top1]) > slope(top1, h[top1], i, h[i])) ||
                    (dir == -1 && slope(top2, h[top2], top1, h[top1]) < slope(top1, h[top1], i, h[i]))) {
                    s.push(top1);
                    break;
                }
            }
            if (!s.empty()) {
                mx = max(mx, abs(i - s.top()));
            }
            s.push(i);
        }
    }

   cout << mx << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3948
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define int long long
using namespace std;
long double slope(int x1, int y1, int x2, int y2) {
    return static_cast<double>(y2 - y1) / (x2 - x1);
}

void solve(int N, const vector<int>& heights) {
    int max_distance = 0;
    for (int dir = 1; dir >= -1; dir -= 2) {
        stack<int> s;
        for (int i = (dir == 1 ? 0 : N - 1); (dir == 1 ? i < N : i >= 0); i += dir) {
            while (s.size() >= 2) {
                int top1 = s.top(); s.pop();
                int top2 = s.top();
                if ((dir == 1 && slope(top2, heights[top2], top1, heights[top1]) > slope(top1, heights[top1], i, heights[i])) ||
                    (dir == -1 && slope(top2, heights[top2], top1, heights[top1]) < slope(top1, heights[top1], i, heights[i]))) {
                    s.push(top1);
                    break;
                }
            }
            if (!s.empty()) {
                max_distance = max(max_distance, abs(i - s.top()));
            }
            s.push(i);
        }
    }

   cout << max_distance << endl;
}

signed main() {
    int n;
    cin >> n;
    vector <int> heights;
    for(int i = 1;i <= n;i++) {
        int x;
        cin >> x;
        heights.push_back(x);
    }
    solve(n, heights);

}
accuracy: 1
time_ms: 30
memory_kb: 3948
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;
//make -f ../makefile SRC=

/*
15
128039160 124673101 948773458 149170687 293862995 464683369 354539820 487002768 326635028 622387414 694040973 216581443 744684635 808744374 900618855
12

WA on test 5 => some lower blocks are blocked by other ones => line of sight might pass thru some
mag of slope of consecutive segment must be non-increasing

11
880963441 951962611 777905304 123268117 264698873 212904696 329352583 421865927 553912354 524281415 313638076
8

sorting of dH ?
hint: convex hull

*/
//------------------------------------------------------------------------------
bool DEBUG = false;
const int INF = 1000000000;
const int W = 1000; //width
const int MAX_N = 100000;
static int vect[MAX_N];
//------------------------------------------------------------------------------
struct Point
{
    int i, x, y;
    Point(): i(-1), x(0), y(0) {}
    Point(int idx, int x1, int x2): i(idx), x(x1), y(x2) {}
    bool operator<(const Point& p1) const
    {
        return x < p1.x || (x == p1.x && y < p1.y);
    }
    void debug() const { printf("%d: %d, %d\n", i, x, y); }
};

typedef vector<Point> Points;

//------------------------------------------------------------------------------
int64_t dist2(const Point& A, const Point& B)
{
    return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y);
}

double dist(const Point& A, const Point& B)
{
    return sqrt(dist2(A, B));
}

//------------------------------------------------------------------------------
int ccw(int x1, int y1, int x2, int y2, int x3, int y3)
{
    int v = (x3-x2)*(y2-y1) - (x2-x1)*(y3-y2);
    if (v==0) return 0;
    else if (v<0) return 1; // counter-clockwise
    return -1; // clockwise
}

int64_t cross_product(const Point& P, const Point& A, const Point& B)
{
	return int64_t(A.x-P.x) * (B.y-P.y) - int64_t(A.y-P.y) * (B.x-P.x);
}


void ccw_triangle(Points& triangle)
{
    Point p = triangle[0];
    Point a = triangle[1];
    Point b = triangle[2];
    if (cross_product(p,a,b) > 0) return;

    triangle[1] = b;
    triangle[2] = a;
}

Points andrew_monotone_chain(int N, Points& points)
{
	if (N <= 3)
	{
	    if (N == 3) ccw_triangle(points);
	    return points;
    }

	sort(points.begin(), points.end());

	Points H(2*N);
    int k = 0;

	// build lower hull:
	for (int i=0; i<N; ++i)
	{
		while (k>=2 && cross_product(H[k-2],H[k-1],points[i])<=0) k--;
		H[k++] = points[i];
	}

	// build upper hull
	for (int i=N-1,t=k+1; i>0; --i)
	{
		while (k>=t && cross_product(H[k-2],H[k-1],points[i-1])<=0) k--;
		H[k++] = points[i-1];
	}
	H.resize(k-1);

	return H;
}

Points setup(int N)
{
    Points P(N+2);
    for (int n=0; n<N; ++n) P[n] = Point(n, n*W, vect[n]);
    P[N] = Point(N, 0, -INF);
    P[N+1] = Point(N+1, (N-1)*W, -INF);
    return P;
}
//------------------------------------------------------------------------------
int solve(int N)
{  
    //--------------------------------------------------------------------------
    // base cases:
    if (N == 1) return 0;
    else if (N == 2) return 1;
    //--------------------------------------------------------------------------
    Points P = setup(N);
    Points H = andrew_monotone_chain(N+2, P);
    int K = H.size();
    //for (Point h: H) h.debug();
    int res = 0;
    for (int k=0; k<K-1; ++k)
        if (H[k].i < N && H[k+1].i < N)
            res = max(res, abs(H[k].i-H[k+1].i));
    //--------------------------------------------------------------------------
    return res;
}


//------------------------------------------------------------------------------
int main()
{
    //DEBUG = true;
    //--------------------------------------------------------------------------
    int N, num;
    num = scanf("%d ", &N);
    for (int n=0; n<N; ++n) num = scanf("%d ", &vect[n]);
    int res = solve(N);
    printf("%d\n", res);
    
    return 0;
}

//------------------------------------------------------------------------------
accuracy: 1
time_ms: 10
memory_kb: 7100
final_rank: 6

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using lint = long long;
using pint = pair<int, int>;
using plint = pair<lint, lint>;
struct fast_ios { fast_ios(){ cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(20); }; } fast_ios_;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i<i##_end_;i++)
#define IFOR(i, begin, end) for(int i=(end)-1,i##_begin_=(begin);i>=i##_begin_;i--)
#define REP(i, n) FOR(i,0,n)
#define IREP(i, n) IFOR(i,0,n)
template <typename T, typename V>
void ndarray(vector<T>& vec, const V& val, int len) { vec.assign(len, val); }
template <typename T, typename V, typename... Args> void ndarray(vector<T>& vec, const V& val, int len, Args... args) { vec.resize(len), for_each(begin(vec), end(vec), [&](T& v) { ndarray(v, val, args...); }); }
template <typename T> bool chmax(T &m, const T q) { return m < q ? (m = q, true) : false; }
template <typename T> bool chmin(T &m, const T q) { return m > q ? (m = q, true) : false; }
int floor_lg(long long x) { return x <= 0 ? -1 : 63 - __builtin_clzll(x); }
template <typename T1, typename T2> pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first + r.first, l.second + r.second); }
template <typename T1, typename T2> pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first - r.first, l.second - r.second); }
template <typename T> vector<T> sort_unique(vector<T> vec) { sort(vec.begin(), vec.end()), vec.erase(unique(vec.begin(), vec.end()), vec.end()); return vec; }
template <typename T> int arglb(const std::vector<T> &v, const T &x) { return std::distance(v.begin(), std::lower_bound(v.begin(), v.end(), x)); }
template <typename T> int argub(const std::vector<T> &v, const T &x) { return std::distance(v.begin(), std::upper_bound(v.begin(), v.end(), x)); }
template <typename T> istream &operator>>(istream &is, vector<T> &vec) { for (auto &v : vec) is >> v; return is; }
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <typename T, size_t sz> ostream &operator<<(ostream &os, const array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
#if __cplusplus >= 201703L
template <typename... T> istream &operator>>(istream &is, tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <typename... T> ostream &operator<<(ostream &os, const tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
#endif
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T, typename TH> ostream &operator<<(ostream &os, const unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa) { os << '(' << pa.first << ',' << pa.second << ')'; return os; }
template <typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <typename TK, typename TV, typename TH> ostream &operator<<(ostream &os, const unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef HITONANODE_LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << endl
#define dbgif(cond, x) ((cond) ? cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << endl : cerr)
#else
#define dbg(x) (x)
#define dbgif(cond, x) 0
#endif

int main() {
    int N;
    cin >> N;
    vector<lint> H(N);
    cin >> H;

    vector<plint> st;
    st.emplace_back(0, H[0]);

    set<int> alive;
    REP(i, N) alive.insert(i);

    int ret = 0;
    auto is_erasable = [&](int now) -> bool {
        if (!alive.count(now)) return false;
        auto itr = alive.find(now);
        if (itr == alive.begin() or next(itr) == alive.end()) return false;

        const int prv = *prev(itr), nxt = *next(itr);

        auto [dX, dY] = plint(now, H[now]) - plint(prv, H[prv]);
        auto [dX2, dY2] = plint(nxt, H[nxt]) - plint(prv, H[prv]);
        auto det = dX * dY2 - dY * dX2;
        return det >= 0;
    };

    vector<int> ers;

    auto erase_one = [&](int now) {
        if (!alive.count(now)) return;
        dbg(alive);
        dbg(now);
        alive.erase(now);
        auto itr = alive.lower_bound(now);

        if (itr != alive.begin()) {
            int prv = *prev(itr);
            chmax(ret, now - prv);
            if (is_erasable(prv)) ers.push_back(prv);
        }

        if (itr != alive.end()) {
            int nxt = *itr;
            chmax(ret, nxt - now);
            if (is_erasable(nxt)) ers.push_back(nxt);
        }
    };

    REP(i, N) if (is_erasable(i)) ers.push_back(i);

    while (ers.size()) {
        int x = ers.back();
        ers.pop_back();
        erase_one(x);
    }

    vector<int> vs{alive.begin(), alive.end()};
    FOR(i, 1, vs.size()) chmax(ret, vs[i] - vs[i - 1]);

    cout << ret << '\n';
}
accuracy: 1
time_ms: 60
memory_kb: 9224
final_rank: 18

code_snippet: #pragma region Macros
//#pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma comment(linker, "/stack:200000000")
#ifdef ONLINE_JUDGE
// #pragma GCC optimize("unroll-loops")
// #pragma GCC target("popcnt")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2,tune=native")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2")
// #pragma GCC target("avx2")
#endif
#pragma GCC optimize("Ofast")
#ifdef noimi
#define oj_local(a, b) b
#else
#define oj_local(a, b) a
#endif

#define LOCAL if(oj_local(0, 1))
#define OJ if(oj_local(1, 0))

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <immintrin.h>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <streambuf>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long int;
using i128 = __int128_t;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using ld = long double;
template <typename T> using vc = vector<T>;
template <typename T> using vvc = vector<vc<T>>;
template <typename T> using vvvc = vector<vvc<T>>;
using vi = vc<int>;
using vl = vc<ll>;
using vpi = vc<pii>;
using vpl = vc<pll>;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T> int si(const T &x) { return x.size(); }
template <class T, class S> inline bool chmax(T &a, const S &b) { return (a < b ? a = b, 1 : 0); }
template <class T, class S> inline bool chmin(T &a, const S &b) { return (a > b ? a = b, 1 : 0); }
vi iota(int n) {
    vi a(n);
    return iota(a.begin(), a.end(), 0), a;
}
template <typename T> vi iota(const vector<T> &a, bool greater = false) {
    vi res(a.size());
    iota(res.begin(), res.end(), 0);
    sort(res.begin(), res.end(), [&](int i, int j) {
        if(greater) return a[i] > a[j];
        return a[i] < a[j];
    });
    return res;
}

// macros
#define overload5(a, b, c, d, e, name, ...) name
#define overload4(a, b, c, d, name, ...) name
#define endl '\n'
#define REP0(n) for(ll jidlsjf = 0; jidlsjf < n; ++jidlsjf)
#define REP1(i, n) for(ll i = 0; i < (n); ++i)
#define REP2(i, a, b) for(ll i = (a); i < (b); ++i)
#define REP3(i, a, b, c) for(ll i = (a); i < (b); i += (c))
#define rep(...) overload4(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define per0(n) for(int jidlsjf = 0; jidlsjf < (n); ++jidlsjf)
#define per1(i, n) for(ll i = (n)-1; i >= 0; --i)
#define per2(i, a, b) for(ll i = (a)-1; i >= b; --i)
#define per3(i, a, b, c) for(ll i = (a)-1; i >= (b); i -= (c))
#define per(...) overload4(__VA_ARGS__, per3, per2, per1, per0)(__VA_ARGS__)
#define fore0(a) rep(a.size())
#define fore1(i, a) for(auto &&i : a)
#define fore2(a, b, v) for(auto &&[a, b] : v)
#define fore3(a, b, c, v) for(auto &&[a, b, c] : v)
#define fore4(a, b, c, d, v) for(auto &&[a, b, c, d] : v)
#define fore(...) overload5(__VA_ARGS__, fore4, fore3, fore2, fore1, fore0)(__VA_ARGS__)
#define fi first
#define se second
#define pb push_back
#define ppb pop_back
#define ppf pop_front
#define eb emplace_back
#define drop(s) cout << #s << endl, exit(0)
#define si(c) (int)(c).size()
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define rng(v, l, r) v.begin() + l, v.begin() + r
#define all(c) begin(c), end(c)
#define rall(c) rbegin(c), rend(c)
#define SORT(v) sort(all(v))
#define REV(v) reverse(all(v))
#define UNIQUE(x) SORT(x), x.erase(unique(all(x)), x.end())
template <typename T = ll, typename S> T SUM(const S &v) { return accumulate(all(v), T(0)); }
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)                                                                                                                         \
    vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define vvvvv(type, name, a, b, c, d, ...) vector name(a, vector(b, vector(c, vector(d, vector<type>(__VA_ARGS__)))))
#define vvvvvv(type, name, a, b, c, d, e, ...) vector name(a, vector(b, vector(c, vector(d, vector(e, vector<type>(__VA_ARGS__))))))
constexpr pii dx4[4] = {pii{1, 0}, pii{0, 1}, pii{-1, 0}, pii{0, -1}};
constexpr pii dx8[8] = {{1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};

namespace yesno_impl {
const string YESNO[2] = {"NO", "YES"};
const string YesNo[2] = {"No", "Yes"};
const string yesno[2] = {"no", "yes"};
const string firstsecond[2] = {"second", "first"};
const string FirstSecond[2] = {"Second", "First"};
const string possiblestr[2] = {"impossible", "possible"};
void YES(bool t = 1) { cout << YESNO[t] << endl; }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { cout << YesNo[t] << endl; }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { cout << yesno[t] << endl; }
void no(bool t = 1) { yes(!t); }
void first(bool t = 1) { cout << firstsecond[t] << endl; }
void First(bool t = 1) { cout << FirstSecond[t] << endl; }
void possible(bool t = 1) { cout << possiblestr[t] << endl; }
}; // namespace yesno_impl
using namespace yesno_impl;

#define INT(...)                                                                                                                                               \
    int __VA_ARGS__;                                                                                                                                           \
    IN(__VA_ARGS__)
#define LL(...)                                                                                                                                                \
    ll __VA_ARGS__;                                                                                                                                            \
    IN(__VA_ARGS__)
#define STR(...)                                                                                                                                               \
    string __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                                                                               \
    char __VA_ARGS__;                                                                                                                                          \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                                                                               \
    double __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
#define VEC(type, name, size)                                                                                                                                  \
    vector<type> name(size);                                                                                                                                   \
    IN(name)
#define VEC2(type, name1, name2, size)                                                                                                                         \
    vector<type> name1(size), name2(size);                                                                                                                     \
    for(int i = 0; i < size; i++) IN(name1[i], name2[i])
#define VEC3(type, name1, name2, name3, size)                                                                                                                  \
    vector<type> name1(size), name2(size), name3(size);                                                                                                        \
    for(int i = 0; i < size; i++) IN(name1[i], name2[i], name3[i])
#define VV(type, name, h, w)                                                                                                                                   \
    vector<vector<type>> name(h, vector<type>(w));                                                                                                             \
    IN(name)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
template <class T> void scan(vector<T> &);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
    scan(head);
    IN(tail...);
}

template <typename T, typename S> T ceil(T x, S y) {
    assert(y);
    return (y < 0 ? ceil(-x, -y) : (x > 0 ? (x + y - 1) / y : x / y));
}

template <typename T, typename S> T floor(T x, S y) {
    assert(y);
    return (y < 0 ? floor(-x, -y) : (x > 0 ? x / y : x / y - (x % y == 0 ? 0 : 1)));
}
template <class T> T POW(T x, int n) {
    T res = 1;
    for(; n; n >>= 1, x *= x)
        if(n & 1) res *= x;
    return res;
}
template <class T, class S> T POW(T x, S n, const ll &mod) {
    T res = 1;
    x %= mod;
    for(; n; n >>= 1, x = x * x % mod)
        if(n & 1) res = res * x % mod;
    return res;
}
vector<pll> factor(ll x) {
    vector<pll> ans;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0) {
            ans.push_back({i, 1});
            while((x /= i) % i == 0) ans.back().second++;
        }
    if(x != 1) ans.push_back({x, 1});
    return ans;
}
template <class T> vector<T> divisor(T x) {
    vector<T> ans;
    for(T i = 1; i * i <= x; i++)
        if(x % i == 0) {
            ans.pb(i);
            if(i * i != x) ans.pb(x / i);
        }
    return ans;
}
template <typename T> void zip(vector<T> &x) {
    vector<T> y = x;
    UNIQUE(y);
    for(int i = 0; i < x.size(); ++i) { x[i] = lb(y, x[i]); }
}
template <class S> void fold_in(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void fold_in(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto e : a) v.emplace_back(e);
    fold_in(v, tail...);
}
template <class S> void renumber(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void renumber(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto &&e : a) e = lb(v, e);
    renumber(v, tail...);
}
template <class S, class... Args> vector<S> zip(vector<S> &head, Args &&...args) {
    vector<S> v;
    fold_in(v, head, args...);
    sort(all(v)), v.erase(unique(all(v)), v.end());
    renumber(v, head, args...);
    return v;
}
template <typename T> vector<T> RUI(const vector<T> &v) {
    vector<T> res(v.size() + 1);
    for(int i = 0; i < v.size(); i++) res[i + 1] = res[i] + v[i];
    return res;
}
// 反時計周りに 90 度回転
template <typename T> void rot(vector<vector<T>> &v) {
    if(empty(v)) return;
    int n = v.size(), m = v[0].size();
    vector res(m, vector<T>(n));
    rep(i, n) rep(j, m) res[m - 1 - j][i] = v[i][j];
    v.swap(res);
}
// x in [l, r)
template <class T, class S> bool inc(const T &x, const S &l, const S &r) { return l <= x and x < r; }

constexpr ll ten(int n) { return n == 0 ? 1 : ten(n - 1) * 10; }
// bit 演算系
ll pow2(int i) { return 1LL << i; }
int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(ll t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int lowbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int lowbit(ll a) { return a == 0 ? 64 : __builtin_ctzll(a); }
// int allbit(int n) { return (1 << n) - 1; }
constexpr ll mask(int n) { return (1LL << n) - 1; }
// int popcount(signed t) { return __builtin_popcount(t); }
// int popcount(ll t) { return __builtin_popcountll(t); }
int popcount(uint64_t t) { return __builtin_popcountll(t); }
static inline uint64_t popcount64(uint64_t x) {
    uint64_t m1 = 0x5555555555555555ll;
    uint64_t m2 = 0x3333333333333333ll;
    uint64_t m4 = 0x0F0F0F0F0F0F0F0Fll;
    uint64_t h01 = 0x0101010101010101ll;

    x -= (x >> 1) & m1;
    x = (x & m2) + ((x >> 2) & m2);
    x = (x + (x >> 4)) & m4;

    return (x * h01) >> 56;
}
bool ispow2(int i) { return i && (i & -i) == i; }

ll rnd(ll l, ll r) { //[l, r)
#ifdef noimi
    static mt19937_64 gen;
#else
    static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
#endif
    return uniform_int_distribution<ll>(l, r - 1)(gen);
}
ll rnd(ll n) { return rnd(0, n); }

template <class t> void random_shuffle(vc<t> &a) { rep(i, si(a)) swap(a[i], a[rnd(0, i + 1)]); }

int in() {
    int x;
    cin >> x;
    return x;
}
ll lin() {
    unsigned long long x;
    cin >> x;
    return x;
}

template <class T, class S> pair<T, S> operator-(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi - y.fi, x.se - y.se); }
template <class T, class S> pair<T, S> operator+(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi + y.fi, x.se + y.se); }
template <class T> pair<T, T> operator&(const pair<T, T> &l, const pair<T, T> &r) { return pair<T, T>(max(l.fi, r.fi), min(l.se, r.se)); }
template <class T, class S> pair<T, S> operator+=(pair<T, S> &l, const pair<T, S> &r) { return l = l + r; }
template <class T, class S> pair<T, S> operator-=(pair<T, S> &l, const pair<T, S> &r) { return l = l - r; }
template <class T> bool intersect(const pair<T, T> &l, const pair<T, T> &r) { return (l.se < r.se ? r.fi < l.se : l.fi < r.se); }

template <typename T> struct edge {
    int from, to;
    T cost;
    int id;
    edge(int to, T cost) : from(-1), to(to), cost(cost) {}
    edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
    edge(int from, int to, T cost, int id) : from(from), to(to), cost(cost), id(id) {}
    constexpr bool operator<(const edge<T> &rhs) const noexcept { return cost < rhs.cost; }
    edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
    friend ostream operator<<(ostream &os, edge &e) { return os << e.to; }
};
template <typename T> using Edges = vector<edge<T>>;

using Tree = vector<vector<int>>;
using Graph = vector<vector<int>>;
template <class T> using Wgraph = vector<vector<edge<T>>>;
Graph getG(int n, int m = -1, bool directed = false, int margin = 1) {
    Tree res(n);
    if(m == -1) m = n - 1;
    while(m--) {
        int a, b;
        cin >> a >> b;
        a -= margin, b -= margin;
        res[a].emplace_back(b);
        if(!directed) res[b].emplace_back(a);
    }
    return res;
}
Graph getTreeFromPar(int n, int margin = 1) {
    Graph res(n);
    for(int i = 1; i < n; i++) {
        int a;
        cin >> a;
        res[a - margin].emplace_back(i);
    }
    return res;
}
template <class T> Wgraph<T> getWg(int n, int m = -1, bool directed = false, int margin = 1) {
    Wgraph<T> res(n);
    if(m == -1) m = n - 1;
    while(m--) {
        int a, b;
        T c;
        scan(a), scan(b), scan(c);
        a -= margin, b -= margin;
        res[a].emplace_back(b, c);
        if(!directed) res[b].emplace_back(a, c);
    }
    return res;
}
void add(Graph &G, int x, int y) { G[x].eb(y), G[y].eb(x); }
template <class S, class T> void add(Wgraph<S> &G, int x, int y, T c) { G[x].eb(y, c), G[y].eb(x, c); }

#define TEST                                                                                                                                                   \
    INT(testcases);                                                                                                                                            \
    while(testcases--)

istream &operator>>(istream &is, i128 &v) {
    string s;
    is >> s;
    v = 0;
    for(int i = 0; i < (int)s.size(); i++) {
        if(isdigit(s[i])) { v = v * 10 + s[i] - '0'; }
    }
    if(s[0] == '-') { v *= -1; }
    return is;
}

ostream &operator<<(ostream &os, const i128 &v) {
    if(v == 0) { return (os << "0"); }
    i128 num = v;
    if(v < 0) {
        os << '-';
        num = -num;
    }
    string s;
    for(; num > 0; num /= 10) { s.push_back((char)(num % 10) + '0'); }
    reverse(s.begin(), s.end());
    return (os << s);
}
namespace aux {
template <typename T, unsigned N, unsigned L> struct tp {
    static void output(std::ostream &os, const T &v) {
        os << std::get<N>(v) << (&os == &cerr ? ", " : " ");
        tp<T, N + 1, L>::output(os, v);
    }
};
template <typename T, unsigned N> struct tp<T, N, N> {
    static void output(std::ostream &os, const T &v) { os << std::get<N>(v); }
};
} // namespace aux
template <typename... Ts> std::ostream &operator<<(std::ostream &os, const std::tuple<Ts...> &t) {
    if(&os == &cerr) { os << '('; }
    aux::tp<std::tuple<Ts...>, 0, sizeof...(Ts) - 1>::output(os, t);
    if(&os == &cerr) { os << ')'; }
    return os;
}
template <class T, class S> ostream &operator<<(ostream &os, const pair<T, S> &p) {
    if(&os == &cerr) { return os << "(" << p.first << ", " << p.second << ")"; }
    return os << p.first << " " << p.second;
}
template <class Ch, class Tr, class Container> std::basic_ostream<Ch, Tr> &operator<<(std::basic_ostream<Ch, Tr> &os, const Container &x) {
    bool f = true;
    if(&os == &cerr) os << "[";
    for(auto &y : x) {
        if(&os == &cerr)
            os << (f ? "" : ", ") << y;
        else
            os << (f ? "" : " ") << y;
        f = false;
    }
    if(&os == &cerr) os << "]";
    return os;
}

#ifdef noimi
#undef endl
void debug() { cerr << endl; }
void debug(bool) { cerr << endl; }
template <class Head, class... Tail> void debug(bool is_front, Head head, Tail... tail) {
    if(!is_front) cerr << ", ";
    cerr << head;
    debug(false, tail...);
}

#define dump(args...)                                                                                                                                          \
    {                                                                                                                                                          \
        vector<string> _debug = _split(#args, ',');                                                                                                            \
        err(true, begin(_debug), args);                                                                                                                        \
    }

vector<string> _split(const string &s, char c) {
    vector<string> v;
    stringstream ss(s);
    string x;
    while(getline(ss, x, c)) {
        if(empty(v))
            v.eb(x);
        else {
            bool flag = false;
            for(auto [c, d] : {pair('(', ')'), pair('[', ']'), pair('{', '}')}) {
                if(count(all(v.back()), c) != count(all(v.back()), d)) flag = true;
            }
            if(flag)
                v.back() += "," + x;
            else
                v.eb(x);
        }
    }
    return move(v);
}

void err(bool, vector<string>::iterator) { cerr << endl; }
template <typename T, typename... Args> void err(bool is_front, vector<string>::iterator it, T a, Args... args) {
    if(!is_front) cerr << ", ";
    cerr << it->substr((*it)[0] == ' ', (*it).size()) << " = " << a, err(false, ++it, args...);
}

// #define dump(...) cerr << #__VA_ARGS__ << " : ", debug(true, __VA_ARGS__)
#else
#define dump(...) static_cast<void>(0)
#define dbg(...) static_cast<void>(0)
#endif
void OUT() { cout << endl; }
template <class Head, class... Tail> void OUT(const Head &head, const Tail &...tail) {
    cout << head;
    if(sizeof...(tail)) cout << ' ';
    OUT(tail...);
}

template <typename T> static constexpr T inf = numeric_limits<T>::max() / 2;

template <class F> struct REC {
    F f;
    REC(F &&f_) : f(std::forward<F>(f_)) {}
    template <class... Args> auto operator()(Args &&...args) const { return f(*this, std::forward<Args>(args)...); }
};

template <class S> vector<pair<S, int>> runLength(const vector<S> &v) {
    vector<pair<S, int>> res;
    for(auto &e : v) {
        if(res.empty() or res.back().fi != e)
            res.eb(e, 1);
        else
            res.back().se++;
    }
    return res;
}
vector<pair<char, int>> runLength(const string &v) {
    vector<pair<char, int>> res;
    for(auto &e : v) {
        if(res.empty() or res.back().fi != e)
            res.eb(e, 1);
        else
            res.back().se++;
    }
    return res;
}

int toint(const char &c, const char start = 'a') { return c - start; }
int toint(const char &c, const string &chars) { return find(all(chars), c) - begin(chars); }
int alphabets_to_int(const char &c) { return (islower(c) ? c - 'a' : c - 'A' + 26); }
template <typename T> auto toint(const T &v, const char &start = 'a') {
    vector<decltype(toint(v[0]))> ret;
    ret.reserve(v.size());
    for(auto &&e : v) ret.emplace_back(toint(e, start));
    return ret;
}
template <typename T> auto toint(const T &v, const string &start) {
    vector<decltype(toint(v[0]))> ret;
    ret.reserve(v.size());
    for(auto &&e : v) ret.emplace_back(toint(e, start));
    return ret;
}
// a -> 0, A -> 26
template <typename T> auto alphabets_to_int(const T &s) {
    vector<decltype(alphabets_to_int(s[0]))> res;
    res.reserve(s.size());
    for(auto &&e : s) { res.emplace_back(alphabets_to_int(e)); }
    return res;
}

template <class T, class F> T bin_search(T ok, T ng, const F &f) {
    while(abs(ok - ng) > 1) {
        T mid = ok + ng >> 1;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
template <class T, class F> T bin_search_double(T ok, T ng, const F &f, int iter = 80) {
    while(iter--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(11);
    }
} setup_io;

#pragma endregion

namespace Geometry {
using T = ll;
inline constexpr int type(T x, T y) {
    if(x == 0 and y == 0) return 0;
    if(y < 0 or (y == 0 and x > 0)) return -1;
    return 1;
}
struct Point {
    T x, y;
    constexpr Point(T _x = 0, T _y = 0) : x(_x), y(_y) {}
    constexpr Point operator+() const noexcept { return *this; }
    constexpr Point operator-() const noexcept { return Point(-x, -y); }
    constexpr Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
    constexpr Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
    constexpr Point &operator+=(const Point &p) { return x += p.x, y += p.y, *this; }
    constexpr Point &operator-=(const Point &p) { return x -= p.x, y -= p.y, *this; }
    constexpr T operator*(const Point &p) const { return x * p.x + y * p.y; }
    constexpr Point &operator*=(const T &k) { return x *= k, y *= k, *this; }
    constexpr Point operator*(const T &k) { return (*this *= k); }
    constexpr bool operator==(const Point &r) const noexcept { return r.x == x and r.y == y; }

    constexpr bool operator<(const Point &r) const {
        int L = type(x, y), R = type(r.x, r.y);
        if(L != R) return L < R;

        T X = x * r.y, Y = r.x * y;
        if(X != Y) return X > Y;
        return x < r.x;
    }
};
ostream &operator<<(ostream &os, const Point &p) { return os << p.x << " " << p.y; }
istream &operator>>(istream &is, Point &p) {
    is >> p.x >> p.y;
    return is;
}

struct Line {
    Point a, b;
    Line() = default;
    Line(Point a, Point b) : a(a), b(b) {}
    // ax + by = c
    Line(T A, T B, T C) {
        if(A == 0) {
            a = Point(0, C / B), Point(1, C / B);
        } else if(B == 0) {
            a = Point(C / A, 0), b = Point(C / A, 1);
        } else {
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }
};
ostream &operator<<(ostream &os, Line &p) { return os << p.a << " to " << p.b; }
istream &operator>>(istream &is, Line &p) { return is >> p.a >> p.b; }

struct Segment : Line {
    Segment() = default;
    Segment(Point a, Point b) : Line(a, b) {}
};

ostream &operator<<(ostream &os, Segment &p) { return os << p.a << " to " << p.b; }
istream &operator>>(istream &is, Segment &p) {
    is >> p.a >> p.b;
    return is;
}

struct Circle {
    Point p;
    T r;
    Circle() = default;
    Circle(Point p, T r) : p(p), r(r) {}
};

using pt = Point;
using Points = vector<pt>;
T cross(const pt &x, const pt &y) { return x.x * y.y - x.y * y.x; }
T dot(const pt &x, const pt &y) { return x.x * y.x + x.y * y.y; }

T abs2(const pt &x) { return dot(x, x); }
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
// 点の回転方向
int ccw(const Point &a, Point b, Point c) {
    b = b - a, c = c - a;
    if(cross(b, c) > 0) return +1;   // "COUNTER_CLOCKWISE"
    if(cross(b, c) < 0) return -1;   // "CLOCKWISE"
    if(dot(b, c) < 0) return +2;     // "ONLINE_BACK"
    if(abs2(b) < abs2(c)) return -2; // "ONLINE_FRONT"
    return 0;                        // "ON_SEGMENT"
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
// 平行判定
bool parallel(const Line &a, const Line &b) { return (cross(a.b - a.a, b.b - b.a) == 0); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
// 垂直判定
bool orthogonal(const Line &a, const Line &b) { return (dot(a.a - a.b, b.a - b.b) == 0); }

bool intersect(const Line &l, const Point &p) { return abs(ccw(l.a, l.b, p)) != 1; }

bool intersect(const Line &l, const Line &m) { return !parallel(l, m); }

bool intersect(const Segment &s, const Point &p) { return ccw(s.a, s.b, p) == 0; }

bool intersect(const Line &l, const Segment &s) { return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) <= 0; }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
bool intersect(const Segment &s, const Segment &t) { return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0; }

Point crosspoint(const Line &l, const Line &m) {
    T A = cross(l.b - l.a, m.b - m.a);
    T B = cross(l.b - l.a, l.b - m.a);
    if(A == 0 and B == 0) return m.a;
    return m.a + (m.b - m.a) * (B / A);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) { return crosspoint(Line(l), Line(m)); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
// 凸性判定
bool is_convex(const Points &p) {
    int n = (int)p.size();
    for(int i = 0; i < n; i++) {
        if(ccw(p[(i + n - 1) % n], p[i], p[(i + 1) % n]) == -1) return false;
    }
    return true;
}

Points convex_hull(Points &p) {
    int n = p.size(), k = 0;
    if(n <= 2) return p;
    sort(begin(p), end(p), [](pt x, pt y) { return (x.x != y.x ? x.x < y.x : x.y < y.y); });
    Points ch(2 * n);
    for(int i = 0; i < n; ch[k++] = p[i++]) {
        if(k >= 2) dump(k, ch, cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]));
        while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) <= 0) --k;
    }
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        while(k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) <= 0) --k;
    }
    ch.resize(k - 1);
    return ch;
}
T area2(const Points &p) {
    T res = 0;
    rep(i, si(p)) { res += cross(p[i], p[i == si(p) - 1 ? 0 : i + 1]); }
    return res;
}
} // namespace Geometry

using namespace Geometry;
int main() {
    INT(n);
    VEC(int, a, n);
    Points P(n + 2);
    P[0] = Point(0, 0);
    rep(i, n) P[i + 1] = Point(i, a[i]);
    P[n + 1] = Point(n - 1, 0);
    auto ch = convex_hull(P);
    dump(ch);
    int ma = 0;
    rep(i, 2, si(ch) - 1) { chmax(ma, ch[i].x - ch[i + 1].x); }
    OUT(ma);
}
accuracy: 1
time_ms: 10
memory_kb: 8304
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repl(i,l,r) for(ll i=(l);i<(r);i++)
#define per(i,n) for(ll i=(n)-1;i>=0;i--)
#define perl(i,r,l) for(ll i=r-1;i>=l;i--)
#define fi first
#define se second
#define pb push_back
#define ins insert
#define pqueue(x) priority_queue<x,vector<x>,greater<x>>
#define all(x) (x).begin(),(x).end()
#define CST(x) cout<<fixed<<setprecision(x)
#define vtpl(x,y,z) vector<tuple<x,y,z>>
#define rev(x) reverse(x);
using ll=long long;
using vl=vector<ll>;
using vvl=vector<vector<ll>>;
using pl=pair<ll,ll>;
using vpl=vector<pl>;
using vvpl=vector<vpl>;
const ll MOD=1000000007;
const ll MOD9=998244353;
const int inf=1e9+10;
const ll INF=4e18;
const ll dy[9]={0,1,-1,0,1,1,-1,-1,0};
const ll dx[9]={1,0,0,-1,1,-1,1,-1,0};
template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
ll det(pl a,pl b,pl c){//a->bとb->cの周り方、正なら時計回り
    ll ax=b.first-a.first,ay=b.second-a.second;
    ll bx=c.first-b.first,by=c.second-b.second;
    return ax*by-ay*bx;
}
int main(){
    ll n;cin >> n;
    vl v(n);rep(i,n)cin >> v[i];
    vpl st;
    rep(i,n){
        pl now={i,v[i]};
        if(st.size()<2){
            st.push_back(now);
            continue;
        }
        ll len=st.size();
        while(len>=2&&det(st[len-2],st[len-1],now)>=0){
            st.pop_back();len--;
        }
        st.push_back(now);
    }
    ll ans=0;
    rep(i,st.size()-1){
        chmax(ans,st[i+1].first-st[i].first);
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3868
final_rank: 5

code_snippet: #define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
constexpr int INF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr double EPS = 1e-8;
constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
constexpr int DY4[]{1, 0, -1, 0}, DX4[]{0, -1, 0, 1};
constexpr int DY8[]{1, 1, 0, -1, -1, -1, 0, 1};
constexpr int DX8[]{0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U>
inline bool chmax(T& a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U>
inline bool chmin(T& a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
  IOSetup() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << fixed << setprecision(20);
  }
} iosetup;

namespace geometry {

using Real = double;
constexpr long double PI = 3.14159265358979323846;

int sgn(const Real x) {
  static constexpr Real EPS = 1e-8;
  return x > EPS ? 1 : (x < -EPS ? -1 : 0);
}

Real degree_to_radian(const Real d) { return d * PI / 180; }
Real radian_to_degree(const Real r) { return r * 180 / PI; }

struct Point {
  Real x, y;
  explicit Point(const Real x = 0, const Real y = 0) : x(x), y(y) {}
  Real abs() const { return std::sqrt(norm()); }
  Real arg() const {
    const Real res = std::atan2(y, x);
    return res < 0 ? res + PI * 2 : res;
  }
  Real norm() const { return x * x + y * y; }
  Point rotate(const Real angle) const {
    const Real cs = std::cos(angle), sn = std::sin(angle);
    return Point(x * cs - y * sn, x * sn + y * cs);
  }
  Point unit_vector() const {
    const Real a = abs();
    return Point(x / a, y / a);
  }
  std::pair<Point, Point> normal_unit_vector() const {
    const Point u = unit_vector();
    return {Point(-u.y, u.x), Point(u.y, -u.x)};
  }
  Point& operator+=(const Point& p) {
    x += p.x; y += p.y;
    return *this;
  }
  Point& operator-=(const Point& p) {
    x -= p.x; y -= p.y;
    return *this;
  }
  Point& operator*=(const Real k) {
    x *= k; y *= k;
    return *this;
  }
  Point& operator/=(const Real k) {
    x /= k; y /= k;
    return *this;
  }
  bool operator<(const Point& p) const {
    const int x_sgn = sgn(p.x - x);
    return x_sgn != 0 ? x_sgn == 1 : sgn(p.y - y) == 1;
  }
  bool operator<=(const Point& p) const { return !(p < *this); }
  bool operator>(const Point& p) const { return p < *this; }
  bool operator>=(const Point& p) const { return !(*this < p); }
  Point operator+() const { return *this; }
  Point operator-() const { return Point(-x, -y); }
  Point operator+(const Point& p) const { return Point(*this) += p; }
  Point operator-(const Point& p) const { return Point(*this) -= p; }
  Point operator*(const Real k) const { return Point(*this) *= k; }
  Point operator/(const Real k) const { return Point(*this) /= k; }
  friend std::ostream& operator<<(std::ostream& os, const Point& p) {
    return os << '(' << p.x << ", " << p.y << ')';
  }
  friend std::istream& operator>>(std::istream& is, Point& p) {
    Real x, y; is >> x >> y;
    p = Point(x, y);
    return is;
  }
};

struct Segment {
  Point s, t;
  explicit Segment(const Point& s = Point(0, 0), const Point& t = Point(0, 0))
      : s(s), t(t) {}
};
struct Line : Segment {
  using Segment::Segment;
  explicit Line(const Real a, const Real b, const Real c) {
    if (sgn(a) == 0) {
      s = Point(0, -c / b); t = Point(1, s.y);
    } else if (sgn(b) == 0) {
      s = Point(-c / a, 0); t = Point(s.x, 1);
    } else if (sgn(c) == 0) {
      s = Point(0, 0); t = Point(1, -a / b);
    } else {
      s = Point(0, -c / b); t = Point(-c / a, 0);
    }
  }
};

struct Circle {
  Point p; Real r;
  explicit Circle(const Point& p = Point(0, 0), const Real r = 0)
      : p(p), r(r) {}
};

Real cross(const Point& a, const Point& b) { return a.x * b.y - a.y * b.x; }
Real dot(const Point& a, const Point& b) { return a.x * b.x + a.y * b.y; }

int ccw(const Point& a, const Point& b, const Point& c) {
  const Point ab = b - a, ac = c - a;
  const int sign = sgn(cross(ab, ac));
  if (sign == 0) {
    if (sgn(dot(ab, ac)) == -1) return 2;
    if (sgn(ac.norm() - ab.norm()) == 1) return -2;
  }
  return sign;
}

Real get_angle(const Point& a, const Point& b, const Point& c) {
  Real ab = (a - b).arg(), bc = (c - b).arg();
  if (ab > bc) std::swap(ab, bc);
  return std::min(bc - ab, static_cast<Real>(PI * 2 - (bc - ab)));
}

Real closest_pair(std::vector<Point> ps) {
  const int n = ps.size();
  assert(n >= 2);
  std::sort(ps.begin(), ps.end());
  const std::function<Real(int, int)> f =
      [&ps, &f](const int left, const int right) -> Real {
        const int mid = (left + right) >> 1;
        Real x_mid = ps[mid].x, d = std::numeric_limits<Real>::max();
        if (left + 1 < mid) d = std::min(d, f(left, mid));
        if (mid + 1 < right) d = std::min(d, f(mid, right));
        std::inplace_merge(std::next(ps.begin(), left),
                           std::next(ps.begin(), mid),
                           std::next(ps.begin(), right),
                           [](const Point& a, const Point& b) -> bool {
                             return sgn(b.y - a.y) == 1;
                           });
        std::vector<Point> tmp;
        for (int i = left; i < right; ++i) {
          if (sgn(std::abs(ps[i].x - x_mid) - d) == 1) continue;
          for (int j = static_cast<int>(tmp.size()) - 1; j >= 0; --j) {
            const Point v = ps[i] - tmp[j];
            if (sgn(v.y - d) == 1) break;
            d = std::min(d, v.abs());
          }
          tmp.emplace_back(ps[i]);
        }
        return d;
      };
  return f(0, n);
}

Point projection(const Segment& a, const Point& b) {
  return a.s + (a.t - a.s) * dot(a.t - a.s, b - a.s) / (a.t - a.s).norm();
}
Point reflection(const Segment& a, const Point& b) {
  return projection(a, b) * 2 - b;
}

bool is_parallel(const Segment& a, const Segment& b) {
  return sgn(cross(a.t - a.s, b.t - b.s)) == 0;
}
bool is_orthogonal(const Segment& a, const Segment& b) {
  return sgn(dot(a.t - a.s, b.t - b.s)) == 0;
}

Real distance(const Point&, const Point&);
Real distance(const Segment&, const Point&);
Real distance(const Line&, const Point&);
int common_tangent_num(const Circle&, const Circle&);
bool has_intersected(const Segment& a, const Point& b) {
  return ccw(a.s, a.t, b) == 0;
}
bool has_intersected(const Segment& a, const Segment& b) {
  return ccw(a.s, a.t, b.s) * ccw(a.s, a.t, b.t) <= 0 &&
         ccw(b.s, b.t, a.s) * ccw(b.s, b.t, a.t) <= 0;
}
bool has_intersected(const Line& a, const Point& b) {
  const int c = ccw(a.s, a.t, b);
  return c != 1 && c != -1;
}
bool has_intersected(const Line& a, const Segment& b) {
  return ccw(a.s, a.t, b.s) * ccw(a.s, a.t, b.t) != 1;
}
bool has_intersected(const Line& a, const Line& b) {
  return sgn(cross(a.t - a.s, b.t - b.s)) != 0 ||
         sgn(cross(a.t - a.s, b.s - a.s)) == 0;
}
bool has_intersected(const Circle& a, const Point& b) {
  return sgn(distance(a.p, b) - a.r) == 0;
}
bool has_intersected(const Circle& a, const Segment& b) {
  return sgn(a.r - distance(b, a.p)) != -1 &&
         sgn(std::max(distance(a.p, b.s), distance(a.p, b.t)) - a.r) != -1;
}
bool has_intersected(const Circle& a, const Line& b) {
  return sgn(a.r - distance(b, a.p)) != -1;
}
bool has_intersected(const Circle& a, const Circle& b) {
  const int num = common_tangent_num(a, b);
  return 1 <= num && num <= 3;
}

Point intersection(const Line& a, const Line& b) {
  assert(has_intersected(a, b) && !is_parallel(a, b));
  const Point va = a.t - a.s, vb = b.t - b.s;
  return a.s + va * cross(vb, b.s - a.s) / cross(vb, va);
}
Point intersection(const Segment& a, const Segment& b) {
  assert(has_intersected(a, b));
  if (is_parallel(a, b)) {
    if (sgn(distance(a.s, b.s)) == 0) {
      assert(sgn(dot(a.t - a.s, b.t - a.s)) == -1);
      return a.s;
    } else if (sgn(distance(a.s, b.t)) == 0) {
      assert(sgn(dot(a.t - a.s, b.s - a.s)) == -1);
      return a.s;
    } else if (sgn(distance(a.t, b.s)) == 0) {
      assert(sgn(dot(a.s - a.t, b.t - a.t)) == -1);
      return a.t;
    } else if (sgn(distance(a.t, b.t)) == 0) {
      assert(sgn(dot(a.s - a.t, b.s - a.t)) == -1);
      return a.t;
    } else {
      assert(false);
    }
  } else {
    return intersection(Line(a.s, a.t), Line(b.s, b.t));
  }
}
Point intersection(const Line& a, const Segment& b) {
  assert(has_intersected(a, b));
  return intersection(a, Line(b.s, b.t));
}
std::vector<Point> intersection(const Circle& a, const Line& b) {
  const Point pro = projection(b, a.p);
  const Real nor = (a.p - pro).norm();
  const int sign = sgn(a.r - std::sqrt(nor));
  if (sign == -1) return {};
  if (sign == 0) return {pro};
  const Point tmp = (b.t - b.s).unit_vector() * std::sqrt(a.r * a.r - nor);
  return {pro + tmp, pro - tmp};
}
std::vector<Point> intersection(const Circle& a, const Segment& b) {
  if (!has_intersected(a, b)) return {};
  const std::vector<Point> res = intersection(a, Line(b.s, b.t));
  if (sgn(distance(a.p, b.s) - a.r) != -1 &&
      sgn(distance(a.p, b.t) - a.r) != -1) {
    return res;
  }
  return {res[sgn(dot(res[0] - b.s, res[0] - b.t)) == 1 ? 1 : 0]};
}
std::vector<Point> intersection(const Circle& a, const Circle& b) {
  const int num = common_tangent_num(a, b);
  if (num == 0 || num == 4) return {};
  const Real alpha = (b.p - a.p).arg();
  if (num == 1 || num == 3) {
    return {Point(a.p.x + a.r * std::cos(alpha),
                  a.p.y + a.r * std::sin(alpha))};
  }
  const Real dist = (b.p - a.p).norm();
  const Real beta =
      std::acos((dist + a.r * a.r - b.r * b.r) / (2 * std::sqrt(dist) * a.r));
  return {
      a.p + Point(a.r * std::cos(alpha + beta), a.r * std::sin(alpha + beta)),
      a.p + Point(a.r * std::cos(alpha - beta), a.r * std::sin(alpha - beta))};
}

Real distance(const Point& a, const Point& b) { return (b - a).abs(); }
Real distance(const Segment& a, const Point& b) {
  const Point foot = projection(a, b);
  return has_intersected(a, foot) ?
         distance(foot, b) : std::min(distance(a.s, b), distance(a.t, b));
}
Real distance(const Segment& a, const Segment& b) {
  return has_intersected(a, b) ? 0 :
         std::min({distance(a, b.s), distance(a, b.t),
                   distance(b, a.s), distance(b, a.t)});
}
Real distance(const Line& a, const Point& b) {
  return distance(projection(a, b), b);
}
Real distance(const Line& a, const Segment& b) {
  return has_intersected(a, b) ?
         0 : std::min(distance(a, b.s), distance(a, b.t));
}
Real distance(const Line& a, const Line& b) {
  return has_intersected(a, b) ? 0 : distance(a, b.s);
}

std::vector<Point> tangency(const Circle& a, const Point& b) {
  const Real dist = distance(a.p, b);
  const int sign = sgn(dist - a.r);
  if (sign == -1) return {};
  if (sign == 0) return {b};
  const Real alpha = (b - a.p).arg(), beta = std::acos(a.r / dist);
  return {
      a.p + Point(a.r * std::cos(alpha + beta), a.r * std::sin(alpha + beta)),
      a.p + Point(a.r * std::cos(alpha - beta), a.r * std::sin(alpha - beta))};
}
int common_tangent_num(const Circle& a, const Circle& b) {
  const Real dist = distance(a.p, b.p);
  int sign = sgn(a.r + b.r - dist);
  if (sign == -1) return 4;
  if (sign == 0) return 3;
  sign = sgn((sgn(a.r - b.r) == -1 ? b.r - a.r : a.r - b.r) - dist);
  if (sign == -1) return 2;
  if (sign == 0) return 1;
  return 0;
}
std::vector<Line> common_tangent(const Circle& a, const Circle& b) {
  std::vector<Line> tangents;
  const Real dist = distance(a.p, b.p), argument = (b.p - a.p).arg();
  int sign = sgn(a.r + b.r - dist);
  if (sign == -1) {
    const Real ac = std::acos((a.r + b.r) / dist);
    Real alpha = argument + ac, cs = std::cos(alpha), sn = std::sin(alpha);
    tangents.emplace_back(a.p + Point(a.r * cs, a.r * sn),
                          b.p + Point(-b.r * cs, -b.r * sn));
    alpha = argument - ac; cs = std::cos(alpha); sn = std::sin(alpha);
    tangents.emplace_back(a.p + Point(a.r * cs, a.r * sn),
                          b.p + Point(-b.r * cs, -b.r * sn));
  } else if (sign == 0) {
    const Point s =
        a.p + Point(a.r * std::cos(argument), a.r * std::sin(argument));
    tangents.emplace_back(s, s + (b.p - a.p).normal_unit_vector().first);
  }
  if (sgn(b.r - a.r) == -1) {
    sign = sgn(a.r - b.r - dist);
    if (sign == -1) {
      const Real at = std::acos((a.r - b.r) / dist);
      Real alpha = argument + at, cs = std::cos(alpha), sn = std::sin(alpha);
      tangents.emplace_back(a.p + Point(a.r * cs, a.r * sn),
                            b.p + Point(b.r * cs, b.r * sn));
      alpha = argument - at; cs = std::cos(alpha); sn = std::sin(alpha);
      tangents.emplace_back(a.p + Point(a.r * cs, a.r * sn),
                            b.p + Point(b.r * cs, b.r * sn));
    } else if (sign == 0) {
      const Point s =
          a.p + Point(a.r * std::cos(argument), a.r * std::sin(argument));
      tangents.emplace_back(s, s + (b.p - a.p).normal_unit_vector().first);
    }
  } else {
    sign = sgn(b.r - a.r - dist);
    if (sign == -1) {
      const Real at = std::acos((b.r - a.r) / dist);
      Real alpha = argument - at, cs = std::cos(alpha), sn = std::sin(alpha);
      tangents.emplace_back(a.p + Point(-a.r * cs, -a.r * sn),
                            b.p + Point(-b.r * cs, -b.r * sn));
      alpha = argument + at; cs = std::cos(alpha); sn = std::sin(alpha);
      tangents.emplace_back(a.p + Point(-a.r * cs, -a.r * sn),
                            b.p + Point(-b.r * cs, -b.r * sn));
    } else if (sign == 0) {
      const Point s =
          b.p + Point(-b.r * std::cos(argument), -b.r * std::sin(argument));
      tangents.emplace_back(s, s + (a.p - b.p).normal_unit_vector().first);
    }
  }
  return tangents;
}

Real intersection_area(const Circle& a, const Circle& b) {
  const Real nor = (b.p - a.p).norm(), dist = std::sqrt(nor);
  if (sgn(a.r + b.r - dist) != 1) return 0;
  if (sgn(std::abs(a.r - b.r) - dist) != -1) {
    return std::min(a.r, b.r) * std::min(a.r, b.r) * PI;
  }
  const Real alpha =
      std::acos((nor + a.r * a.r - b.r * b.r) / (2 * dist * a.r));
  const Real beta = std::acos((nor + b.r * b.r - a.r * a.r) / (2 * dist * b.r));
  return (alpha - std::sin(alpha + alpha) * 0.5) * a.r * a.r +
         (beta - std::sin(beta + beta) * 0.5) * b.r * b.r;
}

using Polygon = std::vector<Point>;

Real area(Polygon a) {
  const int n = a.size();
  a.resize(n + 1);
  a.back() = a.front();
  Real res = 0;
  for (int i = 0; i < n; ++i) {
    res += cross(a[i], a[i + 1]);
  }
  return res * 0.5;
}

Point centroid(Polygon a) {
  const int n = a.size();
  a.resize(n + 1);
  a.back() = a.front();
  Point res(0, 0);
  Real den = 0;
  for (int i = 0; i < n; ++i) {
    const Real cro = cross(a[i], a[i + 1]);
    res += (a[i] + a[i + 1]) / 3 * cro;
    den += cro;
  }
  return res / den;
}

int contains(Polygon a, const Point &b) {
  const int n = a.size();
  a.resize(n + 1);
  a.back() = a.front();
  bool is_in = false;
  for (int i = 0; i < n; ++i) {
    Point p = a[i] - b, q = a[i + 1] - b;
    if (sgn(q.y - p.y) == -1) std::swap(p, q);
    const int sign = sgn(cross(p, q));
    if (sign == 1 && sgn(p.y) != 1 && sgn(q.y) == 1) is_in = !is_in;
    if (sign == 0 && sgn(dot(p, q)) != 1) return 1;
  }
  return is_in ? 2 : 0;
}

bool is_convex(Polygon a) {
  const int n = a.size();
  a.resize(n + 2);
  a[n] = a[0];
  a[n + 1] = a[1];
  for (int i = 1; i <= n; ++i) {
    if (ccw(a[i - 1], a[i], a[i + 1]) == -1) return false;
  }
  return true;
}

Polygon monotone_chain(std::vector<Point> ps, const bool is_tight = true) {
  const int n = ps.size();
  std::sort(ps.begin(), ps.end());
  Polygon convex_hull(n << 1);
  int idx = 0;
  for (int i = 0; i < n; convex_hull[idx++] = ps[i++]) {
    while (idx >= 2 &&
           sgn(cross(convex_hull[idx - 1] - convex_hull[idx - 2],
                     ps[i] - convex_hull[idx - 1])) < is_tight) {
      --idx;
    }
  }
  for (int i = n - 2, border = idx + 1; i >= 0; convex_hull[idx++] = ps[i--]) {
    while (idx >= border &&
           sgn(cross(convex_hull[idx - 1] - convex_hull[idx - 2],
                     ps[i] - convex_hull[idx - 1])) < is_tight) {
      --idx;
    }
  }
  convex_hull.resize(idx - 1);
  return convex_hull;
}

Polygon cut_convex(Polygon a, const Line& b) {
  const int n = a.size();
  a.resize(n + 1);
  a.back() = a.front();
  Polygon res;
  for (int i = 0; i < n; ++i) {
    const int c = ccw(b.s, b.t, a[i]);
    if (c != -1) res.emplace_back(a[i]);
    if (c * ccw(b.s, b.t, a[i + 1]) == -1) {
      res.emplace_back(intersection(Line(a[i], a[i + 1]), b));
    }
  }
  return res.size() < 3 ? Polygon() : res;
}

std::pair<Point, Point> rotating_calipers(Polygon a) {
  const int n = a.size();
  if (n <= 2) {
    assert(n == 2);
    return {a[0], a[1]};
  }
  a.resize(n + 1);
  a.back() = a.front();
  int high = 0, low = 0;
  for (int i = 1; i < n; ++i) {
    if (a[i].y > a[high].y) high = i;
    if (a[i].y < a[low].y) low = i;
  }
  Real max_norm = (a[high] - a[low]).norm();
  int i = high, j = low, argmax_i = i, argmax_j = j;
  do {
    int* i_or_j = &(sgn(cross(a[i + 1] - a[i], a[j + 1] - a[j])) != -1 ? j : i);
    if (++(*i_or_j) == n) *i_or_j = 0;
    const Real tmp = (a[j] - a[i]).norm();
    if (sgn(tmp - max_norm) == 1) {
      max_norm = tmp;
      argmax_i = i; argmax_j = j;
    }
  } while (i != high || j != low);
  return {a[argmax_i], a[argmax_j]};
}

}  // namespace geometry

struct Point {
  ll x, y;
  explicit Point(const ll x = 0, const ll y = 0) : x(x), y(y) {}
  Point& operator-=(const Point& p) {
    x -= p.x; y -= p.y;
    return *this;
  }
  Point operator-(const Point& p) const { return Point(*this) -= p; }
};

ll cross(const Point& a, const Point& b) { return a.x * b.y - a.y * b.x; }

int sgn(ll x) {
  if (x == 0) return 0;
  return x > 0 ? 1 : -1;
}

int main() {
  int n; cin >> n;
  vector<Point> h(n + 2);
  h.front() = Point(-1, -INF);
  REP(i, n) {
    h[i + 1].x = i;
    cin >> h[i + 1].y;
  }
  h.back() = Point(n, -INF);
  vector<Point> convex_hull((n + 2) * 2);
  int m = 0;
  for (int i = 0; i < n + 2; convex_hull[m++] = h[i++]) {
    while (m >= 2 && sgn(cross(convex_hull[m - 1] - convex_hull[m - 2], h[i] - convex_hull[m - 1])) != 1) --m;
  }
  for (int i = n + 2, border = m + 1; i >= 0; convex_hull[m++] = h[i--]) {
    while (m >= border && sgn(cross(convex_hull[m - 1] - convex_hull[m - 2], h[i] - convex_hull[m - 1])) < 1) --m;
  }
  convex_hull.resize(--m);
  int ans = 0;
  REP(i, m) {
    const int l = convex_hull[i].x, r = convex_hull[(i + 1) % m].x;
    if (0 <= l && l < n && 0 <= r && r < n) chmax(ans, abs(l - r));
  }
  cout << ans << '\n';
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7860
final_rank: 8

code_snippet: #include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>=b)return 0; a=b; return 1;}
int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};
long double eps = 1e-9;
long double pi = acos(-1);

template< typename T > istream &operator>>(istream &is, vector< T > &v) {
	for(T &in : v) is >> in;
	return is;
}

template< typename T > ostream &operator<<(ostream &os, const vector< T > &v) {
	for(int i = 0; i < (int) v.size(); i++) {
		os << v[i] << (i + 1 != (int) v.size() ? " " : "");
	}
	return os;
}

/*
正規版
メモ
norm(P) Pの絶対値の2乗 abs(P)の2乗
abs(P) Pの絶対値
arg(P)の戻り値の範囲は[-π, π]
polar(長さ,角度(ラジアン))でPointができる
int(-2.2+0.5)=-1
*/

// #include <bits/stdc++.h>
// using namespace std;
// template<class T,class U>constexpr bool chmin(T&a,const U b){if(a<=b)return false;a=b;return true;}
// template<class T,class U>constexpr bool chmax(T&a,const U b){if(a>=b)return false;a=b;return true;}
// template<class T,class U>constexpr bool bitUP(const T n,const U k){return (n>>k)&1;}



////////////////////////////
// マクロや型
////////////////////////////

using DD=long double;

const DD EPS=1e-9;
const DD INF=1e50;
const DD PI=acosl(-1.0);
#define EQ(a,b) (abs( (a) - (b) )<EPS) //a==b
#define LS(a,b) ( (a)+EPS<(b) ) //a<b
#define GR(a,b) ( (a)>(b)+EPS ) //a>b
#define LE(a,b) ( (a)<(b)+EPS ) //a<=b
#define GE(a,b) ( (a)>(b)-EPS ) //a>=b

#define X real()
#define Y imag()


//点
using Point=complex<DD>;
istream &operator>>(istream &is, Point &p) {
  DD x,y;
  is>>x>>y;
  p=Point(x,y);
  return is;
}

//点a→点bの線分
//aとbが等しい時、色々バグるから注意!
struct Segment{
	Point a,b;
	Segment()=default;
	Segment(Point a,Point b) :a(a),b(b){}
	Segment(DD ax,DD ay,DD bx,DD by):a(ax,ay),b(bx,by){}
	Segment(DD r,Point a) :a(a),b(a+polar((DD)1.0,r)){} 
};
using Line=Segment;

//円
struct Circle{
	Point p;
	DD r;
	Circle()=default;
	Circle(Point p,DD r):p(p),r(r){}
};



////////////////////////////
// 基本計算
////////////////////////////

//度→ラジアン
inline DD torad(const DD deg){return deg*PI/180;}
//ラジアン→度
inline DD todeg(const DD rad){return rad*180/PI;}
//内積 |a||b|cosθ
inline DD dot(const Point &a,const Point &b){return (conj(a)*b).X;}
//外積 |a||b|sinθ
inline DD cross(const Point &a,const Point &b){return (conj(a)*b).Y;}
//ベクトルpを反時計回りにtheta(ラジアン)回転
Point rotate(const Point &p,const DD theta){return p*Point(cos(theta),sin(theta));}

//余弦定理 cos(角度abc(ラジアン))を返す
//長さの対応に注意 ab:辺abの長さ
//verify:https://codeforces.com/gym/102056/problem/F
DD cosine_formula(const DD ab,const DD bc,const DD ca){
	return (ab*ab+bc*bc-ca*ca)/(2*ab*bc);
}

inline bool xy_sort(const Point &a,const Point &b){
	if(a.X+EPS<b.X) return true;
	if(EQ(a.X,b.X) && a.Y+EPS<b.Y) return true;
	return false;
}
inline bool yx_sort(const Point &a,const Point &b){
	if(a.Y+EPS<b.Y) return true;
	if(EQ(a.Y,b.Y) && a.X+EPS<b.X) return true;
	return false;
}


//凸包　アンドリューのアルゴリズム
//O(NlogN)
//反時計回りの多角形を返す
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
vector<Point> ConvexHull(vector<Point> s, const bool on_edge){
	int j;
	if(on_edge) j=-1;
	else j=1;
	int sz=(int)s.size();
	if(sz<3) return s;
	sort(s.begin(),s.end(),yx_sort);

	int n=0;
	vector<Point> res(2*sz);
	for(int i=0;i<sz;i++){
		while(n>=2 && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
			n--;
		}
		res[n]=s[i];
		n++;
	}
	int t=n+1;
	for(int i=sz-2;i>=0;i--){
		while(n>=t && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
			n--;
		}
		res[n]=s[i];
		n++;
	}
	res.resize(n-1);
	return res;
}


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

	int n;
	cin>>n;
	vector<Point> p(n);
	for(int i=0;i<n;i++){
		ll h;
		cin>>h;
		p[i] = Point(i+1, h);
	}
	p.push_back(Point(1,0));
	p.push_back(Point(n,0));
	vector<Point> h = ConvexHull(p,0);
	int ans = 0;
	vector<array<ll,2>> v;
	for(int i=0;i<(int)h.size();i++){
		v.push_back({(ll)h[i].real(), (ll)h[i].imag()});
	}
	sort(all(v));
	for(int i=1;i<(int)v.size();i++){
		chmax(ans, v[i][0] - v[i-1][0]);
	}
	cout << ans << endl;

}
accuracy: 1
time_ms: 40
memory_kb: 17616
final_rank: 19

code_snippet: #include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>=b)return 0; a=b; return 1;}
int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};
long double eps = 1e-9;
long double pi = acos(-1);

template< typename T > istream &operator>>(istream &is, vector< T > &v) {
	for(T &in : v) is >> in;
	return is;
}

template< typename T > ostream &operator<<(ostream &os, const vector< T > &v) {
	for(int i = 0; i < (int) v.size(); i++) {
		os << v[i] << (i + 1 != (int) v.size() ? " " : "");
	}
	return os;
}

/*
正規版
メモ
norm(P) Pの絶対値の2乗 abs(P)の2乗
abs(P) Pの絶対値
arg(P)の戻り値の範囲は[-π, π]
polar(長さ,角度(ラジアン))でPointができる
int(-2.2+0.5)=-1
*/

// #include <bits/stdc++.h>
// using namespace std;
// template<class T,class U>constexpr bool chmin(T&a,const U b){if(a<=b)return false;a=b;return true;}
// template<class T,class U>constexpr bool chmax(T&a,const U b){if(a>=b)return false;a=b;return true;}
// template<class T,class U>constexpr bool bitUP(const T n,const U k){return (n>>k)&1;}



////////////////////////////
// マクロや型
////////////////////////////

using DD=long double;

const DD EPS=1e-9;
const DD INF=1e50;
const DD PI=acosl(-1.0);
#define EQ(a,b) (abs( (a) - (b) )<EPS) //a==b
#define LS(a,b) ( (a)+EPS<(b) ) //a<b
#define GR(a,b) ( (a)>(b)+EPS ) //a>b
#define LE(a,b) ( (a)<(b)+EPS ) //a<=b
#define GE(a,b) ( (a)>(b)-EPS ) //a>=b

#define X real()
#define Y imag()


//点
using Point=complex<DD>;
istream &operator>>(istream &is, Point &p) {
  DD x,y;
  is>>x>>y;
  p=Point(x,y);
  return is;
}

//点a→点bの線分
//aとbが等しい時、色々バグるから注意!
struct Segment{
	Point a,b;
	Segment()=default;
	Segment(Point a,Point b) :a(a),b(b){}
	Segment(DD ax,DD ay,DD bx,DD by):a(ax,ay),b(bx,by){}
	Segment(DD r,Point a) :a(a),b(a+polar((DD)1.0,r)){} 
};
using Line=Segment;

//円
struct Circle{
	Point p;
	DD r;
	Circle()=default;
	Circle(Point p,DD r):p(p),r(r){}
};



////////////////////////////
// 基本計算
////////////////////////////

//度→ラジアン
inline DD torad(const DD deg){return deg*PI/180;}
//ラジアン→度
inline DD todeg(const DD rad){return rad*180/PI;}
//内積 |a||b|cosθ
inline DD dot(const Point &a,const Point &b){return (conj(a)*b).X;}
//外積 |a||b|sinθ
inline DD cross(const Point &a,const Point &b){return (conj(a)*b).Y;}
//ベクトルpを反時計回りにtheta(ラジアン)回転
Point rotate(const Point &p,const DD theta){return p*Point(cos(theta),sin(theta));}

//余弦定理 cos(角度abc(ラジアン))を返す
//長さの対応に注意 ab:辺abの長さ
//verify:https://codeforces.com/gym/102056/problem/F
DD cosine_formula(const DD ab,const DD bc,const DD ca){
	return (ab*ab+bc*bc-ca*ca)/(2*ab*bc);
}

inline bool xy_sort(const Point &a,const Point &b){
	if(a.X+EPS<b.X) return true;
	if(EQ(a.X,b.X) && a.Y+EPS<b.Y) return true;
	return false;
}
inline bool yx_sort(const Point &a,const Point &b){
	if(a.Y+EPS<b.Y) return true;
	if(EQ(a.Y,b.Y) && a.X+EPS<b.X) return true;
	return false;
}


//凸包　アンドリューのアルゴリズム
//O(NlogN)
//反時計回りの多角形を返す
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
vector<Point> ConvexHull(vector<Point> s, const bool on_edge){
	int j;
	if(on_edge) j=-1;
	else j=1;
	int sz=(int)s.size();
	if(sz<3) return s;
	sort(s.begin(),s.end(),yx_sort);

	int n=0;
	vector<Point> res(2*sz);
	for(int i=0;i<sz;i++){
		while(n>=2 && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
			n--;
		}
		res[n]=s[i];
		n++;
	}
	int t=n+1;
	for(int i=sz-2;i>=0;i--){
		while(n>=t && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
			n--;
		}
		res[n]=s[i];
		n++;
	}
	res.resize(n-1);
	return res;
}


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

	int n;
	cin>>n;
	vector<Point> p(n);
	for(int i=0;i<n;i++){
		ll h;
		cin>>h;
		p[i] = Point(i+1, h);
	}
	p.push_back(Point(1,0));
	p.push_back(Point(n,0));
	vector<Point> h = ConvexHull(p,0);
	int ans = 0;
	vector<array<ll,2>> v;
	for(int i=0;i<(int)h.size();i++){
		v.push_back({(ll)h[i].real(), (ll)h[i].imag()});
	}
	sort(all(v));
	for(int i=1;i<(int)v.size();i++){
		chmax(ans, v[i][0] - v[i-1][0]);
	}
	cout << ans << endl;

}
accuracy: 1
time_ms: 40
memory_kb: 17712
final_rank: 20

code_snippet: #pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// #include<ext/pb_ds/tag_and_trait.hpp>
// using namespace __gnu_pbds;
// #include<boost/multiprecision/cpp_int.hpp>
// namespace multiprecisioninteger = boost::multiprecision;
// using cint=multiprecisioninteger::cpp_int;
using namespace std;
using ll=long long;
using datas=pair<ll,ll>;
using ddatas=pair<long double,long double>;
using tdata=pair<ll,datas>;
using vec=vector<ll>;
using mat=vector<vec>;
using pvec=vector<datas>;
using pmat=vector<pvec>;
// using llset=tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;
#define For(i,a,b) for(i=a;i<(ll)b;++i)
#define bFor(i,b,a) for(i=b,--i;i>=(ll)a;--i)
#define rep(i,N) For(i,0,N)
#define rep1(i,N) For(i,1,N)
#define brep(i,N) bFor(i,N,0)
#define brep1(i,N) bFor(i,N,1)
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define vsort(v) sort(all(v))
#define vrsort(v) sort(allr(v))
#define uniq(v) vsort(v),(v).erase(unique(all(v)),(v).end())
#define endl "\n"
#define popcount __builtin_popcountll
#define eb emplace_back
#define print(x) cout<<x<<endl
#define printyes print("Yes")
#define printno print("No")
#define printYES print("YES")
#define printNO print("NO")
#define output(v) do{bool f=0;for(auto outi:v){cout<<(f?" ":"")<<outi;f=1;}cout<<endl;}while(0)
#define matoutput(v) do{for(auto outimat:v)output(outimat);}while(0)
// constexpr ll mod=1000000007;
constexpr ll mod=998244353;
constexpr ll inf=1LL<<60;
constexpr long double eps=1e-9;
const long double PI=acosl(-1);
template<class T,class E> ostream& operator<<(ostream& os,const pair<T,E>& p){return os<<"("<<p.first<<","<<p.second<<")";}
template<class T> ostream& operator<<(ostream& os,const vector<T>& v){
  os<<"{";bool f=false;
  for(auto& x:v){if(f)os<<",";os<<x;f=true;}
  os<<"}";
  return os;
}
template<class T> ostream& operator<<(ostream& os,const set<T>& v){
  os<<"{";bool f=false;
  for(auto& x:v){if(f)os<<",";os<<x;f=true;}
  os<<"}";
  return os;
}
template<class T> ostream& operator<<(ostream& os,const multiset<T>& v){
  os<<"{";bool f=false;
  for(auto& x:v){if(f)os<<",";os<<x;f=true;}
  os<<"}";
  return os;
}
template<class T,class E> ostream& operator<<(ostream& os,const map<T,E>& v){
  os<<"{";bool f=false;
  for(auto& x:v){if(f)os<<",";os<<x;f=true;}
  os<<"}";
  return os;
}
template<class T> inline bool chmax(T& a,const T b){bool x=a<b;if(x)a=b;return x;}
template<class T> inline bool chmin(T& a,const T b){bool x=a>b;if(x)a=b;return x;}
#ifdef DEBUG
void debugg(){cout<<endl;}
template<class T,class... Args>void debugg(const T& x,const Args&... args){cout<<" "<<x;debugg(args...);}
#define debug(...) cout<<__LINE__<<" ["<<#__VA_ARGS__<<"]:",debugg(__VA_ARGS__)
#else
#define debug(...) (void(0))
#endif

inline void startupcpp(void) noexcept{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
}

ll modinv(ll a,const ll m=mod) noexcept{
  ll b=m,u=1,v=0,t;
  while(b){
    t=a/b;
    a-=t*b; swap(a,b);
    u-=t*v; swap(u,v);
  }
  return (u+m)%m;
}

ll moddevide(const ll a,const ll b) noexcept{return (a*modinv(b))%mod;}

vec modncrlistp,modncrlistm;

ll modncr(const ll n,const ll r) noexcept{
  if(n<r||r<0)return 0;
  ll i,size=modncrlistp.size();
  if(size<=n){
    modncrlistp.resize(n+1);
    modncrlistm.resize(n+1);
    if(!size){
      modncrlistp[0]=modncrlistm[0]=1;
      size++;
    }
    For(i,size,n+1)modncrlistp[i]=modncrlistp[i-1]*i%mod;
    modncrlistm[n]=modinv(modncrlistp[n]);
    for(i=n;i>size;--i)modncrlistm[i-1]=modncrlistm[i]*i%mod;
  }
  return modncrlistp[n]*modncrlistm[r]%mod*modncrlistm[n-r]%mod;
}

ll modpow(ll a,ll n,const ll m=mod){
  if(n<0)return 0;
  ll res=1;
  while(n>0){
    if(n&1)res=res*a%m;
    a=a*a%m;
    n>>=1;
  }
  return res;
}

ll solve(vec h){
  ll i,N=h.size(),ans=0;
  vec dp(N,-1);
  rep1(i,N){
    ll res=i-1;
    while(dp[res]>=0&&(h[res]-h[i])*(dp[res]-i)>=(h[dp[res]]-h[i])*(res-i))res=dp[res];
    dp[i]=res;
    chmax(ans,i-res);
  }
  return ans;
}
int main(){
  startupcpp();
  ll N;
  cin>>N;
  vec v(N);
  for(auto& x:v)cin>>x;
  auto ans=solve(v);
  reverse(all(v));
  print(max(ans,solve(v)));
}
accuracy: 1
time_ms: 10
memory_kb: 5452
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
#include <unordered_set>
#include <random>
//#define int long long
#define REP(i,m,n) for(int i=(m);i<(n);i++)
#define rep(i,n) REP(i,0,n)
#define pb push_back
#define all(a) a.begin(),a.end()
#define rall(c) (c).rbegin(),(c).rend()
#define mp make_pair
#define endl '\n'
//#define vec vector<ll>
//#define mat vector<vector<ll> >
#define fi first
#define se second
#define double long double
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
//typedef long double ld;
typedef complex<double> Complex;
const ll INF=1e9+7;
const ll MOD=998244353;
const ll inf=INF*INF;
const ll mod=MOD;
const ll MAX=100010;
const double PI=acos(-1.0);
typedef vector<vector<ll> > mat;
typedef vector<ll> vec;
double pi=M_PI;



void solve(){
    ll n;cin>>n;
    vector<ll>h(n);
    rep(i,n)cin>>h[i];
    stack<pll>st;
    ll ma=0;
    ma=h[0];
    st.push(mp(0,ma));
    ll ans=0;
    REP(i,1,n){
        if(ma>h[i])continue;
        pll nxt=st.top();
        st.pop();
        ans=max(ans,i-nxt.fi);
        while(!st.empty()){
            pll k=st.top();
            st.pop();
            if((i-nxt.fi)*(h[i]-k.se)<=(i-k.fi)*(h[i]-nxt.se)){
                ans=max(ans,i-k.fi);
                nxt=k;
            }else{
                st.push(k);
                break;
            }
        }
        st.push(nxt);
        st.push(mp(i,h[i]));
        ma=h[i];
    }
    reverse(all(h));
    while(!st.empty())st.pop();
    ma=h[0];
    st.push(mp(0,ma));
    REP(i,1,n){
        if(ma>h[i])continue;
        pll nxt=st.top();
        st.pop();
        ans=max(ans,i-nxt.fi);
        while(!st.empty()){
            pll k=st.top();
            st.pop();
            if((i-nxt.fi)*(h[i]-k.se)<=(i-k.fi)*(h[i]-nxt.se)){
                ans=max(ans,i-k.fi);
                nxt=k;
            }else{
                st.push(k);
                break;
            }
        }
        st.push(nxt);
        st.push(mp(i,h[i]));
        ma=h[i];
    }
    cout<<ans<<endl;
}
signed main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3868
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#pragma region Header
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
using f64 = double;
using f80 = long double;
using f128 = __float128;
constexpr i32 operator"" _i32(u64 v)
{
    return v;
}
constexpr i32 operator"" _u32(u64 v)
{
    return v;
}
constexpr i64 operator"" _i64(u64 v)
{
    return v;
}
constexpr u64 operator"" _u64(u64 v)
{
    return v;
}
constexpr f64 operator"" _f64(f80 v)
{
    return v;
}
constexpr f80 operator"" _f80(f80 v)
{
    return v;
}
using Istream = std::istream;
using Ostream = std::ostream;
using Str = std::string;
template<typename T>
using Lt = std::less<T>;
template<typename T>
using Gt = std::greater<T>;
template<typename T>
using IList = std::initializer_list<T>;
template<int n>
using BSet = std::bitset<n>;
template<typename T1, typename T2>
using Pair = std::pair<T1, T2>;
template<typename... Ts>
using Tup = std::tuple<Ts...>;
template<typename T, int N>
using Arr = std::array<T, N>;
template<typename... Ts>
using Deq = std::deque<Ts...>;
template<typename... Ts>
using Set = std::set<Ts...>;
template<typename... Ts>
using MSet = std::multiset<Ts...>;
template<typename... Ts>
using USet = std::unordered_set<Ts...>;
template<typename... Ts>
using UMSet = std::unordered_multiset<Ts...>;
template<typename... Ts>
using Map = std::map<Ts...>;
template<typename... Ts>
using MMap = std::multimap<Ts...>;
template<typename... Ts>
using UMap = std::unordered_map<Ts...>;
template<typename... Ts>
using UMMap = std::unordered_multimap<Ts...>;
template<typename... Ts>
using Vec = std::vector<Ts...>;
template<typename... Ts>
using Stack = std::stack<Ts...>;
template<typename... Ts>
using Queue = std::queue<Ts...>;
template<typename T>
using MaxHeap = std::priority_queue<T>;
template<typename T>
using MinHeap = std::priority_queue<T, Vec<T>, Gt<T>>;
using NSec = std::chrono::nanoseconds;
using USec = std::chrono::microseconds;
using MSec = std::chrono::milliseconds;
using Sec = std::chrono::seconds;
template<typename T>
constexpr T LIMMIN = std::numeric_limits<T>::min();
template<typename T>
constexpr T LIMMAX = std::numeric_limits<T>::max();
template<typename T>
constexpr T INF = (LIMMAX<T> - 1) / 2;
template<typename T>
constexpr T PI = T{3.141592653589793238462643383279502884};
template<typename T = u64>
constexpr T TEN(const int n)
{
    return n == 0 ? T{1} : TEN<T>(n - 1) * T{10};
}
Ostream& operator<<(Ostream& os, i128 v)
{
    bool minus = false;
    if (v < 0) { minus = true, v = -v; }
    Str ans;
    if (v == 0) { ans = "0"; }
    while (v) {
        ans.push_back('0' + v % 10), v /= 10;
    }
    std::reverse(ans.begin(), ans.end());
    return os << (minus ? "-" : "") << ans;
}
Ostream& operator<<(Ostream& os, u128 v)
{
    Str ans;
    if (v == 0) { ans = "0"; }
    while (v) {
        ans.push_back('0' + v % 10), v /= 10;
    }
    std::reverse(ans.begin(), ans.end());
    return os << ans;
}
template<typename T>
bool chmin(T& a, const T& b)
{
    if (a > b) {
        a = b;
        return true;
    } else {
        return false;
    }
}
template<typename T>
bool chmax(T& a, const T& b)
{
    if (a < b) {
        a = b;
        return true;
    } else {
        return false;
    }
}
template<typename T>
constexpr T floorDiv(T x, T y)
{
    if (y < T{}) { x = -x, y = -y; }
    return x >= T{} ? x / y : (x - y + 1) / y;
}
template<typename T>
constexpr T ceilDiv(T x, T y)
{
    if (y < T{}) { x = -x, y = -y; }
    return x >= T{} ? (x + y - 1) / y : x / y;
}
template<typename T, typename I>
constexpr T modPower(T v, I n, T mod)
{
    T ans = 1 % mod;
    for (; n > 0; n >>= 1, (v *= v) %= mod) {
        if (n % 2 == 1) { (ans *= v) %= mod; }
    }
    return ans;
}
template<typename T, typename I>
constexpr T power(T v, I n)
{
    T ans = 1;
    for (; n > 0; n >>= 1, v *= v) {
        if (n % 2 == 1) { ans *= v; }
    }
    return ans;
}
template<typename T, typename I>
constexpr T power(T v, I n, const T& e)
{
    T ans = e;
    for (; n > 0; n >>= 1, v *= v) {
        if (n % 2 == 1) { ans *= v; }
    }
    return ans;
}
template<typename T>
Vec<T> operator+=(Vec<T>& vs1, const Vec<T>& vs2)
{
    vs1.insert(vs1.end(), vs2.begin(), vs2.end());
    return vs1;
}
template<typename T>
Vec<T> operator+(const Vec<T>& vs1, const Vec<T>& vs2)
{
    auto vs = vs1;
    vs += vs2;
    return vs;
}
template<typename Vs, typename V>
void fillAll(Vs& arr, const V& v)
{
    if constexpr (std::is_convertible<V, Vs>::value) {
        arr = v;
    } else {
        for (auto& subarr : arr) {
            fillAll(subarr, v);
        }
    }
}
template<typename Vs>
void sortAll(Vs& vs)
{
    std::sort(std::begin(vs), std::end(vs));
}
template<typename Vs, typename C>
void sortAll(Vs& vs, C comp)
{
    std::sort(std::begin(vs), std::end(vs), comp);
}
template<typename Vs>
void reverseAll(Vs& vs)
{
    std::reverse(std::begin(vs), std::end(vs));
}
template<typename V, typename Vs>
V sumAll(const Vs& vs)
{
    if constexpr (std::is_convertible<Vs, V>::value) {
        return static_cast<V>(vs);
    } else {
        V ans = 0;
        for (const auto& v : vs) {
            ans += sumAll<V>(v);
        }
        return ans;
    }
}
template<typename Vs>
int minInd(const Vs& vs)
{
    return std::min_element(std::begin(vs), std::end(vs)) - std::begin(vs);
}
template<typename Vs>
int maxInd(const Vs& vs)
{
    return std::max_element(std::begin(vs), std::end(vs)) - std::begin(vs);
}
template<typename Vs, typename V>
int lbInd(const Vs& vs, const V& v)
{
    return std::lower_bound(std::begin(vs), std::end(vs), v) - std::begin(vs);
}
template<typename Vs, typename V>
int ubInd(const Vs& vs, const V& v)
{
    return std::upper_bound(std::begin(vs), std::end(vs), v) - std::begin(vs);
}
template<typename T, typename F>
Vec<T> genVec(int n, F gen)
{
    Vec<T> ans;
    std::generate_n(std::back_insert_iterator(ans), n, gen);
    return ans;
}
Vec<int> iotaVec(int n, int offset = 0)
{
    Vec<int> ans(n);
    std::iota(ans.begin(), ans.end(), offset);
    return ans;
}
constexpr int popcount(const u64 v)
{
    return v ? __builtin_popcountll(v) : 0;
}
constexpr int log2p1(const u64 v)
{
    return v ? 64 - __builtin_clzll(v) : 0;
}
constexpr int lsbp1(const u64 v)
{
    return __builtin_ffsll(v);
}
constexpr int clog(const u64 v)
{
    return v ? log2p1(v - 1) : 0;
}
constexpr u64 ceil2(const u64 v)
{
    const int l = clog(v);
    return (l == 64) ? 0_u64 : (1_u64 << l);
}
constexpr u64 floor2(const u64 v)
{
    return v ? (1_u64 << (log2p1(v) - 1)) : 0_u64;
}
constexpr bool ispow2(const u64 v)
{
    return (v > 0) and ((v & (v - 1)) == 0);
}
constexpr bool btest(const u64 mask, const int ind)
{
    return (mask >> ind) & 1_u64;
}
template<typename F>
struct Fix : F
{
    Fix(F&& f) : F{std::forward<F>(f)} {}
    template<typename... Args>
    auto operator()(Args&&... args) const
    {
        return F::operator()(*this, std::forward<Args>(args)...);
    }
};
class irange
{
private:
    struct itr
    {
        itr(i64 start = 0, i64 step = 1) : m_cnt{start}, m_step{step} {}
        bool operator!=(const itr& it) const
        {
            return m_cnt != it.m_cnt;
        }
        int operator*()
        {
            return m_cnt;
        }
        itr& operator++()
        {
            m_cnt += m_step;
            return *this;
        }
        i64 m_cnt, m_step;
    };
    i64 m_start, m_end, m_step;
public:
    irange(i64 start, i64 end, i64 step = 1)
    {
        assert(step != 0);
        const i64 d = std::abs(step);
        const i64 l = (step > 0 ? start : end);
        const i64 r = (step > 0 ? end : start);
        int n = (r - l) / d + ((r - l) % d ? 1 : 0);
        if (l >= r) { n = 0; }
        m_start = start;
        m_end = start + step * n;
        m_step = step;
    }
    itr begin() const
    {
        return itr{m_start, m_step};
    }
    itr end() const
    {
        return itr{m_end, m_step};
    }
};
irange rep(int end)
{
    return irange(0, end, 1);
}
irange per(int rend)
{
    return irange(rend - 1, -1, -1);
}
#pragma COMMENT("[REFS] Xoshiro: https://prng.di.unimi.it")
namespace xoshiro_impl {
u64 x;
u64 next()
{
    uint64_t z = (x += 0x9e3779b97f4a7c15);
    z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
    z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
    return z ^ (z >> 31);
}
} // namespace xoshiro_impl
class Xoshiro32
{
public:
    using result_type = u32;
    using T = result_type;
    Xoshiro32(T seed = 0)
    {
        xoshiro_impl::x = seed;
        s[0] = xoshiro_impl::next();
        s[1] = xoshiro_impl::next();
        s[2] = xoshiro_impl::next();
        s[3] = xoshiro_impl::next();
    }
    static constexpr T min()
    {
        return LIMMIN<T>;
    }
    static constexpr T max()
    {
        return LIMMAX<T>;
    }
    T operator()()
    {
        return next();
    }
private:
    static constexpr T rotl(const T x, int k)
    {
        return (x << k) | (x >> (32 - k));
    }
    T next()
    {
        const T ans = rotl(s[1] * 5, 7) * 9;
        const T t = s[1] << 9;
        s[2] ^= s[0];
        s[3] ^= s[1];
        s[1] ^= s[2];
        s[0] ^= s[3];
        s[2] ^= t;
        s[3] = rotl(s[3], 11);
        return ans;
    }
    T s[4];
};
class Xoshiro64
{
public:
    using result_type = u64;
    using T = result_type;
    Xoshiro64(T seed = 0)
    {
        xoshiro_impl::x = seed;
        s[0] = xoshiro_impl::next();
        s[1] = xoshiro_impl::next();
        s[2] = xoshiro_impl::next();
        s[3] = xoshiro_impl::next();
    }
    static constexpr T min()
    {
        return LIMMIN<T>;
    }
    static constexpr T max()
    {
        return LIMMAX<T>;
    }
    T operator()()
    {
        return next();
    }
private:
    static constexpr T rotl(const T x, int k)
    {
        return (x << k) | (x >> (64 - k));
    }
    T next()
    {
        const T ans = rotl(s[1] * 5, 7) * 9;
        const T t = s[1] << 17;
        s[2] ^= s[0];
        s[3] ^= s[1];
        s[1] ^= s[2];
        s[0] ^= s[3];
        s[2] ^= t;
        s[3] = rotl(s[3], 45);
        return ans;
    }
    T s[4];
};
template<typename Rng>
class RNG
{
public:
    using result_type = typename Rng::result_type;
    using T = result_type;
    static constexpr T min()
    {
        return Rng::min();
    }
    static constexpr T max()
    {
        return Rng::max();
    }
    RNG() : RNG(std::random_device{}()) {}
    RNG(T seed) : m_rng(seed) {}
    T operator()()
    {
        return m_rng();
    }
    template<typename T>
    T val(T min, T max)
    {
        return std::uniform_int_distribution<T>(min, max)(m_rng);
    }
    template<typename T>
    Pair<T, T> pair(T min, T max)
    {
        return std::minmax({val<T>(min, max), val<T>(min, max)});
    }
    template<typename T>
    Vec<T> vec(int n, T min, T max)
    {
        return genVec<T>(n, [&]() { return val<T>(min, max); });
    }
    template<typename T>
    Vec<Vec<T>> vvec(int n, int m, T min, T max)
    {
        return genVec<Vec<T>>(n, [&]() { return vec(m, min, max); });
    }
private:
    Rng m_rng;
};
RNG<std::mt19937> rng;
RNG<std::mt19937_64> rng64;
RNG<Xoshiro32> rng_xo;
RNG<Xoshiro64> rng_xo64;
class Scanner
{
public:
    Scanner(Istream& is = std::cin) : m_is{is}
    {
        m_is.tie(nullptr)->sync_with_stdio(false);
    }
    template<typename T>
    T val()
    {
        T v;
        return m_is >> v, v;
    }
    template<typename T>
    T val(T offset)
    {
        return val<T>() - offset;
    }
    template<typename T>
    Vec<T> vec(int n)
    {
        return genVec<T>(n, [&]() { return val<T>(); });
    }
    template<typename T>
    Vec<T> vec(int n, T offset)
    {
        return genVec<T>(n, [&]() { return val<T>(offset); });
    }
    template<typename T>
    Vec<Vec<T>> vvec(int n, int m)
    {
        return genVec<Vec<T>>(n, [&]() { return vec<T>(m); });
    }
    template<typename T>
    Vec<Vec<T>> vvec(int n, int m, const T offset)
    {
        return genVec<Vec<T>>(n, [&]() { return vec<T>(m, offset); });
    }
    template<typename... Args>
    auto tup()
    {
        return Tup<Args...>{val<Args>()...};
    }
    template<typename... Args>
    auto tup(const Args&... offsets)
    {
        return Tup<Args...>{val<Args>(offsets)...};
    }
private:
    Istream& m_is;
};
Scanner in;
class Printer
{
public:
    Printer(Ostream& os = std::cout) : m_os{os}
    {
        m_os << std::fixed << std::setprecision(15);
    }
    template<typename... Args>
    int operator()(const Args&... args)
    {
        dump(args...);
        return 0;
    }
    template<typename... Args>
    int ln(const Args&... args)
    {
        dump(args...), m_os << '\n';
        return 0;
    }
    template<typename... Args>
    int el(const Args&... args)
    {
        dump(args...), m_os << std::endl;
        return 0;
    }
private:
    template<typename T>
    void dump(const T& v)
    {
        m_os << v;
    }
    template<typename T>
    void dump(const Vec<T>& vs)
    {
        for (const int i : rep(vs.size())) {
            m_os << (i ? " " : ""), dump(vs[i]);
        }
    }
    template<typename T>
    void dump(const Vec<Vec<T>>& vss)
    {
        for (const int i : rep(vss.size())) {
            m_os << (i ? "\n" : ""), dump(vss[i]);
        }
    }
    template<typename T, typename... Ts>
    int dump(const T& v, const Ts&... args)
    {
        dump(v), m_os << ' ', dump(args...);
        return 0;
    }
    Ostream& m_os;
};
Printer out;
template<typename T, int n, int i = 0>
auto ndVec(int const (&szs)[n], const T x = T{})
{
    if constexpr (i == n) {
        return x;
    } else {
        return std::vector(szs[i], ndVec<T, n, i + 1>(szs, x));
    }
}
template<typename T, typename F>
T binSearch(T ng, T ok, F check)
{
    while (std::abs(ok - ng) > 1) {
        const T mid = (ok + ng) / 2;
        (check(mid) ? ok : ng) = mid;
    }
    return ok;
}
template<u32 mod_, u32 root_, u32 max2p_>
class modint
{
    template<typename U = u32&>
    static U modRef()
    {
        static u32 s_mod = 0;
        return s_mod;
    }
    template<typename U = u32&>
    static U rootRef()
    {
        static u32 s_root = 0;
        return s_root;
    }
    template<typename U = u32&>
    static U max2pRef()
    {
        static u32 s_max2p = 0;
        return s_max2p;
    }
public:
    template<typename U = const u32>
    static constexpr std::enable_if_t<mod_ != 0, U> mod()
    {
        return mod_;
    }
    template<typename U = const u32>
    static std::enable_if_t<mod_ == 0, U> mod()
    {
        return modRef();
    }
    template<typename U = const u32>
    static constexpr std::enable_if_t<mod_ != 0, U> root()
    {
        return root_;
    }
    template<typename U = const u32>
    static std::enable_if_t<mod_ == 0, U> root()
    {
        return rootRef();
    }
    template<typename U = const u32>
    static constexpr std::enable_if_t<mod_ != 0, U> max2p()
    {
        return max2p_;
    }
    template<typename U = const u32>
    static std::enable_if_t<mod_ == 0, U> max2p()
    {
        return max2pRef();
    }
    template<typename U = u32>
    static void setMod(std::enable_if_t<mod_ == 0, U> m)
    {
        modRef() = m;
    }
    template<typename U = u32>
    static void setRoot(std::enable_if_t<mod_ == 0, U> r)
    {
        rootRef() = r;
    }
    template<typename U = u32>
    static void setMax2p(std::enable_if_t<mod_ == 0, U> m)
    {
        max2pRef() = m;
    }
    constexpr modint() : m_val{0} {}
    constexpr modint(i64 v) : m_val{normll(v)} {}
    constexpr void setRaw(u32 v)
    {
        m_val = v;
    }
    constexpr modint operator-() const
    {
        return modint{0} - (*this);
    }
    constexpr modint& operator+=(const modint& m)
    {
        m_val = norm(m_val + m.val());
        return *this;
    }
    constexpr modint& operator-=(const modint& m)
    {
        m_val = norm(m_val + mod() - m.val());
        return *this;
    }
    constexpr modint& operator*=(const modint& m)
    {
        m_val = normll((i64)m_val * (i64)m.val() % (i64)mod());
        return *this;
    }
    constexpr modint& operator/=(const modint& m)
    {
        return *this *= m.inv();
    }
    constexpr modint operator+(const modint& m) const
    {
        auto v = *this;
        return v += m;
    }
    constexpr modint operator-(const modint& m) const
    {
        auto v = *this;
        return v -= m;
    }
    constexpr modint operator*(const modint& m) const
    {
        auto v = *this;
        return v *= m;
    }
    constexpr modint operator/(const modint& m) const
    {
        auto v = *this;
        return v /= m;
    }
    constexpr bool operator==(const modint& m) const
    {
        return m_val == m.val();
    }
    constexpr bool operator!=(const modint& m) const
    {
        return not(*this == m);
    }
    friend Istream& operator>>(Istream& is, modint& m)
    {
        i64 v;
        return is >> v, m = v, is;
    }
    friend Ostream& operator<<(Ostream& os, const modint& m)
    {
        return os << m.val();
    }
    constexpr u32 val() const
    {
        return m_val;
    }
    template<typename I>
    constexpr modint pow(I n) const
    {
        return power(*this, n);
    }
    constexpr modint inv() const
    {
        return pow(mod() - 2);
    }
    static modint sinv(u32 n)
    {
        static Vec<modint> is{1, 1};
        for (u32 i = (u32)is.size(); i <= n; i++) {
            is.push_back(-is[mod() % i] * (mod() / i));
        }
        return is[n];
    }
    static modint fact(u32 n)
    {
        static Vec<modint> fs{1, 1};
        for (u32 i = (u32)fs.size(); i <= n; i++) {
            fs.push_back(fs.back() * i);
        }
        return fs[n];
    }
    static modint ifact(u32 n)
    {
        static Vec<modint> ifs{1, 1};
        for (u32 i = (u32)ifs.size(); i <= n; i++) {
            ifs.push_back(ifs.back() * sinv(i));
        }
        return ifs[n];
    }
    static modint comb(int n, int k)
    {
        return k > n or k < 0 ? modint{0} : fact(n) * ifact(n - k) * ifact(k);
    }
private:
    static constexpr u32 norm(u32 x)
    {
        return x < mod() ? x : x - mod();
    }
    static constexpr u32 normll(i64 x)
    {
        return norm(u32(x % (i64)mod() + (i64)mod()));
    }
    u32 m_val;
};
using modint_1000000007 = modint<1000000007, 5, 1>;
using modint_998244353 = modint<998244353, 3, 23>;
template<int id>
using modint_dynamic = modint<0, 0, id>;
template<typename T = int>
class Graph
{
    struct Edge
    {
        Edge() = default;
        Edge(int i, int t, T c) : id{i}, to{t}, cost{c} {}
        int id;
        int to;
        T cost;
        operator int() const
        {
            return to;
        }
    };
public:
    Graph(int n) : m_v{n}, m_edges(n) {}
    void addEdge(int u, int v, bool bi = false)
    {
        assert(0 <= u and u < m_v);
        assert(0 <= v and v < m_v);
        m_edges[u].emplace_back(m_e, v, 1);
        if (bi) { m_edges[v].emplace_back(m_e, u, 1); }
        m_e++;
    }
    void addEdge(int u, int v, const T& c, bool bi = false)
    {
        assert(0 <= u and u < m_v);
        assert(0 <= v and v < m_v);
        m_edges[u].emplace_back(m_e, v, c);
        if (bi) { m_edges[v].emplace_back(m_e, u, c); }
        m_e++;
    }
    const Vec<Edge>& operator[](const int u) const
    {
        assert(0 <= u and u < m_v);
        return m_edges[u];
    }
    Vec<Edge>& operator[](const int u)
    {
        assert(0 <= u and u < m_v);
        return m_edges[u];
    }
    int v() const
    {
        return m_v;
    }
    int e() const
    {
        return m_e;
    }
    friend Ostream& operator<<(Ostream& os, const Graph& g)
    {
        for (int u : rep(g.v())) {
            for (const auto& [id, v, c] : g[u]) {
                os << "[" << id << "]: ";
                os << u << "->" << v << "(" << c << ")\n";
            }
        }
        return os;
    }
    Vec<T> sizes(int root = 0) const
    {
        const int N = v();
        assert(0 <= root and root < N);
        Vec<T> ss(N, 1);
        Fix([&](auto dfs, int u, int p) -> void {
            for (const auto& [id, v, c] : m_edges[u]) {
                static_cast<void>(id);
                if (v == p) { continue; }
                dfs(v, u);
                ss[u] += ss[v];
            }
        })(root, -1);
        return ss;
    }
    Vec<T> depths(int root = 0) const
    {
        const int N = v();
        assert(0 <= root and root < N);
        Vec<T> ds(N, 0);
        Fix([&](auto dfs, int u, int p) -> void {
            for (const auto& [id, v, c] : m_edges[u]) {
                static_cast<void>(id);
                if (v == p) { continue; }
                ds[v] = ds[u] + c;
                dfs(v, u);
            }
        })(root, -1);
        return ds;
    }
    Vec<int> parents(int root = 0) const
    {
        const int N = v();
        assert(0 <= root and root < N);
        Vec<int> ps(N, -1);
        Fix([&](auto dfs, int u, int p) -> void {
            for (const auto& [id, v, c] : m_edges[u]) {
                static_cast<void>(id);
                if (v == p) { continue; }
                ps[v] = u;
                dfs(v, u);
            }
        })(root, -1);
        return ps;
    }
private:
    int m_v;
    int m_e = 0;
    Vec<Vec<Edge>> m_edges;
};
#pragma endregion
int main()
{
    const auto N = in.val<int>();
    const auto Hs = in.vec<i64>(N);
    Vec<int> vs;
    for (int i : rep(N)) {
        if (vs.size() < 2) {
            vs.push_back(i);
        } else {
            const int nv = i;
            bool need = false;
            while (vs.size() >= 2) {
                const int pv = vs[vs.size() - 2];
                const int v = vs[vs.size() - 1];
                if ((Hs[v] - Hs[pv]) * (nv - pv)
                    <= (Hs[nv] - Hs[pv]) * (v - pv)) {
                    vs.pop_back();
                } else {
                    break;
                }
            }
            vs.push_back(nv);
        }
    }
    void(0);
    if (vs.size() < 2) {
        out.ln(0);
    } else {
        int ans = 0;
        for (int i : rep(vs.size() - 1)) {
            chmax(ans, vs[i + 1] - vs[i]);
        }
        out.ln(ans);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4164
final_rank: 2

code_snippet: // #pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<unsigned int> { using type = unsigned long long; };
template <>
struct safely_multipliable<unsigned long long> { using type = __uint128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;
using ll = long long;
using uint = unsigned int;
using ull  = unsigned long long;

template <typename T> using vec  = std::vector<T>;
template <typename T> using vec2 = vec<vec <T>>;
template <typename T> using vec3 = vec<vec2<T>>;
template <typename T> using vec4 = vec<vec3<T>>;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) (iterable).begin(), (iterable).end()
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

// ! I/O utilities

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U> &a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
// array
template <typename T, size_t N>
std::ostream& operator<<(std::ostream& out, const std::array<T, N> &a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head &head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U> &a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...> &a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T> &a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
// array
template <typename T, size_t N>
std::istream& operator>>(std::istream& in, std::array<T, N> &a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    ( std::cin >> ... >> args );
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcount(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcount(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int popcount(const T x) { return __builtin_popcountll(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x)   : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> - 1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x)  { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

struct all_subset {
    struct all_subset_iter {
        const int s; int t;
        constexpr all_subset_iter(int s) : s(s), t(s + 1) {}
        constexpr auto operator*() const { return t; }
        constexpr auto operator++() {}
        constexpr auto operator!=(std::nullptr_t) { return t ? (--t &= s, true) : false; }
    };
    int s;
    constexpr all_subset(int s) : s(s) {}
    constexpr auto begin() { return all_subset_iter(s); }
    constexpr auto end()   { return nullptr; }
};

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable &iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}
template <typename T>
auto generate_range_vector(T l, T r) {
    return generate_vector(r - l, [l](int i) { return l + i; });
}
template <typename T>
auto generate_range_vector(T n) {
    return generate_range_vector(0, n);
}

template <typename T>
void sort_unique_erase(std::vector<T> &a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

template <typename InputIterator, typename BiConsumer>
auto foreach_adjacent_values(InputIterator first, InputIterator last, BiConsumer f) -> decltype(f(*first++, *last), void()) {
    if (first != last) for (auto itr = first, itl = itr++; itr != last; itl = itr++) f(*itl, *itr);
}
template <typename Container, typename BiConsumer>
auto foreach_adjacent_values(Container c, BiConsumer f) -> decltype(c.begin(), c.end(), void()){
    foreach_adjacent_values(c.begin(), c.end(), f);
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T &x, const T &y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T &x, const T &y) {
    if (y <= x) return false;
    x = y;
    return true;
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_ {};

// ! code from here

namespace integral_geometry {
    template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
    std::vector<int> convex_hull(const std::vector<std::pair<T, T>> &points) {
        const int n = points.size();
        std::vector<int> sorted(n);
        std::iota(sorted.begin(), sorted.end(), 0);
        std::sort(sorted.begin(), sorted.end(), [&points](int i, int j) {
            auto &a = points[i], &b = points[j];
            return a.first == b.first ? a.second < b.second : a.first < b.first;
        });
        std::vector<char> used(n, false);
        sorted.resize(2 * n - 1);
        std::copy(sorted.rbegin() + n, sorted.rend(), sorted.begin() + n);
        std::vector<int> res;
        res.reserve(n);
        int first = sorted[0], last = sorted[n - 1];
        auto isp_pos = [](T x1, T y1, T x2, T y2) -> bool {
            T det = x1 * y2 - y1 * x2;
            return det > 0;
        };
        for (int k : sorted) {
            if (k != first and used[k]) continue;
            for (int sz = res.size(); sz >= 2; --sz) {
                int i = res[sz - 2], j = res[sz - 1];
                if (j == last) break;
                T ab_x = points[j].first - points[i].first, ab_y = points[j].second - points[i].second;
                T bc_x = points[k].first - points[j].first, bc_y = points[k].second - points[j].second;
                if (isp_pos(ab_x, ab_y, bc_x, bc_y)) break;
                res.pop_back(), used[j] = false;
            }
            if (not used[k]) res.push_back(k);
            used[k] = true;
        }
        return res;
    }
}

int main() {
    input(int, n);
    vector<int> h(n);
    read(h);

    vector<pair<long long, long long>> points;
    points.emplace_back(-1, -1000000000);
    rep(i, n) {
        points.emplace_back(i, h[i]);
    }
    points.emplace_back(n, -1000000000);

    auto ps = integral_geometry::convex_hull(points);

    sort(all(ps));
    
    int ans = 0;
    int sz = ps.size();
    rep(i, 1, sz - 2) {
        chmax(ans, ps[i + 1] - ps[i]);
    }
    print(ans);
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6368
final_rank: 4

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
int N;
int H[1<<17];
int Lt[1<<17],Rt[1<<17];
int main()
{
	cin>>N;
	vector<pair<int,int> >Hi(N);
	for(int i=0;i<N;i++)
	{
		cin>>H[i];
		Hi[i]=make_pair(H[i],i);
		Lt[i]=Rt[i]=-1;
	}
	sort(Hi.begin(),Hi.end());
	reverse(Hi.begin(),Hi.end());
	int ans=0;
	set<int>S;
	for(pair<int,int>p:Hi)
	{
		int id=p.second;
		int l=-1,r=N;
		auto it=S.lower_bound(id);
		if(it!=S.end())r=*it;
		if(it!=S.begin())
		{
			it--;
			l=*it;
		}
		S.insert(id);
		if(l>=0)
		{
			while(l>=0)
			{
				int i=Lt[l];
				Lt[id]=l;
				if(i>=0&&(long)(H[i]-H[id])*(id-l)>=(long)(H[l]-H[id])*(id-i))l=i;
				else l=-1;
			}
			ans=max(ans,id-Lt[id]);
		}
		if(r<N)
		{
			while(r<N)
			{
				int i=Rt[r];
				Rt[id]=r;
				if(i>=0&&(long)(H[i]-H[id])*(r-id)>=(long)(H[r]-H[id])*(i-id))r=i;
				else r=N;
			}
			ans=max(ans,Rt[id]-id);
		}
	}
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 50
memory_kb: 9712
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;
using ll = long long;

struct Pos {
  ll x, y;
 
  bool operator< (const Pos& other) const {
    return (x == other.x ? y < other.y : x < other.x);
  }
};
 
inline ll cross(Pos &a, Pos &b, Pos &c) {
  return (((b.x - a.x) * (c.y - a.y)) - ((b.y - a.y) * (c.x - a.x)));
}
 
void convex_hull(vector<Pos> &ps, vector<Pos> &qs) {
  sort(ps.begin(), ps.end());
  qs.clear();
  qs.reserve(ps.size());
  int n = ps.size();
  for(auto p : ps) {
    // 外積判定の等号なし => 凸包の直線上にある点も含む
    while(qs.size() > 1 && cross(qs[qs.size()-2], qs[qs.size()-1], p) >= 0) {
      qs.pop_back();
    }
    qs.push_back(p);
  }
  int t = qs.size();
 
  for(int i = n-2; i >= 0; --i) {
    Pos &p = ps[i];
    while(qs.size() > t && cross(qs[qs.size()-2], qs[qs.size()-1], p) >= 0) {
      qs.pop_back();
    }
    qs.push_back(p);
  }
  qs.pop_back();
}

ll h[100010];
int main(){
    int i,n; cin >> n;
    vector<Pos> ps,qs;
    for(i=0;i<n;i++){
        cin >> h[i];
        ps.push_back({i,h[i]});
    }
    ps.push_back({0,0}); ps.push_back({n - 1,0});
    convex_hull(ps,qs);
    ll ans = 0;
    for(i=0;i<qs.size();i++){
        int nx = (i + 1)%(int)(qs.size());
        if(qs[i].y>0 && qs[nx].y>0){
            //cout << qs[i].x << " " << qs[nx].x << endl;
            ans = max(ans,abs(qs[i].x - qs[nx].x));
        }
    }
    /*
    for(i=0;i<qs.size();i++){
        cout << qs[i].x << " " << qs[i].y << " ";
        cout << endl;
    }*/
    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 6684
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb(...) emplace_back(__VA_ARGS__)
#define mp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define lscan(x) scanf("%I64d", &x)
#define lprint(x) printf("%I64d", x)
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, n) for (ll i = (ll)n - 1; i >= 0; i--)
#define REP(i, l, r) for (ll i = l; i < (r); i++)
#define REP2(i, l, r) for (ll i = (ll)r - 1; i >= (l); i--)
#define siz(x) (ll) x.size()
template <class T>
using rque = priority_queue<T, vector<T>, greater<T>>;

template <class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return 1;
    }
    return 0;
}

template <class T>
bool chmax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return 1;
    }
    return 0;
}

template <class T>
void print(vector<T> a) {
    if (a.empty())
        cout << '\n';
    else {
        for (int i = 0; i < a.size(); i++)
            cout << a[i] << (i + 1 == a.size() ? '\n' : ' ');
    }
}

// __int128_t gcd(__int128_t a, __int128_t b) {
//     if (a == 0)
//         return b;
//     if (b == 0)
//         return a;
//     __int128_t cnt = a % b;
//     while (cnt != 0) {
//         a = b;
//         b = cnt;
//         cnt = a % b;
//     }
//     return b;
// }

long long extGCD(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

struct UnionFind {
    vector<ll> data;
    int num;

    UnionFind(int sz) {
        data.assign(sz, -1);
        num = sz;
    }

    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y)
            return (false);
        if (data[x] > data[y])
            swap(x, y);
        data[x] += data[y];
        data[y] = x;
        num--;
        return (true);
    }

    int find(int k) {
        if (data[k] < 0)
            return (k);
        return (data[k] = find(data[k]));
    }

    ll size(int k) {
        return (-data[find(k)]);
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    int operator[](int k) {
        return find(k);
    }
};

template <int mod>
struct Mod_Int {
    int x;

    Mod_Int() : x(0) {
    }

    Mod_Int(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {
    }

    static int get_mod() {
        return mod;
    }

    Mod_Int &operator+=(const Mod_Int &p) {
        if ((x += p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator-=(const Mod_Int &p) {
        if ((x += mod - p.x) >= mod)
            x -= mod;
        return *this;
    }

    Mod_Int &operator*=(const Mod_Int &p) {
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }

    Mod_Int &operator/=(const Mod_Int &p) {
        *this *= p.inverse();
        return *this;
    }

    Mod_Int &operator++() {
        return *this += Mod_Int(1);
    }

    Mod_Int operator++(int) {
        Mod_Int tmp = *this;
        ++*this;
        return tmp;
    }

    Mod_Int &operator--() {
        return *this -= Mod_Int(1);
    }

    Mod_Int operator--(int) {
        Mod_Int tmp = *this;
        --*this;
        return tmp;
    }

    Mod_Int operator-() const {
        return Mod_Int(-x);
    }

    Mod_Int operator+(const Mod_Int &p) const {
        return Mod_Int(*this) += p;
    }

    Mod_Int operator-(const Mod_Int &p) const {
        return Mod_Int(*this) -= p;
    }

    Mod_Int operator*(const Mod_Int &p) const {
        return Mod_Int(*this) *= p;
    }

    Mod_Int operator/(const Mod_Int &p) const {
        return Mod_Int(*this) /= p;
    }

    bool operator==(const Mod_Int &p) const {
        return x == p.x;
    }

    bool operator!=(const Mod_Int &p) const {
        return x != p.x;
    }

    Mod_Int inverse() const {
        assert(*this != Mod_Int(0));
        return pow(mod - 2);
    }

    Mod_Int pow(long long k) const {
        Mod_Int now = *this, ret = 1;
        for (; k > 0; k >>= 1, now *= now) {
            if (k & 1)
                ret *= now;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const Mod_Int &p) {
        return os << p.x;
    }

    friend istream &operator>>(istream &is, Mod_Int &p) {
        long long a;
        is >> a;
        p = Mod_Int<mod>(a);
        return is;
    }
};

ll mpow2(ll x, ll n, ll mod) {
    ll ans = 1;
    x %= mod;
    while (n != 0) {
        if (n & 1)
            ans = ans * x % mod;
        x = x * x % mod;
        n = n >> 1;
    }
    return ans;
}

ll modinv2(ll a, ll mod) {
    ll b = mod, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= mod;
    if (u < 0)
        u += mod;
    return u;
}

// constexpr int mod = 1000000007;
constexpr int mod = 998244353;
// constexpr int mod = 31607;
using mint = Mod_Int<mod>;

mint mpow(mint x, ll n) {
    mint ans = 1;
    while (n != 0) {
        if (n & 1)
            ans *= x;
        x *= x;
        n = n >> 1;
    }
    return ans;
}

// ----- library -------
template <typename T>
vector<pair<T, T>> convex_hull_integer(vector<pair<T, T>> p) {
    sort(begin(p), end(p));
    int n = p.size(), k = 0;
    if (n == 1)
        return p;
    vector<pair<T, T>> ch(2 * n);
    for (int i = n - 1; i >= 0; ch[k++] = p[i--]) {
        while (k >= 2) {
            T x1 = ch[k - 1].first - ch[k - 2].first, y1 = ch[k - 1].second - ch[k - 2].second;
            T x2 = p[i].first - ch[k - 1].first, y2 = p[i].second - ch[k - 1].second;
            if (x1 * y2 - x2 * y1 <= 0) {
                k--;
            } else {
                break;
            }
        }
    }
    ch.resize(k);
    return ch;
}
// ----- library -------

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);

    int n;
    cin >> n;
    vector<int> h(n);
    rep(i, n) cin >> h[i];
    vector<pair<ll, ll>> p;
    rep(i, n) p.pb(i, h[i]);
    auto res = convex_hull_integer<ll>(p);
    ll ans = 0;
    rep(i, siz(res) - 1) chmax(ans, abs(res[i + 1].first - res[i].first));
    cout << ans << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 10000
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#include <complex>
#include <random>
#include <functional>
using namespace std;
using ll = long long;
#define all(A) A.begin(),A.end()
#define ALL(A) A.begin(),A.end()
using vll = vector<ll>;
using vvll = vector<vll>;
#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)

struct Point {
    ll x, y;
    ll A;
    bool operator <(const Point& p) const {
        return x < p.x || (x == p.x && y < p.y);
    }
};

double cross(const Point& O, const Point& A, const Point& B)
{
    return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x);
}

vector<Point> convex_hull(vector<Point> P)
{
    size_t n = P.size(), k = 0;
    if (n <= 3) return P;
    vector<Point> H(2 * n);

    // Sort points lexicographically
    sort(P.begin(), P.end());

    // Build lower hull
    for (size_t i = 0; i < n; ++i) {
        while (k >= 2 && cross(H[k - 2], H[k - 1], P[i]) <= 0) k--;
        H[k++] = P[i];
    }

    // Build upper hull
    for (size_t i = n - 1, t = k + 1; i > 0; --i) {
        while (k >= t && cross(H[k - 2], H[k - 1], P[i - 1]) <= 0) k--;
        H[k++] = P[i - 1];
    }

    H.resize(k - 1);
    return H;

}

int main() {
    ll N;
    cin>>N;
    vector<Point> P(N+2);
    rep(h,N){
        ll H;
        cin>>H;
        P[h+1]=Point({h+1,H});
    }
    P[0]=Point({0,-10000009});
    P[N+1]=Point({N+1,-10000009});
    auto V=convex_hull(P);
    sort(all(V));
    ll n=V.size();
    ll an=V[1].x-V[0].x-1;
    rep(i,n-3){
        an=max(an,V[i+2].x-V[i+1].x);
    }
    an=max(V[n-1].x-V[n-2].x-1,an);
    cout<<an<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 12548
final_rank: 16