//LIS
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <vector>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX=200005,INF=1<<30;
const int ROOT=0;
int n;
int a[MAX],c[MAX];
int dpL[MAX],dpR[MAX];
int ans,len;
void setDp(){
dpR[n-1]=1;
for(int i=n-2;i>=0;i--){
if(a[i]<a[i+1])
dpR[i]=dpR[i+1]+1;
else
dpR[i]=1;
}
dpL[0]=1;
for(int i=1;i<n;i++){
if(a[i]>a[i-1]){
dpL[i]=dpL[i-1]+1;
}
else
dpL[i]=1;
}
return ;
}
int bSearch(int x,int y,const int &val){
int mid;
while(x<y){
mid=(x+y)>>1;
if(c[mid]<val)
x=mid+1;
else
y=mid;
}
return x-1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
#endif
int T,pos;
scanf("%d",&T);
while(T--){
memset(c,0,sizeof(c));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
setDp();
ans=1;
len=1;
c[len]=a[0];
for(int i=1;i<n;i++){
pos=bSearch(1,len+1,a[i]);
if(ans<pos+dpR[i])
ans=pos+dpR[i];
if(a[i]<c[dpL[i]] || dpL[i]>len){
c[dpL[i]]=a[i];
len=max(len,dpL[i]);
}
// if (a[j]<p[f1[j]] || gs<f1[j]){
// p[f1[j]]=a[j];
// if (gs<f1[j]) gs=f1[j];
// }
}
printf("%d
",ans);
}
return 0;
}
// ,, TLE
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <map>
#include <vector>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAX=200005,INF=1<<30;
const int ROOT=0;
int n;
int a[MAX],b[MAX];
int dpL[MAX],dpR[MAX];
int cnt;
int f,result;
int ans;
struct NODE{
int b,e,val;
NODE *lson,*rson;
};
NODE node[MAX*2+5];
int bSearch(int x,int y,const int &val){
int mid;
while(x<y){
mid=(x+y)>>1;
if(b[mid]==val)
return mid;
else if(b[mid]<val)
x=mid+1;
else
y=mid;
}
return -1;
}
void unique(){
f=0; result=0;
sort(b,b+n);
while(++f!=n){
if(b[result]!=b[f]){
b[++result]=b[f];
}
}
++result;
// cout<<"LEN: "<<result<<endl;
for(int i=0;i<n;i++){
a[i]=bSearch(0,result,a[i])+1;
// cout<<"A{i}: "<<a[i]<<endl;
}
return ;
}
void setDp(){
dpR[n-1]=1;
for(int i=n-2;i>=0;i--){
if(a[i]<a[i+1])
dpR[i]=dpR[i+1]+1;
else
dpR[i]=1;
}
dpL[0]=1;
for(int i=1;i<n;i++){
if(a[i]>a[i-1]){
dpL[i]=dpL[i-1]+1;
// cout<<"ASD:"<<dpL[i]<<endl;
}
else
dpL[i]=1;
}
// for(int i=0;i<n;i++)
// cout<<dpL[i]<<" "<<dpR[i]<<endl;
return ;
}
void built(NODE *root,int l,int r){
root->b=l; root->e=r;
root->val=0;
if(l>=r)
return ;
int mid=(l+r)>>1;
root->lson=&node[++cnt];
built(root->lson,l,mid);
root->rson=&node[++cnt];
built(root->rson,mid+1,r);
return ;
}
void insert(NODE *root,int x,int val){
if(root->val<val)
root->val=val;
if(x==root->b&&root->e==x)
return ;
int mid=(root->b+root->e)>>1;
if(x<=mid)
insert(root->lson,x,val);
else
insert(root->rson,x,val);
return ;
}
int search(NODE *root,const int &l,const int &r){
if(l<=root->b&&root->e<=r)
return root->val;
int mid=(root->b+root->e)>>1,maxVal=0;
if(r<=mid)
maxVal=max(maxVal,
search(root->lson,l,r));
else if(l>=mid+1)
maxVal=max(maxVal,
search(root->rson,l,r));
else {
maxVal=max(maxVal,
search(root->lson,l,mid));
maxVal=max(maxVal,
search(root->rson,mid+1,r));
}
// if(l<=mid)
// maxVal=max(maxVal,
// search(root->lson,l,r));
// if(r>=mid+1)
// maxVal=max(maxVal,
// search(root->rson,l,r));
return maxVal;
}
void segmentTree(){
cnt=0;
built(&node[ROOT],1,result);
ans=dpR[0];
for(int i=1;i<n;i++){
insert(&node[ROOT],a[i-1],dpL[i-1]);
if(1<=a[i]-1)
ans=max(ans,
search(&node[ROOT],1,a[i]-1)+dpR[i]);
//cout<<"I: "<<i<<endl;
}
printf("%d
",ans);
return ;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
// freopen("prefix.in","r",stdin);
// freopen("prefix.out","w",stdout);
#endif
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
unique();
setDp();
segmentTree();
}
return 0;
}