import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { static class Max implements Comparable { int max; int index; Max(int max, int index) { this.max = max; this.index = index; } @Override public int compareTo(Max other) { return other.max - max; } } static class RollingMax extends LinkedList { int k; RollingMax(int k) { this.k = k; } int maybeOffer(int value, int index) { Max m = new Max(value, index); if (isEmpty()) { addLast(m); return value; } else { if (peekFirst().index < index - k) { pollFirst(); } while (!isEmpty() && peekLast().max < value) { pollLast(); } addLast(m); return peekFirst().max; } } } static int MOD = 1000000007; static Integer[] max(Integer[] A) { // use a heap to track the max, with its index. LinkedList res = new LinkedList<>(); for (int k = 0; k < A.length; k++) { RollingMax rm = new RollingMax(k); for (int i = 0; i < A.length; i++) { if (i >= k) { int addingMax = rm.maybeOffer(A[i], i); res.add(addingMax); } else { rm.maybeOffer(A[i], i); } } } Integer[] result = new Integer[res.size()]; res.toArray(result); return result; } static int solve(Integer[] A) { int total = 0; Integer[] maxes = max(A); // use a heap to track the max, with its index. for (int k = 0; k < maxes.length; k++) { RollingMax rm = new RollingMax(k); for (int i = 0; i < maxes.length; i++) { if (i >= k) { total += rm.maybeOffer(maxes[i], i) % MOD; } else { rm.maybeOffer(maxes[i], i); } } } return total % MOD; } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); Integer[] a = new Integer[n]; for(int a_i = 0; a_i < n; a_i++){ a[a_i] = in.nextInt(); } int result = solve(a); System.out.println(result); in.close(); } }