#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const long long Inf = 1e18;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
int gi() {
  int x = 0, o = 1;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  if (ch == '-') o = -1, ch = getchar();
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  return x * o;
}
template <typename T>
bool chkmax(T &a, T b) {
  return a < b ? a = b, 1 : 0;
};
template <typename T>
bool chkmin(T &a, T b) {
  return a > b ? a = b, 1 : 0;
};
int add(int a, int b) { return a + b >= mod ? a + b - mod : a + b; }
int sub(int a, int b) { return a - b < 0 ? a - b + mod : a - b; }
void inc(int &a, int b) { a = (a + b >= mod ? a + b - mod : a + b); }
void dec(int &a, int b) { a = (a - b < 0 ? a - b + mod : a - b); }
int n, a[N], pre[N], nxt[N];
map<int, int> pos;
stack<pair<int, int> > sa, sb;
struct node {
  int sa = 0, sb = 0, ta = 0, tb = 0, ans = 0;
  void modify(int l, int r, int aa, int ab) {
    inc(ans, 1ll * aa * sb % mod);
    inc(ans, 1ll * sa * ab % mod);
    inc(ans, 1ll * aa * ab % mod * (r - l + 1) % mod);
    inc(sa, 1ll * (r - l + 1) * aa % mod);
    inc(sb, 1ll * (r - l + 1) * ab % mod);
    inc(ta, aa), inc(tb, ab);
  }
} tr[N << 2];
void down(int o, int l, int r) {
  if (!tr[o].ta && !tr[o].tb) return;
  int mid = (l + r) >> 1;
  tr[(o << 1)].modify(l, mid, tr[o].ta, tr[o].tb);
  tr[(o << 1 | 1)].modify(mid + 1, r, tr[o].ta, tr[o].tb);
  tr[o].ta = tr[o].tb = 0;
}
node merge(node a, node b) {
  node ret;
  ret.sa = add(a.sa, b.sa);
  ret.sb = add(a.sb, b.sb);
  ret.ans = add(a.ans, b.ans);
  return ret;
}
void up(int o) { tr[o] = merge(tr[(o << 1)], tr[(o << 1 | 1)]); }
void modify(int o, int l, int r, int L, int R, int aa, int ab) {
  if (L <= l && r <= R) return tr[o].modify(l, r, aa, ab);
  down(o, l, r);
  int mid = (l + r) >> 1;
  if (L <= mid) modify((o << 1), l, mid, L, R, aa, ab);
  if (R > mid) modify((o << 1 | 1), mid + 1, r, L, R, aa, ab);
  up(o);
}
node query(int o, int l, int r, int L, int R) {
  if (L <= l && r <= R) return tr[o];
  down(o, l, r);
  int mid = (l + r) >> 1;
  node ret;
  if (L <= mid) ret = merge(ret, query((o << 1), l, mid, L, R));
  if (R > mid) ret = merge(ret, query((o << 1 | 1), mid + 1, r, L, R));
  return ret;
}
void modify(int l, int r, int aa, int ab) {
  if (l <= r) modify(1, 1, n, l, r, aa, ab);
}
int query(int l, int r) {
  if (l <= r) return query(1, 1, n, l, r).ans;
  return 0;
}
void build(int o, int l, int r) {
  if (l == r) {
    tr[o].sa = l - 1;
    return;
  }
  int mid = (l + r) >> 1;
  build((o << 1), l, mid), build((o << 1 | 1), mid + 1, r);
}
int main() {
  n = gi();
  for (int i = 1; i <= n; i++) a[i] = gi();
  for (int i = 1; i <= n; i++) pre[i] = pos[a[i]], pos[a[i]] = i;
  for (int i = 1; i <= n; i++) pos[a[i]] = n + 1;
  for (int i = n; i; i--) nxt[i] = pos[a[i]], pos[a[i]] = i;
  build(1, 1, n);
  int ans = 0, lb = 0;
  for (int i = 1; i <= n; i++) {
    chkmax(lb, pre[i] + 1);
    int now = i;
    while (!sa.empty() && sa.top().second <= pre[i])
      modify(sa.top().first, now - 1, sa.top().second, 0), now = sa.top().first,
                                                           sa.pop();
    modify(now, i, sub(0, pre[i]), 0), sa.push(make_pair(now, pre[i]));
    now = i;
    while (!sb.empty() && sb.top().second >= nxt[i])
      modify(sb.top().first, now - 1, 0, sub(0, sb.top().second)),
          now = sb.top().first, sb.pop();
    modify(now, i, 0, nxt[i]), sb.push(make_pair(now, nxt[i]));
    modify(lb, i, 0, sub(0, i + 1)), inc(ans, query(lb, i)),
        modify(lb, i, 0, i + 1);
  }
  printf("%d\n", ans);
  return 0;
}
