#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <stack>
#include <ctime>
#include <unordered_map>
#include <unordered_set>
#include <list>
#pragma comment (linker, "/STACK:256000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

using namespace std;

vector < int > merge(vector < int > a, vector < int > b) {
    for (int i = 0; i < b.size(); ++i) {
        a.push_back(b[i]);
    }
    sort(a.begin(), a.end());
    a.resize(unique(a.begin(), a.end()) - a.begin());
    return a;
}

vector < vector < int > > step(vector < vector < int > > a) {
    vector < vector < int > > res;
    for (int len = 1; len <= a.size(); ++len) {
        for (int i = 0; i + len - 1 < a.size(); ++i) {
            vector < int > cur;
            for (int j = i; j < i + len; ++j) {
                cur = merge(cur, a[j]);
            }
            res.push_back(cur);
        }
    }
    return res;
}

const long long P = 1000000007;
const int maxN = 210000;

int n;
int a[maxN];

void computeFirst(long long &ans, long long &total, int n) {
    set < pair < int, long long > > c, d;
    c.insert(make_pair(a[n - 1], 1));
    long long sc = a[n - 1];
    d.insert(make_pair(a[n - 1], 1));
    long long sd = a[n - 1];

    int oldtotal = total;
    int oldans = ans;

    total = (total + 1) % P;
    ans = (ans + a[n - 1]) % P;
    long long s = 1;

    int shift = 0;
    for (int i = n - 2; i >= 1; --i) {
        ++shift;
        s += (shift + 1);
        s %= P;
        total = (total + s) % P;
        {
            long long cnt = 0;
            while (!d.empty() && d.begin()->first <= a[i]) {
                cnt = (cnt + d.begin()->second) % P;
                sd -= (long long)(d.begin()->first) * d.begin()->second;
                sd %= P;
                d.erase(d.begin());
            }
            cnt = (cnt + 1 - shift) % P;
            d.insert(make_pair(a[i], cnt));
            sd += cnt * (long long)(a[i]);
            sd %= P;
        }
        {
            long long cnt = 0;
            while (!c.empty() && c.begin()->first <= a[i]) {
                cnt = (cnt + c.begin()->second) % P;
                sc -= (long long)(c.begin()->first) * c.begin()->second;
                sc %= P;
                c.erase(c.begin());
            }
            cnt = (cnt + 1) % P;
            c.insert(make_pair(a[i], cnt));
            sc += cnt * (long long)(a[i]);
            sc %= P;
        }
        ans = (ans + sd + (long long)(shift) * sc) % P;
    }
}

void computeSecond(long long &ans, long long &total, int n) {
    vector < int > buf;
    int res = 0;
    int value = 0;
    for (int i = 0; i + 1 < n; ++i) {
        //buf.push_back(i);
        value = max(value, a[i]);
        ++res;
        //M[buf] = res;
        ans = (ans + (long long)(value) * (long long)(res)) % P;
        total = (total + res) % P;
    }
}

void output(multiset < pair < int, long long > > s) {
    cout << "====" << endl;
    while (!s.empty()) {
        cout << s.begin()->first << ": " << s.begin()->second << endl;
        s.erase(s.begin());
    }
    cout << "----" << endl;
}

void prepare(multiset < pair < int, long long > > s) {
    while (!s.empty()) {
        if (s.begin()->second == 0) {
            s.erase(s.begin());
        } else {
            break;
        }
    }
}

