#include <bits/stdc++.h>
using namespace std;

template<unsigned long long m>
struct modint {

	unsigned long long x;

	modint() : x(0) {}

	modint(long long arg) {
		arg %= m;
		if (arg < 0) {
			x = arg + m;
		} else {
			x = arg;
		}
	}

	

	modint& operator+= (const modint& other) {
		x += other.x;
		if (x >= m) {
			x -= m;
		}
		return *this;
	}

	modint& operator*= (const modint& other) {
		x = (x * other.x) % m;
		return *this;
	}

	modint& operator-= (const modint& other) {
		x += m - other.x;
		if (x >= m) {
			x -= m;
		}
		return *this;
	}

	modint operator+ (const modint& other) const {
		modint tmp = *this;
		tmp += other;
		return tmp;
	}

	modint operator- (const modint& other) const {
		modint tmp = *this;
		tmp -= other;
		return tmp;
	}

	modint operator* (const modint& other) const {
		modint tmp = *this;
		tmp *= other;
		return tmp;
	}

	explicit operator unsigned long long () const {
		return x;
	}

	modint& operator++ () {
		++x;
		if (x == m) {
			x = 0;
		}
		return *this;
	}

	modint& operator-- () {
		if (x == 0) {
			x = m-1;
		} else {
			--x;
		}
		return *this;
	}

	modint operator++ (int) {
		modint tmp = *this;
		++*this;
		return tmp;
	}

	modint operator-- (int) {
		modint tmp = *this;
		--*this;
		return tmp;
	}

	bool operator== (const modint& other) const {
		return x == other.x;
	}

	bool operator!= (const modint& other) const {
		return x != other.x;
	}

	modint operator^ (unsigned long long arg) const {
		if (arg == 0) {
			return 1;
		}
		if (arg == 1) {
			return x;
		}
		auto t = *this ^ (arg >> 1);
		t *= t;
		if (arg & 1) {
			t *= *this;
		}
		return t;
	}

	modint inv(unsigned long long exp = m - 2) const {
		return *this ^ exp;
	}
};

const unsigned long long MOD = 1'000'000'007;
typedef modint<MOD> mint;

typedef long long ll;

mint pp2(ll x) {
	if (x < 0) {
		return 0;
	}
	return mint(2).inv() * x * (x+1);
}

mint pp3(ll x) {
	if (x < 0) {
		return 0;
	}
	return mint(6).inv() * x * (x+1) * (x+2);
}

mint ex_parno(int x) {
	return mint(24).inv() * x * (x+2) * (2*x+5);
}

mint ex_neparno(int x) {
	return mint(24).inv() * (x+1) * (x+3) * (2*x+1);
}

mint ex_general(int x) {
	return x % 2 ? ex_neparno(x) : ex_parno(x);
}

mint cross_fall(int a, int b) {
	// ab + (a-1)(b-1) + ...
	if (a > b) {
		swap(a, b);
	}
	return mint(6).inv() * a * (a+1) * (3*b + 1 - a);
}

// a > b
// Sum[ (a+b-2i) * (a+b-2i+1) / 2  , {i, 0, a-1}]
mint ona_kul_formula(ll a, ll b) {
	return mint(6).inv() * b * (3*a*a + 9*a + b*b + 5);
}

// suma traje dok a ne padne na 0
mint dok_a_ne_padne_na_0(ll a, ll b) {
	if (b < 0) {
		b = 0;
	}

	if (a <= 0) {
		return 0;
	}

	if (a > b) {
		mint ret = ona_kul_formula(a, b);
		ret += pp3(a-b);
		return ret;
	} else {
		return ona_kul_formula(b, a);
	}
}

// suma traje dok oba ne padnu na 0
mint dok_ima_nesto(ll a, ll b) {
	if (a < b) {
		swap(a, b);
	}

	if (b < 0) {
		b = 0;
	}

	if (a <= 0) {
		return 0;
	}

	mint ret = ona_kul_formula(a, b);
	ret += pp3(a - b);
	return ret;
}

void asert(bool x) {
	cerr << (x ? "OK" : "FAILED") << '\n';
}

void test_dve_ruzne_formule() {
	asert(dok_a_ne_padne_na_0(1, 4).x == 15);
	asert(dok_a_ne_padne_na_0(2, 5).x == 43);
	asert(dok_a_ne_padne_na_0(3, 3).x == 34);
	asert(dok_a_ne_padne_na_0(5, 2).x == 53);

	asert(dok_ima_nesto(1, 4).x == 25);
	asert(dok_ima_nesto(2, 5).x == 53);
	asert(dok_ima_nesto(3, 3).x == 34);
	asert(dok_ima_nesto(5, 2).x == 53);
}

