#include <fstream>
#include <cmath>
#include <vector>
#include <string>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <bitset>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <set>
#include <complex>

using namespace std;

const int SIZE = 1 << 10;

int pointer = SIZE;
char buffer[SIZE];

char Advance() {
    if (pointer == SIZE) {
        fread(buffer, 1, SIZE, stdin);
        pointer = 0;
    }
    return buffer[pointer++];
}

int Read() {
    int answer = 0;
    char ch = Advance();
    while (!isdigit(ch))
        ch = Advance();
    while (isdigit(ch)) {
        answer = answer * 10 + ch - '0';
        ch = Advance();
    }
    return answer;
}

const int MAXN = 200000;
const int MAXNODES = 524288;
const int MOD = 1000000007;

void Add(int &x, int y) {
    x += y;
    if (x >= MOD)
        x -= MOD;
}

void Subtract(int &x, int y) {
    x -= y;
    if (x < 0)
        x += MOD;
}

int RaiseToPower(int base, int power) {
    int answer = 1;
    while (power) {
        if (power % 2)
            answer = (1LL * answer * base) % MOD;
        base = (1LL * base * base) % MOD;
        power /= 2;
    }
    return answer;
}

int v[1 + MAXN];
pair<int, int> vn[1 + MAXN];
vector<int> here[1 + MAXN];
int n, tree[1 + MAXNODES], value[1 + MAXN], answer = 0;

void Normalize(int &m) {
    for (int i = 1; i <= n; i++)
        vn[i] = make_pair(v[i], i);
    sort(vn + 1, vn + n + 1);
    m = 0;
    for (int i = 1; i <= n; i++) {
        if (vn[i].first != vn[i - 1].first) {
            m++;
            value[m] = vn[i].first;
        }
        v[vn[i].second] = m;
        here[m].push_back(vn[i].second);
    }
}

void BuildTree(int node, int left, int right) {
    if (left == right) {
        tree[node] = v[left];
        return;
    }
    int middle = (left + right) / 2;
    BuildTree(2 * node, left, middle);
    BuildTree(2 * node + 1, middle + 1, right);
    tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}

int Query(int node, int left, int right, int from, int to) {
    if (from <= left && right <= to)
        return tree[node];
    int middle = (left + right) / 2, answer = 0;
    if (from <= middle)
        answer = max(answer, Query(2 * node, left, middle, from, to));
    if (middle + 1 <= to)
        answer = max(answer, Query(2 * node + 1, middle + 1, right, from, to));
    return answer;
}

int BinarySearch(int x, int limit) {
    int left = 0, right = here[x].size() - 1, best = here[x].size();
    while (left <= right) {
        int middle = (left + right) / 2;
        if (here[x][middle] >= limit) {
            best = middle;
            right = middle - 1;
        }
        else
            left = middle + 1;
    }
    return best;
}

int Normal(int left, int right) {
    int l = right - left + 1, x = Query(1, 1, n, left, right), a = BinarySearch(x, left), b = BinarySearch(x, right + 1) - 1;
    int total = (1LL * l * (l + 1) * (l + 2) / 6) % MOD;
    if (b - a + 1 == right - left + 1)
        answer = (1LL * total * value[x]+ answer) % MOD;
    else {
        int now = total;
        if (here[x][a] != left)
            Subtract(now, Normal(left, here[x][a] - 1));
        for (int i = a; i < b; i++)
            if (here[x][i] <= here[x][i + 1] - 2)
                Subtract(now, Normal(here[x][i] + 1, here[x][i + 1] - 1));
        if (here[x][b] != right)
            Subtract(now, Normal(here[x][b] + 1, right));
        answer = (1LL * now * value[x] + answer) % MOD;
    }
    return total;
}