void computeThird(long long &ans, long long &total, int n) {
    if (n < 4) {
        return;
    }
    int oldans = ans;
    int oldtotal = total;

    /*for (int missing = n - 2; missing > 1; --missing) {
        int value = 0;
        for (int i = 0; i < missing; ++i) {
            value = max(value, a[i]);
        }
        int res = 0;
        for (int i = n - 1; i > missing; --i) {
            value = max(value, a[i]);
            ++res;
            int cnt = min(missing - 1, res);
            if (cnt > 0) {
                ans = (ans + (long long)(value) * (long long)(cnt)) % P;
                total = (total + cnt) % P;
            }
        }
    }*/

    

    int gmax = 0;
    for (int i = 0; i < n; ++i) {
        gmax = max(gmax, a[i]);
    }

    multiset < pair < int, long long > > b, c, d;
    long long sd = 0, sc = 0, sb = 0;
    long long td = 0, tc = 0, tb = 0;

    int value = max(a[0], a[1]);
    int cnt = 0;
    for (int i = n - 1; i > 2; --i) {
        value = max(value, a[i]);
        d.insert(make_pair(value, 1));
        sd = (sd + value) % P;
        total = (total + 1) % P;

        td = (td + 1) % P;

        ++cnt;
        c.insert(make_pair(value, cnt));
        sc = (sc + (long long)(value) * (long long)(cnt)) % P;
        tc = (tc + cnt) % P;

        if (cnt - 1 > 0) {
            b.insert(make_pair(value, cnt - 1));
            sb = (sb + (long long)(value) * (long long)(cnt - 1)) % P;
            tb = (tb + cnt - 1) % P;
        }
    }
    ans = (ans + sd) % P;

    int tvalue = max(a[n - 1], a[0]);
    tvalue = max(a[0], a[1]);

    int bound = n - 2;
    long long cbound = -1;
    for (int missing = 3; missing <= n - 2; ++missing) {
        tvalue = max(tvalue, a[missing - 1]);
        --bound;
        ++cbound;
        //output(d);
        //cerr << sc << " " << sb << " " << sd << endl;
        //cerr << tc << " " << tb << " " << td << endl;
        {
            long long cnt = 0;
            while (!d.empty() && d.begin()->first <= a[missing - 1]) {
                cnt = (cnt + d.begin()->second);
                sd -= (long long)(d.begin()->first) * d.begin()->second;
                sd %= P;
                d.erase(d.begin());
            }
            if (cnt > 0) {
                d.insert(make_pair(a[missing - 1], cnt));
                sd += (cnt % P) * (long long)(a[missing - 1]);
                sd %= P;
            }
        }
        if (!d.empty()) {
            pair < int, long long > p = *d.rbegin();
            d.erase(d.find(p));
            if (p.second > 1) {
                d.insert(make_pair(p.first, p.second - 1));
            }
            sd -= p.first;
            sd %= P;
            td = (td - 1) % P;

            if (!d.empty()) {
                p = *d.begin();
                d.erase(d.begin());
                if (p.second > 1) {
                    d.insert(make_pair(p.first, p.second - 1));
                }
                sd -= p.first;
                sd %= P;
                td = (td - 1) % P;
            }
        }
        {
            long long cnt = 0;
            while (!c.empty() && c.begin()->first <= a[missing - 1]) {
                cnt = (cnt + c.begin()->second);
                sc -= (long long)(c.begin()->first) * c.begin()->second;
                sc %= P;
                c.erase(c.begin());
            }
            if (cnt > 0) {
                c.insert(make_pair(a[missing - 1], cnt));
                sc += (cnt % P) * (long long)(a[missing - 1]);
                sc %= P;
            }
        }
        if (!c.empty()) {
            pair < int, long long > p = *c.rbegin();
            //cerr << "x: " << p.first << " " << p.second << " " << bound << endl;
            c.erase(c.find(p));
            if (p.second > bound) {
                c.insert(make_pair(p.first, p.second - bound));
            }
            sc -= (long long)(p.first) * (long long)(bound);
            sc %= P;
            tc = (tc - bound) % P;
        }

        {
            long long cnt = 0;
            while (!b.empty() && b.begin()->first <= a[missing - 1]) {
                cnt = (cnt + b.begin()->second);
                sb -= (long long)(b.begin()->first) * b.begin()->second;
                sb %= P;
                b.erase(b.begin());
            }
            if (cnt > 0) {
                b.insert(make_pair(a[missing - 1], cnt));
                sb += (cnt % P) * (long long)(a[missing - 1]);
                sb %= P;
            }
        }
        if (!b.empty()) {
            pair < int, long long > p = *b.rbegin();
            b.erase(b.find(p));
            //cerr << "b: " << p.first << " " << p.second << " " << bound - 1 << endl;
            if (p.second > bound - 1) {
                b.insert(make_pair(p.first, p.second + 1 - bound));
            }
            sb -= (long long)(p.first) * (long long)(bound - 1);
            sb %= P;
            tb = (tb - bound + 1) % P;
            tb %= P;

            if (!b.empty() && cbound > 0) {
                p = *b.begin();
                b.erase(b.begin());
                if (p.second > cbound) {
                    b.insert(make_pair(p.first, p.second - cbound));
                }
                sb -= (long long)(p.first) * (long long)(cbound);
                sb %= P;
                tb = (tb - cbound) % P;
            }
        }

        //prepare(c);
        //prepare(b);
        //prepare(d);

        //output(c);
        //output(b);
        //output(d);

        //cerr << sc << " " << sb << " " << sd << endl;
        //cerr << tc << " " << tb << " " << td << endl;

        //cerr << tc - tb + (cbound + 1) * td << endl;

        ans = (ans + sc - sb + (cbound + 1) * sd) % P;
        total = (total + tc - tb + (cbound + 1) * td) % P;
    }
    //cerr << "o: " << ans - oldans << " " << total - oldtotal << endl;
}

