#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
struct Range {
int l, r;
} olis[N], olds[N];
int n, ans;
int a[N];
int lis[N], lds[N], li, ld;
int len_i[N], len_d[N];
namespace SegT1 {
int mx[4 * N], tag[4 * N];
inline int lc(int x) { return x << 1; }
inline int rc(int x) { return x << 1 | 1; }
inline void push_up(int p) { mx[p] = max(mx[lc(p)], mx[rc(p)]); }
inline void spread(int p, int tg) { tag[p] += tg; mx[p] += tg; }
inline void push_down(int p) { if(tag[p]) spread(lc(p), tag[p]), spread(rc(p), tag[p]), tag[p] = 0; }
void add(int p, int l, int r, int ql, int qr, int v) {
if(ql <= l && r <= qr) { spread(p, v); return; }
int mid = (l + r) >> 1; push_down(p);
if(ql <= mid) add(lc(p), l, mid, ql, qr, v);
if(mid < qr) add(rc(p), mid + 1, r, ql, qr, v);
push_up(p);
}
int query(int p, int l, int r, int ql, int qr) {
if(ql > qr) return -INF;
if(ql <= l && r <= qr) return mx[p];
int mid = (l + r) >> 1, res = 0; push_down(p);
if(ql <= mid) res = query(lc(p), l, mid, ql, qr);
if(mid < qr) res = max(res, query(rc(p), mid + 1, r, ql, qr));
return res;
}
}
namespace SegT2 {
int mx[4 * N], tag[4 * N];
inline int lc(int x) { return x << 1; }
inline int rc(int x) { return x << 1 | 1; }
inline void push_up(int p) { mx[p] = max(mx[lc(p)], mx[rc(p)]); }
inline void spread(int p, int tg) { tag[p] += tg; mx[p] += tg; }
inline void push_down(int p) { if(tag[p]) spread(lc(p), tag[p]), spread(rc(p), tag[p]), tag[p] = 0; }
void add(int p, int l, int r, int ql, int qr, int v) {
if(ql <= l && r <= qr) { spread(p, v); return; }
int mid = (l + r) >> 1; push_down(p);
if(ql <= mid) add(lc(p), l, mid, ql, qr, v);
if(mid < qr) add(rc(p), mid + 1, r, ql, qr, v);
push_up(p);
}
int query(int p, int l, int r, int ql, int qr) {
if(ql > qr) return -INF;
if(ql <= l && r <= qr) return mx[p];
int mid = (l + r) >> 1, res = 0; push_down(p);
if(ql <= mid) res = query(lc(p), l, mid, ql, qr);
if(mid < qr) res = max(res, query(rc(p), mid + 1, r, ql, qr));
return res;
}
}
set<int> st;
int main() {
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n + 1; i++) lds[i] = n + 1;
for(int i = n; i >= 1; i--) {
int p = lower_bound(lds + 1, lds + 1 + ld, a[i]) - lds;
olds[i] = (Range){a[i], lds[p] - 1};
lds[p] = a[i]; ld = max(ld, p);
len_d[i] = p;
}
for(int i = n; i >= 1; i--) {
int p = upper_bound(lis + 1, lis + 1 + li, a[i], [](int a, int b) { return a > b; } ) - lis;
olis[i] = (Range){lis[p] + 1, a[i]};
lis[p] = a[i]; li = max(li, p);
len_i[i] = p;
}
for(int i = 1; i <= n; i++) SegT1::add(1, 0, n, olds[i].l, olds[i].r, 1);
for(int i = 1; i <= n; i++) SegT2::add(1, 0, n, olis[i].l, olis[i].r, 1);
st.insert(0);
st.insert(n + 1);
for(int i = 1; i <= n; i++) {
int pre = *--st.lower_bound(a[i]);
int nxt = *st.upper_bound(a[i]);
st.insert(a[i]);
SegT1::add(1, 0, n, pre, nxt - 1, 1);
SegT2::add(1, 0, n, pre, nxt - 1, 1);
SegT1::add(1, 0, n, olds[i].l, olds[i].r, -1);
SegT2::add(1, 0, n, olis[i].l, olis[i].r, -1);
ans = max(ans, SegT1::query(1, 0, n, 0, pre - 1) + len_i[i]);
ans = max(ans, SegT2::query(1, 0, n, nxt, n) + len_d[i]);
}
cout << ans << endl;
return 0;
}