import java.io.*; import java.math.*; import java.security.KeyStore.Entry; import java.util.*; class SPOJANDCC { @SuppressWarnings("rawtypes") static InputReader in; static PrintWriter out; public static class SegmentTree { int n; int arr[], lazy[]; SegmentTree(int n) { this.n = n; arr = new int[n << 2]; lazy = new int[n << 2]; } SegmentTree(int a[]) { this.n = a.length; arr = new int[n << 2]; lazy = new int[n << 2]; build(0, n - 1, 0, a); } void build(int l, int r, int c, int a[]) { if (l == r) { arr[c] = a[l]; return; } int mid = l + r >> 1; build(l, mid, (c << 1) + 1, a); build(mid + 1, r, (c << 1) + 2, a); arr[c] = merge(arr[(c << 1) + 1], arr[(c << 1) + 2]); } int merge(int a, int b) { return Math.max(a, b); } int lazymerge(int a, int b) { return a + b; } boolean getInitialValue(long a) { return !(a == 0); } void check(int c, int l, int r) { if (getInitialValue(lazy[c])) { arr[c] = lazymerge(arr[c], lazy[c]); if (l != r) { lazy[(c << 1) + 1] = lazymerge(lazy[(c << 1) + 1], lazy[c]); lazy[(c << 1) + 2] = lazymerge(lazy[(c << 1) + 2], lazy[c]); } lazy[c] = 0; } } void update(int l, int r, int c, int x, int y, int val) { check(c, l, r); if (l > r || x > y || l > y || x > r) return; if (x <= l && y >= r) { arr[c] = lazymerge(arr[c], val); if (l != r) { lazy[(c << 1) + 1] = lazymerge(lazy[(c << 1) + 1], val); lazy[(c << 1) + 2] = lazymerge(lazy[(c << 1) + 2], val); } return; } int mid = l + r >> 1; update(l, mid, (c << 1) + 1, x, y, val); update(mid + 1, r, (c << 1) + 2, x, y, val); arr[c] = merge(arr[(c << 1) + 1], arr[(c << 1) + 2]); } void up(int x, int y, int val) { update(0, n - 1, 0, x, y, val); } int get(int l, int r, int c, int x, int y) { check(c, l, r); if (l > r || x > y || l > y || x > r) // return inverse value return 0; else if (x <= l && y >= r) return arr[c]; int mid = l + r >> 1; return merge(get(l, mid, (c << 1) + 1, x, y), get(mid + 1, r, (c << 1) + 2, x, y)); } int ans(int x, int y) { return get(0, n - 1, 0, x, y); } } static long mod = (long) 1e9 + 7; static void solve() { int n = in.ni(); int arr[] = new int[n + 1]; long max = 0; for (int i = 1; i <= n; i++) { arr[i] = in.ni(); max = Math.max(max, arr[i]); } SegmentTree t = new SegmentTree((int) (1e6 + 10)); int l[] = new int[n + 1]; int r[] = new int[n + 1]; int mx = (int) 1e6 + 5; for (int i = 1; i <= n; i++) { l[i] = t.ans(arr[i] + 1, mx); t.up(arr[i], arr[i], i); } t = new SegmentTree(mx + 5); for (int i = n; i > 0; i--) { r[i] = t.ans(arr[i], mx); if (r[i] == 0) r[i] = n + 1; t.up(arr[i], arr[i], i); } long ans = 0, tmp = 0; for (int i = 1; i <= n; i++) { long fg = (r[i] - l[i] - 1); fg *= (fg + 1); fg >>= 1; fg %= mod; tmp += fg; tmp %= mod; fg *= arr[i]; fg %= mod; ans += fg; } long nn = n; long var = nn * nn + nn; var %= mod; var *= ((nn * nn + nn + 2) % mod); var %= mod; var *= 125000001; var %= mod; var = (var - tmp + mod) % mod; ans += max * var; ans %= mod; out.println(ans); } @SuppressWarnings("rawtypes") static void soln() { in = new InputReader(System.in); out = new PrintWriter(System.out); solve(); out.flush(); } static void debug(Object... o) { System.out.println(Arrays.deepToString(o)); } public static void main(String[] args) { new Thread(null, new Runnable() { public void run() { try { soln(); } catch (Exception e) { e.printStackTrace(); } } }, "1", 1 << 26).start(); } static class InputReader { private final InputStream stream; private final byte[] buf = new byte[8192]; private int curChar, snumChars; private SpaceCharFilter filter; public InputReader(InputStream stream) { this.stream = stream; } public int snext() { if (snumChars == -1) throw new InputMismatchException(); if (curChar >= snumChars) { curChar = 0; try { snumChars = stream.read(buf); } catch (IOException e) { throw new InputMismatchException(); } if (snumChars <= 0) return -1; } return buf[curChar++]; } public int ni() { int c = snext(); while (isSpaceChar(c)) { c = snext(); } int sgn = 1; if (c == '-') { sgn = -1; c = snext(); } int res = 0; do { if (c < '0' || c > '9') throw new InputMismatchException(); res *= 10; res += c - '0'; c = snext(); } while (!isSpaceChar(c)); return res * sgn; } public long nl() { int c = snext(); while (isSpaceChar(c)) { c = snext(); } int sgn = 1; if (c == '-') { sgn = -1; c = snext(); } long res = 0; do { if (c < '0' || c > '9') throw new InputMismatchException(); res *= 10; res += c - '0'; c = snext(); } while (!isSpaceChar(c)); return res * sgn; } public int[] nextIntArray(int n) { int a[] = new int[n]; for (int i = 0; i < n; i++) { a[i] = ni(); } return a; } public long[] nextLongArray(int n) { long a[] = new long[n]; for (int i = 0; i < n; i++) { a[i] = nl(); } return a; } public String readString() { int c = snext(); while (isSpaceChar(c)) { c = snext(); } StringBuilder res = new StringBuilder(); do { res.appendCodePoint(c); c = snext(); } while (!isSpaceChar(c)); return res.toString(); } public String nextLine() { int c = snext(); while (isSpaceChar(c)) c = snext(); StringBuilder res = new StringBuilder(); do { res.appendCodePoint(c); c = snext(); } while (!isEndOfLine(c)); return res.toString(); } public boolean isSpaceChar(int c) { if (filter != null) return filter.isSpaceChar(c); return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; } private boolean isEndOfLine(int c) { return c == '\n' || c == '\r' || c == -1; } public interface SpaceCharFilter { public boolean isSpaceChar(int ch); } } }