#include <bits/stdc++.h>   using namespace std;   const int MOD = (int)1e9 + 7;   const int MAXN = (int)3e5 + 3;   const int infint = (int)1e9 + 3;   const long long inf = (long long)2e18;   struct node {     int minf, tedf, mimm, tmimm, mipm, tmipm, min, max, lazymax, lazymin;     node() {       minf = infint, tedf = 0;       mimm = infint, tmimm = 0;       mipm = infint, tmipm = 0;       min = infint, max = -infint;       lazymax = -1, lazymin = -1;     }   } seg[4 * MAXN];   void updmax(int node, int st, int en, int x) {     seg[node].max = x;     seg[node].mipm = st + seg[node].max, seg[node].tmipm = 1;     seg[node].minf = seg[node].mimm + seg[node].max,     seg[node].tedf = seg[node].tmimm;     seg[node].lazymax = x;     return;   }   void updmin(int node, int st, int en, int x) {     seg[node].min = x;     seg[node].mimm = st - seg[node].min, seg[node].tmimm = 1;     seg[node].minf = seg[node].mipm - seg[node].min,     seg[node].tedf = seg[node].tmipm;     seg[node].lazymin = x;   }   void shift(int node, int st, int en) {     int mid = (st + en) >> 1;     if (seg[node].lazymax != -1)       updmax(node << 1, st, mid, seg[node].lazymax),           updmax(node << 1 | 1, mid, en, seg[node].lazymax);     if (seg[node].lazymin != -1)       updmin(node << 1, st, mid, seg[node].lazymin),           updmin(node << 1 | 1, mid, en, seg[node].lazymin);     seg[node].lazymax = seg[node].lazymin = -1;   }   node merge(node a, node b) {     node c;     c.min = min(a.min, b.min);     c.max = max(a.max, b.max);     c.minf = a.minf, c.tedf = a.tedf;     if (b.minf < c.minf)       c.minf = b.minf, c.tedf = b.tedf;     else if (b.minf == c.minf)       c.tedf += b.tedf;     c.mimm = a.mimm, c.tmimm = a.tmimm;     if (b.mimm < c.mimm)       c.mimm = b.mimm, c.tmimm = b.tmimm;     else if (b.mimm == c.mimm)       c.tmimm += b.tmimm;     c.mipm = a.mipm, c.tmipm = a.tmipm;     if (b.mipm < c.mipm)       c.mipm = b.mipm, c.tmipm = b.tmipm;     else if (b.mipm == c.mipm)       c.tmipm += b.tmipm;     c.lazymax = -1, c.lazymin = -1;     return c;   }   void updatemax(int node, int st, int en, int l, int r, int x) {     if (l >= en || st >= r) return;     if (l <= st && en <= r) {       updmax(node, st, en, x);       return;     }     int mid = (st + en) >> 1;     shift(node, st, en);     updatemax(node << 1, st, mid, l, r, x);     updatemax(node << 1 | 1, mid, en, l, r, x);     seg[node] = merge(seg[node << 1], seg[node << 1 | 1]);   }   void updatemin(int node, int st, int en, int l, int r, int x) {     if (l >= en || st >= r) return;     if (l <= st && en <= r) {       updmin(node, st, en, x);       return;     }     int mid = (st + en) >> 1;     shift(node, st, en);     updatemin(node << 1, st, mid, l, r, x);     updatemin(node << 1 | 1, mid, en, l, r, x);     seg[node] = merge(seg[node << 1], seg[node << 1 | 1]);   }   node emp;   node get(int node, int st, int en, int l, int r) {     if (l >= en || st >= r) {       emp.minf = infint, emp.tedf = 0;       emp.mimm = infint, emp.tmimm = 0;       emp.mipm = infint, emp.tmipm = 0;       emp.min = infint, emp.max = -infint;       emp.lazymax = -1, emp.lazymin = -1;       return emp;     }     if (l <= st && en <= r) return seg[node];     int mid = (st + en) >> 1;     shift(node, st, en);     return merge(get(node << 1, st, mid, l, r),                  get(node << 1 | 1, mid, en, l, r));   }   int n, a[MAXN], s[MAXN], g[MAXN];   int zero[MAXN], oc[MAXN], prv[MAXN];   int main() {     ios::sync_with_stdio(false);     cin.tie(0);     cout.tie(0);     cin >> n;     for (int i = 0; i < 4 * MAXN; i++) seg[i] = node();     for (int i = 0; i < n; i++) {       cin >> a[i];       a[i]--;     }     for (int i = 0; i < n; i++)       if (a[i] == 0)         zero[i] = i;       else if (i == 0)         zero[i] = -1;       else         zero[i] = zero[i - 1];     memset(oc, -1, sizeof oc);     for (int i = 0; i < n; i++) {       prv[i] = oc[a[i]], oc[a[i]] = i;       if (i) prv[i] = max(prv[i], prv[i - 1]);     }     for (int i = 0; i < n; i++) prv[i]++;     stack<int> S;     for (int i = 0; i < n; i++) {       while (!S.empty() && a[S.top()] > a[i]) S.pop();       if (S.size())         s[i] = S.top();       else         s[i] = -1;       S.push(i);     }     while (S.size()) S.pop();     for (int i = 0; i < n; i++) {       while (!S.empty() && a[S.top()] < a[i]) S.pop();       if (S.size())         g[i] = S.top();       else         g[i] = -1;       S.push(i);     }     long long ans = 0;     for (int i = 0; i < n; i++) {       updatemin(1, 0, n, s[i] + 1, i + 1, a[i]);       updatemax(1, 0, n, g[i] + 1, i + 1, a[i]);       if (prv[i] <= zero[i]) {         node cur = get(1, 0, n, prv[i], zero[i] + 1);         if (cur.minf == i) ans += cur.tedf;       }     }     cout << ans;   }