#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T& x) {
  char c = getchar();
  bool f = false;
  for (x = 0; !isdigit(c); c = getchar()) {
    if (c == '-') {
      f = true;
    }
  }
  for (; isdigit(c); c = getchar()) {
    x = x * 10 + c - '0';
  }
  if (f) {
    x = -x;
  }
}
template <typename T, typename... U>
inline void read(T& x, U&... y) {
  read(x), read(y...);
}
const int N = 1e5 + 10, INF = 2e9, P = 1e9 + 7;
int n;
int A[N], last[N], Next[N], LX[N << 2], RX[N << 2];
map<int, int> S, M;
struct Node {
  int a, l, r, ar, lr, lx, rx, num;
  Node() {}
  Node(int a, int l, int r, int ar, int lr, int lx, int rx, int num)
      : a(a), l(l), r(r), ar(ar), lr(lr), lx(lx), rx(rx), num(num) {}
} Tr[N << 2];
int ADD(int a, int b) {
  a += b;
  if (a >= P) a -= P;
  return a;
}
Node operator+(Node A, Node B) {
  return Node(ADD(A.a, B.a), ADD(A.l, B.l), ADD(A.r, B.r), ADD(A.ar, B.ar),
              ADD(A.lr, B.lr), max(A.lx, B.lx), min(A.rx, B.rx), A.num + B.num);
}
void Down(int o, bool OK, int lx, int rx) {
  if (OK) {
    Tr[o] = Tr[0];
    return;
  }
  if (lx != -INF) {
    Tr[o].lx = lx;
    Tr[o].l = 1ll * lx * Tr[o].num % P;
    Tr[o].lr = 1ll * lx * Tr[o].r % P;
    LX[o] = max(LX[o], lx);
  }
  if (rx != INF) {
    Tr[o].rx = rx;
    Tr[o].r = 1ll * rx * Tr[o].num % P;
    Tr[o].lr = 1ll * rx * Tr[o].l % P;
    Tr[o].ar = 1ll * rx * Tr[o].a % P;
    if (!RX[o])
      RX[o] = rx;
    else
      RX[o] = min(RX[o], rx);
  }
}
void Pushdown(int o) {
  if (LX[o]) {
    Down(o << 1, 0, LX[o], INF);
    Down(o << 1 | 1, 0, LX[o], INF);
    LX[o] = 0;
  }
  if (RX[o]) {
    Down(o << 1, 0, -INF, RX[o]);
    Down(o << 1 | 1, 0, -INF, RX[o]);
    RX[o] = 0;
  }
}
void New(int l, int r, int o, int pos, int lx, int rx) {
  if (l == r) {
    Tr[o] = Node(l, lx, rx, 1ll * l * rx % P, 1ll * lx * rx % P, lx, rx, 1);
    return;
  }
  Pushdown(o);
  int mid = l + r >> 1;
  if (pos <= mid)
    New(l, mid, o << 1, pos, lx, rx);
  else
    New(mid + 1, r, o << 1 | 1, pos, lx, rx);
  Tr[o] = Tr[o << 1] + Tr[o << 1 | 1];
}
void Zero(int l, int r, int o, int ql, int qr) {
  if (Tr[o].num == 0) return;
  if (ql <= l && r <= qr) return Down(o, 1, 0, 0);
  Pushdown(o);
  int mid = l + r >> 1;
  if (ql <= mid) Zero(l, mid, o << 1, ql, qr);
  if (qr > mid) Zero(mid + 1, r, o << 1 | 1, ql, qr);
  Tr[o] = Tr[o << 1] + Tr[o << 1 | 1];
}
void Modify(int l, int r, int o, int ql, int qr, int lx, int rx) {
  if (Tr[o].num == 0) return;
  if (ql <= l && r <= qr) return Down(o, 0, lx, rx);
  Pushdown(o);
  int mid = l + r >> 1;
  if (ql <= mid) Modify(l, mid, o << 1, ql, qr, lx, rx);
  if (qr > mid) Modify(mid + 1, r, o << 1 | 1, ql, qr, lx, rx);
  Tr[o] = Tr[o << 1] + Tr[o << 1 | 1];
}
int Q1(int l, int r, int o, int pos) {
  if (l == r) return Tr[o].l;
  Pushdown(o);
  int mid = l + r >> 1, t;
  if (pos <= mid)
    t = Q1(l, mid, o << 1, pos);
  else
    t = Q1(mid + 1, r, o << 1 | 1, pos);
  Tr[o] = Tr[o << 1] + Tr[o << 1 | 1];
  return t;
}
int Q2(int l, int r, int o, int pos) {
  if (l == r) return Tr[o].r;
  Pushdown(o);
  int mid = l + r >> 1, t;
  if (pos <= mid)
    t = Q2(l, mid, o << 1, pos);
  else
    t = Q2(mid + 1, r, o << 1 | 1, pos);
  Tr[o] = Tr[o << 1] + Tr[o << 1 | 1];
  return t;
}
int Get(int l, int r, int x) {
  if (l == r) return l;
  int mid = l + r >> 1;
  if (Q1(1, n, 1, mid) > x) return Get(mid + 1, r, x);
  return Get(l, mid, x);
}
int Find(int l, int r, int x) {
  if (l == r) return l;
  int mid = l + r >> 1;
  if (Q2(1, n, 1, mid) < x) return Find(mid + 1, r, x);
  return Find(l, mid, x);
}
int main() {
  read(n);
  for (int i = 1; i <= n; ++i) {
    read(A[i]);
    if (!S.count(A[i]))
      last[i] = 0;
    else
      last[i] = S[A[i]];
    S[A[i]] = i;
  }
  for (int i = n; i; --i) {
    if (!M.count(A[i]))
      Next[i] = n + 1;
    else
      Next[i] = M[A[i]];
    M[A[i]] = i;
  }
  int res = 0, now = 1;
  for (int i = 2; i < n; ++i) {
    New(1, n, 1, i, last[i] + 1, Next[i] - 1);
    if (last[i] >= now + 1) Zero(1, n, 1, now + 1, last[i]), now = last[i];
    if (i - 1 >= now + 1) {
      int p = Get(max(now + 1, last[i] + 1), i, last[i] + 1);
      if (p != i) Modify(1, n, 1, p, i - 1, last[i] + 1, INF);
      p = Find(max(now + 1, last[i] + 1), i, Next[i] - 1);
      if (p != i) Modify(1, n, 1, p, i - 1, -INF, Next[i] - 1);
    }
    res =
        ADD(res, ADD(Tr[1].ar, ADD(-1ll * Tr[1].a * i % P + P,
                                   ADD(-Tr[1].lr + P, 1ll * Tr[1].l * i % P))));
  }
  printf("%d\n", res);
  return 0;
}
