#pragma GCC optimize("Ofast,unroll-loops")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const bool DEBUG=false;
struct Return{
ll ans;
vector<int>ord[2][2][2];// prefix/suffix, 0/min, 0/max
Return(int i){
ans=1;
for(int a=0;a<8;++a)ord[a>>2][(a>>1)&1][a&1]={i};
}
Return(int initialAns,int vsize){
ans=initialAns;
for(int a=0;a<8;++a)ord[a>>2][(a>>1)&1][a&1].reserve(vsize);
}
};
int n;
vector<int>arr,disc,cnt,mergeBuf[5];
vector<int>prefOpt[2][2];
vector<array<int,2>>halfOpt;
int infected[2][2];
template<typename Func1,typename Func2>
int mergeSort(vector<int>&bufLeft,vector<int>&bufRight,Func1&&evalLeft,Func2&&evalRight){
int m=bufRight.size();
int ptrLeft=0,ptrRight=m-1;
int lstLeft=evalLeft(bufLeft[0]),lstRight=evalRight(bufRight[m-1]),lst=INT_MAX;
int h=-1;
while(true){
if(lstLeft<lstRight){
if(lst!=lstLeft)++h,lst=lstLeft;
disc[bufLeft[ptrLeft]]=h;
++ptrLeft;
if(ptrLeft<bufLeft.size())lstLeft=evalLeft(bufLeft[ptrLeft]);
else break;
}
else{
if(lst!=lstRight)++h,lst=lstRight;
disc[bufRight[ptrRight]]=h;
--ptrRight;
if(ptrRight>=0)lstRight=evalRight(bufRight[ptrRight]);
else break;
}
}
while(ptrLeft<bufLeft.size()){
lstLeft=evalLeft(bufLeft[ptrLeft]);
if(lst!=lstLeft)++h,lst=lstLeft;
disc[bufLeft[ptrLeft]]=h;
++ptrLeft;
}
while(ptrRight>=0){
lstRight=evalRight(bufRight[ptrRight]);
if(lst!=lstRight)++h,lst=lstRight;
disc[bufRight[ptrRight]]=h;
--ptrRight;
}
return h+1;
}
template<typename Func>
void mergeSort(vector<int>&bufLeft,vector<int>&bufRight,Func&&eval,vector<int>&outBuf){
if(bufLeft.empty())return outBuf.swap(bufRight);
if(bufRight.empty())return outBuf.swap(bufLeft);
int ptrLeft=0,ptrRight=0;
while(ptrLeft<bufLeft.size()&&ptrRight<bufRight.size())
outBuf.push_back(eval(bufLeft[ptrLeft])<eval(bufRight[ptrRight])?bufLeft[ptrLeft++]:bufRight[ptrRight++]);
while(ptrLeft<bufLeft.size())outBuf.push_back(bufLeft[ptrLeft++]);
while(ptrRight<bufRight.size())outBuf.push_back(bufRight[ptrRight++]);
}
using Func=int(*)(int);
static const Func eval[8]={
[](int i)->int{return arr[i]-0-0;},
[](int i)->int{return arr[i]-0-prefOpt[0][1][i];},
[](int i)->int{return arr[i]-prefOpt[0][0][i]-0;},
[](int i)->int{return arr[i]-prefOpt[0][0][i]-prefOpt[0][1][i];},
[](int i)->int{return arr[i]-0-0;},
[](int i)->int{return arr[i]-0-prefOpt[1][1][i];},
[](int i)->int{return arr[i]-prefOpt[1][0][i]-0;},
[](int i)->int{return arr[i]-prefOpt[1][0][i]-prefOpt[1][1][i];}
};
Return dnq(int l,int r){
if(r-l<=16){
Return ret(0,r-l+1);
prefOpt[0][0][l-1]=prefOpt[1][0][r+1]=inf,prefOpt[0][1][l-1]=prefOpt[1][1][r+1]=-inf;
for(int a=l;a<=r;++a)prefOpt[0][0][a]=min(prefOpt[0][0][a-1],arr[a]),prefOpt[0][1][a]=max(prefOpt[0][1][a-1],arr[a]);
for(int a=r;a>=l;--a)prefOpt[1][0][a]=min(prefOpt[1][0][a+1],arr[a]),prefOpt[1][1][a]=max(prefOpt[1][1][a+1],arr[a]);
for(int a=0;a<8;++a){
auto&v=ret.ord[a>>2][(a>>1)&1][a&1];
v.resize(r-l+1);
iota(v.begin(),v.end(),l);
sort(v.begin(),v.end(),[&](int i,int j){
return eval[a](i)<eval[a](j);
});
}
for(int a=l;a<=r;++a){
int accuMin=inf,accuMax=-inf;
for(int b=a;b<=r;++b){
accuMin=min(accuMin,arr[b]);
accuMax=max(accuMax,arr[b]);
ret.ans+=(accuMin+accuMax==arr[a]+arr[b]);
}
}
return ret;
}
int mid=(l+r)/2;
auto lres=dnq(l,mid);
auto rres=dnq(mid+1,r);
ll subAns=lres.ans+rres.ans;
for(int a=mid,accuMin=inf,accuMax=-inf;a>=l;--a)halfOpt[a]={accuMin=min(accuMin,arr[a]),accuMax=max(accuMax,arr[a])};
for(int a=mid+1,accuMin=inf,accuMax=-inf;a<=r;++a)halfOpt[a]={accuMin=min(accuMin,arr[a]),accuMax=max(accuMax,arr[a])};
{
static const Func halfEval[8]={
[](int i)->int{return arr[i]-0-0;},
[](int i)->int{return arr[i]-0-halfOpt[i][1];},
[](int i)->int{return arr[i]-halfOpt[i][0]-0;},
[](int i)->int{return arr[i]-halfOpt[i][0]-halfOpt[i][1];},
[](int i)->int{return -(arr[i]-0-0);},
[](int i)->int{return -(arr[i]-0-halfOpt[i][1]);},
[](int i)->int{return -(arr[i]-halfOpt[i][0]-0);},
[](int i)->int{return -(arr[i]-halfOpt[i][0]-halfOpt[i][1]);}
};
#pragma unroll
for(int leftMask=0;leftMask<4;++leftMask){
int rightMask=(3^leftMask);
mergeSort(lres.ord[1][leftMask>>1][leftMask&1],rres.ord[0][rightMask>>1][rightMask&1],halfEval[0|leftMask],halfEval[4|rightMask]);
fill(cnt.begin(),cnt.begin()+r-l+1,0);
int minRp=mid+1,maxRp=mid;
for(int lp=mid;lp>=l;--lp){
while(maxRp+1<=r&&(!(leftMask&2)||(halfOpt[maxRp+1][0]>=halfOpt[lp][0]))&&(!(leftMask&1)||(halfOpt[maxRp+1][1]<=halfOpt[lp][1])))++cnt[disc[++maxRp]];
while(minRp<=maxRp&&(((rightMask&2)&&(halfOpt[minRp][0]>=halfOpt[lp][0]))||((rightMask&1)&&(halfOpt[minRp][1]<=halfOpt[lp][1]))))--cnt[disc[minRp++]];
subAns+=cnt[disc[lp]];
}
}
}
Return res(subAns,r-l+1);
prefOpt[0][0][l-1]=prefOpt[1][0][r+1]=inf,prefOpt[0][1][l-1]=prefOpt[1][1][r+1]=-inf;
for(int a=l;a<=r;++a)prefOpt[0][0][a]=min(prefOpt[0][0][a-1],arr[a]),prefOpt[0][1][a]=max(prefOpt[0][1][a-1],arr[a]);
for(int a=r;a>=l;--a)prefOpt[1][0][a]=min(prefOpt[1][0][a+1],arr[a]),prefOpt[1][1][a]=max(prefOpt[1][1][a+1],arr[a]);
if(r-l+1!=n){
mergeSort(lres.ord[0][0][0],rres.ord[0][0][0],eval[0],res.ord[0][0][0]);
res.ord[1][0][0]=res.ord[0][0][0];
infected[0][0]=infected[0][1]=r+1;
infected[1][0]=infected[1][1]=l-1;
for(int mnmx:{0,1})
for(int a=mid+1;a<=r;++a)
if(prefOpt[0][mnmx][a]!=prefOpt[0][mnmx][mid]){
infected[0][mnmx]=a;
break;
}
for(int mnmx:{0,1})
for(int a=mid;a>=l;--a)
if(prefOpt[1][mnmx][a]!=prefOpt[1][mnmx][mid]){
infected[1][mnmx]=a;
break;
}
struct Range{
int lo,hi,mask;
};
//Left
#pragma unroll
for(int mn:{0,1}){
#pragma unroll
for(int mx:{0,1}){
if(!mn&&!mx)continue;
static Range ran[3];
int h=0,bufh=0;
if(infected[0][0]<=infected[0][1]){
if(mid+1<infected[0][0])ran[h++]={mid+1,infected[0][0]-1,0};
if(infected[0][0]<infected[0][1])ran[h++]={infected[0][0],infected[0][1]-1,mn<<1};
if(infected[0][1]<=r)ran[h++]={infected[0][1],r,mn<<1|mx};
}
else{
if(mid+1<infected[0][1])ran[h++]={mid+1,infected[0][1]-1,0};
if(infected[0][1]<infected[0][0])ran[h++]={infected[0][1],infected[0][0]-1,mx};
if(infected[0][0]<=r)ran[h++]={infected[0][0],r,mn<<1|mx};
}
for(int i=0;i<h;){
int j=i,lo=ran[i].lo,hi=ran[i].hi;
while(j<h&&ran[j].mask==ran[i].mask)hi=ran[j++].hi;
for(int k:rres.ord[0][(ran[i].mask>>1)&1][ran[i].mask&1])if(lo<=k&&k<=hi)mergeBuf[bufh].push_back(k);
i=j,++bufh;
}
assert(!mergeBuf[0].empty());
if(lres.ord[0][mn][mx].size()>mergeBuf[1].size()+mergeBuf[2].size()){
mergeSort(mergeBuf[1],mergeBuf[2],eval[0|mn<<1|mx],mergeBuf[3]);
mergeSort(mergeBuf[0],mergeBuf[3],eval[0|mn<<1|mx],mergeBuf[4]);
mergeSort(lres.ord[0][mn][mx],mergeBuf[4],eval[0|mn<<1|mx],res.ord[0][mn][mx]);
}
else{
mergeSort(lres.ord[0][mn][mx],mergeBuf[0],eval[0|mn<<1|mx],mergeBuf[3]);
mergeSort(mergeBuf[1],mergeBuf[2],eval[0|mn<<1|mx],mergeBuf[4]);
mergeSort(mergeBuf[3],mergeBuf[4],eval[0|mn<<1|mx],res.ord[0][mn][mx]);
}
for(int x=0;x<5;++x)mergeBuf[x].clear();
}
}
//Right
#pragma unroll
for(int mn:{0,1}){
#pragma unroll
for(int mx:{0,1}){
if(!mn&&!mx)continue;
static Range ran[3];
int h=0,bufh=0;
if(infected[1][0]>=infected[1][1]){
if(mid>infected[1][0])ran[h++]={infected[1][0]+1,mid,0};
if(infected[1][1]<infected[1][0])ran[h++]={infected[1][1]+1,infected[1][0],mn<<1};
if(l<=infected[1][1])ran[h++]={l,infected[1][1],mn<<1|mx};
}
else{
if(mid>infected[1][1])ran[h++]={infected[1][1]+1,mid,0};
if(infected[1][0]<infected[1][1])ran[h++]={infected[1][0]+1,infected[1][1],mx};
if(l<=infected[1][0])ran[h++]={l,infected[1][0],mn<<1|mx};
}
for(int i=0;i<h;){
int j=i,lo=ran[i].lo,hi=ran[i].hi;
while(j<h&&ran[j].mask==ran[i].mask)lo=ran[j++].lo;
for(int k:lres.ord[1][(ran[i].mask>>1)&1][ran[i].mask&1])if(lo<=k&&k<=hi)mergeBuf[bufh].push_back(k);
i=j,++bufh;
}
if(rres.ord[1][mn][mx].size()>mergeBuf[1].size()+mergeBuf[2].size()){
mergeSort(mergeBuf[1],mergeBuf[2],eval[4|mn<<1|mx],mergeBuf[3]);
mergeSort(mergeBuf[0],mergeBuf[3],eval[4|mn<<1|mx],mergeBuf[4]);
mergeSort(rres.ord[1][mn][mx],mergeBuf[4],eval[4|mn<<1|mx],res.ord[1][mn][mx]);
}
else{
mergeSort(rres.ord[1][mn][mx],mergeBuf[0],eval[4|mn<<1|mx],mergeBuf[3]);
mergeSort(mergeBuf[1],mergeBuf[2],eval[4|mn<<1|mx],mergeBuf[4]);
mergeSort(mergeBuf[3],mergeBuf[4],eval[4|mn<<1|mx],res.ord[1][mn][mx]);
}
for(int x=0;x<5;++x)mergeBuf[x].clear();
}
}
}
return res;
}
signed main(){
iostream::sync_with_stdio(false);
cin.tie(NULL);
cin>>n;
arr.resize(n+2),halfOpt.resize(n+2);
for(int i=0;i<5;++i)mergeBuf[i].reserve(n);
for(auto i:{&disc,&cnt,&prefOpt[0][0],&prefOpt[0][1],&prefOpt[1][0],&prefOpt[1][1]})i->resize(n+2);
for(int a=1;a<=n;++a)cin>>arr[a];
cout<<dnq(1,n).ans<<endl;
}