import
java.util.*;
public
class
GFG {
static
class
Query {
int
l, r, x, index;
}
static
class
ArrayElement {
int
val, index;
}
static
boolean
cmp1(Query q1, Query q2) {
return
q1.x < q2.x;
}
static
boolean
cmp2(ArrayElement x, ArrayElement y) {
return
x.val < y.val;
}
static
void
update(
int
[] Fenwick,
int
index,
int
val,
int
n) {
while
(index <= n) {
Fenwick[index] += val;
index += index & (-index);
}
}
static
int
query(
int
[] Fenwick,
int
index,
int
n) {
int
sum =
0
;
while
(index >
0
) {
sum = sum + Fenwick[index];
index -= index & (-index);
}
return
sum;
}
static
int
maxLength(
int
n, ArrayList<Integer> v) {
int
[] where =
new
int
[n +
2
];
ArrayElement[] arr =
new
ArrayElement[n];
Query[] queries =
new
Query[
4
* n];
Query[] ans =
new
Query[n];
for
(
int
i =
1
; i <= n; ++i) {
v.set(i -
1
, v.get(i -
1
) -
1
);
int
x = v.get(i -
1
);
where[x] = i -
1
;
arr[i -
1
] =
new
ArrayElement();
arr[i -
1
].val = x;
arr[i -
1
].index = i -
1
;
}
if
(n <=
2
) {
System.out.println(n);
return
0
;
}
int
left = n, right =
0
, mx =
0
;
int
j =
0
;
for
(
int
i = n -
1
; i >=
0
; --i) {
left = Math.min(left, where[i]);
right = Math.max(right, where[i]);
int
diff = right - left;
if
(diff ==
0
|| diff ==
1
) {
continue
;
}
int
val1 = v.get(left);
int
val2 = v.get(right);
int
minn = Math.min(val1, val2);
queries[j] =
new
Query();
queries[j].x = minn;
queries[j].index = j;
queries[j].l = left +
1
;
queries[j].r = right -
1
;
++j;
}
int
[] Fenwick =
new
int
[n +
1
];
int
q = j -
1
;
ArrayElement[] sortedArr = Arrays.copyOfRange(arr,
0
, n +
1
);
Query[] sortedQueries = Arrays.copyOfRange(queries,
0
, q +
1
);
Query[] sortedAns =
new
Query[n];
int
curr =
0
;
Query[] sortedAnsTemp = Arrays.copyOfRange(sortedAns,
0
, n);
for
(
int
i =
0
; i <= q; ++i) {
while
(sortedArr[curr].val <= sortedQueries[i].x && curr < n) {
update(Fenwick, sortedArr[curr].index +
1
,
1
, n);
curr++;
}
sortedAnsTemp[sortedQueries[i].index] =
new
Query();
sortedAnsTemp[sortedQueries[i].index].x = query(Fenwick, sortedQueries[i].r +
1
, n) - query(Fenwick, sortedQueries[i].l, n);
sortedAnsTemp[sortedQueries[i].index].index = sortedQueries[i].index;
}
for
(
int
i =
0
; i <= q; ++i) {
mx = Math.max(mx, sortedAnsTemp[i].x);
}
mx = mx +
2
;
return
mx;
}
public
static
void
main(String[] args) {
int
n =
6
;
ArrayList<Integer> v =
new
ArrayList<>(Arrays.asList(
4
,
2
,
6
,
5
,
3
,
1
));
System.out.println(maxLength(n, v));
}
}