int Special(int left, int right) {
    int x = max(Query(1, 1, n, 1, left), Query(1, 1, n, right, n)), l2 = left, l1 = n - right + 1, k = min(l2 - 1, l1);
    int a = BinarySearch(x, left + 1) - 1, b = BinarySearch(x, right);
    int total = (1LL * l1 * (l1 + 1) * (l1 + 2) / 6 + 1LL * l2 * (l2 + 1) * (l2 + 2) / 6) % MOD;
    total = (1LL * k * l1 * l2 + total) % MOD;
    Subtract(total, (1LL * k * (k + 1) * l1 / 2) % MOD);
    Subtract(total, (1LL * (k - 1) * k * l2 / 2) % MOD);
    total = (1LL * (k - 1) * k * (k + 1) / 3 + total) % MOD;
    if (a + 1 + here[x].size() - b == l1 + l2)
        answer = (1LL * total * value[x] + answer) % MOD;
    else {
        int now = total;
        if (a == -1) {
            if (here[x].back() == n)
                Subtract(now, Normal(1, left));
            else
                Subtract(now, Special(left, here[x].back() + 1));
            if (here[x][b] != right)
                Subtract(now, Normal(right, here[x][b] - 1));
            for (int i = b; i < here[x].size() - 1; i++)
                if (here[x][i] <= here[x][i + 1] - 2)
                    Subtract(now, Normal(here[x][i] + 1, here[x][i + 1] - 1));
        }
        else
            if (b == here[x].size()) {
                if (here[x][0] == 1)
                    Subtract(now, Normal(right, n));
                else
                    Subtract(now, Special(here[x][0] - 1, right));
                if (here[x][a] != left)
                    Subtract(now, Normal(here[x][a] + 1, left));
                for (int i = 0; i < a; i++)
                    if (here[x][i] <= here[x][i + 1] - 2)
                        Subtract(now, Normal(here[x][i] + 1, here[x][i + 1] - 1));
            }
            else {
                if (here[x][0] != 1 && here[x].back() != n)
                    Subtract(now, Special(here[x][0] - 1, here[x].back() + 1));
                else {
                    if (here[x][0] != 1)
                        Subtract(now, Normal(1, here[x][0] - 1));
                    if (here[x].back() != n)
                        Subtract(now, Normal(here[x].back() + 1, n));
                }
                if (here[x][a] != left)
                    Subtract(now, Normal(here[x][a] + 1, left));
                for (int i = 0; i < a; i++)
                    if (here[x][i] <= here[x][i + 1] - 2)
                        Subtract(now, Normal(here[x][i] + 1, here[x][i + 1] - 1));
                if (here[x][b] != right)
                    Subtract(now, Normal(right, here[x][b] - 1));
                for (int i = b; i < here[x].size() - 1; i++)
                    if (here[x][i] <= here[x][i + 1] - 2)
                        Subtract(now, Normal(here[x][i] + 1, here[x][i + 1] - 1));
            }
        answer = (1LL * now * value[x] + answer) % MOD;
    }
    return total;
}

int main() {
    //freopen("tema.in", "r", stdin);
    //freopen("tema.out", "w", stdout);
    scanf("%d", &n);
    int m;
    for (int i = 1; i <= n; i++)
        scanf("%d", &v[i]);
    Normalize(m);
    BuildTree(1, 1, n);
    int total = (1LL * n * (n + 1) / 2) % MOD;
    total = (1LL * total * (total + 1) / 2) % MOD;
    for (int i = 0; i < here[m].size() - 1; i++)
        if (here[m][i] <=  here[m][i + 1] - 2)
            Subtract(total, Normal(here[m][i] + 1, here[m][i + 1] - 1));
    if (here[m][0] != 1 && here[m].back() != n)
        Subtract(total, Special(here[m][0] - 1, here[m].back() + 1));
    else {
        if (here[m][0] != 1)
            Subtract(total, Normal(1, here[m][0] - 1));
        if (here[m].back() != n)
            Subtract(total, Normal(here[m].back() + 1, n));
    }
    answer = (1LL * total * value[m] + answer) % MOD;
    printf("%d\n", answer);
    return 0;
}