// p je ovo sto je zaglavljeno levo od 4
// q je ovo sto je desno od 4 a pre wrap-a
// s je ovo sto je posle wrap-a
mint pqs_solver(ll p, ll q, ll s) {
	if (s > p+q+1) {
		// dodaj sve
		mint ret = dok_a_ne_padne_na_0(p+q+1, s);
		// izbaci p
		ret -= pp3(p);
		// izbaci qs
		ret -= dok_ima_nesto(q, s);
		// nepravedno sam izbacio visak
		ret += pp3(s-(p+q+1));

		return ret;
	} else {
		mint ret = dok_a_ne_padne_na_0(p+q+1, s);
		// izbaci p
		ret -= pp3(p);
		// izbaci q-s
		ret -= dok_ima_nesto(q, s);

		return ret;
	}
}

mint pqs_solver_2(ll p, ll q, ll s) {
	if (s > p+q+2) {
		// dodaj sve
		mint ret = dok_a_ne_padne_na_0(p+q+2, s);
		// izbaci p
		ret -= pp3(p);
		// izbaci qs
		ret -= dok_ima_nesto(q, s);
		// nepravedno sam izbacio visak
		ret += pp3(s-(p+q+2));

		return ret;
	} else {
		mint ret = dok_a_ne_padne_na_0(p+q+2, s);
		// izbaci p
		ret -= pp3(p);
		// izbaci q-s
		ret -= dok_ima_nesto(q, s);

		return ret;
	}
}


vector<int> transform(vector<int> a) {
	int n = a.size();

	vector<vector<int>> d(n, vector<int>(n, 0));
	for (int i=0; i<n; i++) {
		d[i][i] = a[i];
		for (int j=i+1; j<n; j++) {
			d[i][j] = max(d[i][j-1], a[j]);
		}
	}

	vector<int> b;
	b.reserve(n*(n+1) / 2);
	for (int k=0; k<n; k++) {
		for (int i=0; i+k<n; i++) {
			int xx = d[i][i+k];
			
			b.push_back(xx);
		}
	}
	return b;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cerr.tie(nullptr);

	test_dve_ruzne_formule();

	int n;
	cin >> n;

	vector<int> a(n);
	for (int& x : a) {
		cin >> x;
	}

	vector<pair<int, int>> b;

	for (int rep=0; rep<3; rep++) {
		for (int i=0; i<n; i++) {
			b.push_back({a[i], i});
		}
	}

	vector<int> s;
	vector<int> r(3*n, 3*n), l(3*n, -1);

	// prvi desno veci ili jednak
	for (int i=0; i<3*n; i++) {
		while (s.size() && b[s.back()] <= b[i]) {
			r[s.back()] = i;
			s.pop_back();
		}
		s.push_back(i);
	}

	// isto s druge strane
	s.clear();
	for (int i=3*n-1; i>=0; i--) {
		while (s.size() && b[s.back()] < b[i]) {
			l[s.back()] = i;
			s.pop_back();
		}
		s.push_back(i);
	}

	vector<int> kl(l.begin() + n, l.begin()+2*n);
	vector<int> kr(r.begin() + n, r.begin()+2*n);

	mint sol = 0;

	for (int i=n; i<2*n; i++) {
		int l = kl[i-n];
		int r = kr[i-n];
		int bi = b[i].first;
		int slucaj = 0;

		// ni jedan ni drugi se ne overextenduju
		// ovaj slucaj je ok i proveren je
		if (l >= n && r < 2*n) {
			slucaj = 1;

			int p = i-l-1;
			int q = r-i-1;

			sol += pp3(p+q+1) * bi;
			sol -= pp3(p) * bi;
			sol -= pp3(q) * bi;
		}

		// overextend u desno ali ne u levo
		else if (l >= n && r >= 2*n) {
			slucaj = 2;
			
			int p = i-l-1;
			int q = 2*n-i-1;
			int s = r-2*n;

			//cerr << "try2 " << p << ' ' << q << ' ' << s << '\n';

			sol += pqs_solver(p, q, s-1) * bi;
		}

		// overextend u levo ali ne u desno
		else if (l < n && r < 2*n) {
			slucaj = 3;
			// sol += mint(i-(n-1)) * (r-i) * bi;

			int p = n-l-1;
			int q = i-n;
			int s = r-i-1;

			//cerr << "try3 " << p << ' ' << q << ' ' << s << '\n';

			// prvo parce
			sol += mint(q+1) * (s+1) * bi;

			if (s > 0 && q > 0) {
				sol += pqs_solver_2(s-1, q-1, p) * bi;
			} else if (s > 0 || q > 0) {
				sol += pqs_solver(max(0, s-1), max(0, q-1), p) * bi;
			}			
		}

		// lepotannn
		else {
			slucaj = 4;

			int x = i-n;
			int y = 2*n - i - 1;

			//cerr << "try4 " << x << ' ' << y << '\n';

			sol += pp2(n * (n+1ll) / 2) * bi;
			sol -= pp2(x) * bi;

			// opadajuce sume
			sol -= dok_ima_nesto(y, x-1) * bi;
		}

		//cerr << i << ' ' << slucaj << ' ' << l << ' ' << r << ' ' << sol.x << '\n';
	}

	cout << sol.x << '\n';




}