void generate(long long &ans, int n) {
    long long total = 0;
    computeFirst(ans, total, n);
    computeSecond(ans, total, n);
    computeThird(ans, total, n);

    long long x = (long long)(n) * (long long)(n + 1) / 2LL;
    x %= P;
    x = (x * (x + 1)) % P;
    x = (x * (P + 1)) / 2LL;
    x %= P;

    int value = 0;
    for (int i = 0; i < n; ++i) {
        value = max(value, a[i]);
    }
    ans = (ans + (long long)(value) * (long long)(x - total)) % P;
    ans = (ans + P) % P;
}

long long trivial() {
    vector < int > b;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j + i - 1 < n; ++j) {
            int value = 0;
            for (int k = j; k < j + i; ++k) {
                value = max(value, a[k]);
            }
            b.push_back(value);
        }
    }
    int n = b.size();
    int res = 0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j + i - 1 < n; ++j) {
            int value = 0;
            for (int k = j; k < j + i; ++k) {
                value = max(value, b[k]);
            }
            res += value;
            res %= P;
        }
    }
    return res;
}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    /*while (true) {
        n = 20;
        for (int i = 0; i < n; ++i) {
            a[i] = rand() % 10 + 1;
        }
        long long res = 0;
        generate(res, n);
        if (trivial() != res) {
            cerr << "bad" << endl;
            cerr << res << endl;
            cerr << trivial() << endl;
            cerr << n << endl;
            for (int i = 0; i < n; ++i) {
                cerr << a[i] << " ";
            }
            cerr << endl;
            return 0;
        }
        cerr << "test" << endl;
    }*/

    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }

    long long res = 0;
    generate(res, n);

    cout << res << endl;
    //cout << trivial() << endl;
    /*vector < vector < int > > a;
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        a.push_back(vector < int > (1, i));
    }
    a = step(a);
    a = step(a);
    
    map < vector < int >, int > cnt;
    for (int i = 0; i < a.size(); ++i) {
        ++cnt[a[i]];
    }
    map < vector < int >, int > A = generate(n);
    int tot = 0;
    for (map < vector < int >, int > ::iterator it = cnt.begin(); it != cnt.end(); ++it) {
        tot += it->second;
        if (A[it->first] != it->second) {
             for (int i = 0; i < it->first.size(); ++i) {
                cout << it->first[i] << ",";
            }
            cout << ": " << it->second << " " << A[it->first] << endl;
        }
        A.erase(it->first);
    }
    int m = n * (n + 1) / 2;
    m = m * (m + 1) / 2;
    cerr << "tot:" << tot << " " << m << endl;
    cerr << "remained: " << A.size() << endl;
    for (map < vector < int >, int > ::iterator it = A.begin(); it != A.end(); ++it) {
        for (int i = 0; i < it->first.size(); ++i) {
            cout << it->first[i] << ",";
        }
        cout << ": " << it->second << " " << cnt[it->first] << endl;
    }*/

    return 0;
}