#include <bits/stdc++.h>
using namespace std;
using vint = vector<long long>;
using pint = pair<long long, long long>;
using vpint = vector<pint>;
template <typename A, typename B>
inline void chmin(A &a, B b) {
  if (a > b) a = b;
}
template <typename A, typename B>
inline void chmax(A &a, B b) {
  if (a < b) a = b;
}
template <class A, class B>
ostream &operator<<(ostream &ost, const pair<A, B> &p) {
  ost << "{" << p.first << "," << p.second << "}";
  return ost;
}
template <class T>
ostream &operator<<(ostream &ost, const vector<T> &v) {
  ost << "{";
  for (long long i = 0; i < v.size(); i++) {
    if (i) ost << ",";
    ost << v[i];
  }
  ost << "}";
  return ost;
}
template <uint32_t mod>
struct ModInt {
  uint32_t a;
  ModInt &s(uint32_t vv) {
    a = vv < mod ? vv : vv - mod;
    return *this;
  }
  ModInt(int64_t x = 0) { s(x % mod + mod); }
  ModInt &operator+=(const ModInt &x) { return s(a + x.a); }
  ModInt &operator-=(const ModInt &x) { return s(a + mod - x.a); }
  ModInt &operator*=(const ModInt &x) {
    a = uint64_t(a) * x.a % mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &x) {
    *this *= x.inv();
    return *this;
  }
  ModInt operator+(const ModInt &x) const { return ModInt(*this) += x; }
  ModInt operator-(const ModInt &x) const { return ModInt(*this) -= x; }
  ModInt operator*(const ModInt &x) const { return ModInt(*this) *= x; }
  ModInt operator/(const ModInt &x) const { return ModInt(*this) /= x; }
  bool operator==(const ModInt &x) const { return a == x.a; }
  bool operator!=(const ModInt &x) const { return a != x.a; }
  bool operator<(const ModInt &x) const { return a < x.a; }
  ModInt operator-() const { return ModInt() - *this; }
  ModInt pow(int64_t n) const {
    ModInt res(1), x(*this);
    while (n) {
      if (n & 1) res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }
  ModInt inv() const { return pow(mod - 2); }
};
template <uint32_t mod>
istream &operator>>(istream &in, const ModInt<mod> &a) {
  return (in >> a.a);
}
template <uint32_t mod>
ostream &operator<<(ostream &out, const ModInt<mod> &a) {
  return (out << a.a);
}
using mint = ModInt<1000000007>;
template <class T, class E, class F, class G, class H>
struct LazySegmentTree {
  F f;
  G g;
  H h;
  T ti;
  E ei;
  vector<T> dat;
  vector<E> put;
  long long sz;
  LazySegmentTree(const T &ti, const E &ei, const F &f, const G &g, const H &h)
      : ti(ti), ei(ei), f(f), g(g), h(h) {}
  void build(const vector<T> &v) {
    assert(v.size());
    sz = 1;
    while (sz < v.size()) sz <<= 1;
    dat.resize(sz << 1, ti);
    put.resize(sz << 1, ei);
    for (long long i = 0; i < v.size(); i++) dat[sz - 1 + i] = v[i];
    for (long long i = sz - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  inline void push(long long k, long long l, long long r) {
    dat[k] = g(dat[k], put[k], r - l);
    if (k < sz - 1) {
      put[k * 2 + 1] = h(put[k * 2 + 1], put[k]);
      put[k * 2 + 2] = h(put[k * 2 + 2], put[k]);
    }
    put[k] = ei;
  }
  void modify(long long a, long long b, E x, long long k, long long l,
              long long r) {
    push(k, l, r);
    if (r <= a || b <= l) return;
    if (a <= l && r <= b) {
      put[k] = x;
      push(k, l, r);
      return;
    }
    modify(a, b, x, k * 2 + 1, l, (l + r) / 2);
    modify(a, b, x, k * 2 + 2, (l + r) / 2, r);
    dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
  inline void modify(long long a, long long b, E x) {
    return modify(a, b, x, 0, 0, sz);
  }
  T query(long long a, long long b, long long k, long long l, long long r) {
    push(k, l, r);
    if (r <= a || b <= l) return ti;
    if (a <= l && r <= b) return dat[k];
    return f(query(a, b, k * 2 + 1, l, (l + r) / 2),
             query(a, b, k * 2 + 2, (l + r) / 2, r));
  }
  inline T query(long long a, long long b) { return query(a, b, 0, 0, sz); }
};
struct Node {
  long long sumR;
  long long sumL;
  long long sumLR;
  long long sumRi;
  long long l;
  long long r;
};
Node ei{-1, -1, -1, -1, -1, -1};
auto ff = [](Node a, Node b) -> Node {
  if (a.l == -1) return b;
  if (b.l == -1) return a;
  return {a.sumR + b.sumR,
          a.sumL + b.sumL,
          a.sumLR + b.sumLR,
          a.sumRi + b.sumRi,
          a.l,
          b.r};
};
auto gg = [](Node a, pint p, long long len) {
  if (a.l == -1) return ei;
  if (p.first != -1) {
    a.sumLR = a.sumL * p.first;
    a.sumR = (a.r - a.l) * p.first;
    a.sumRi = (a.r * (a.r - 1) / 2 - a.l * (a.l - 1) / 2) * p.first;
  }
  if (p.second != -1) {
    a.sumLR = a.sumR * p.second;
    a.sumL = (a.r - a.l) * p.second;
  }
  return a;
};
auto hh = [](pint p, pint q) {
  if (q.first != -1) p.first = q.first;
  if (q.second != -1) p.second = q.second;
  return p;
};
pint ti{-1, -1};
LazySegmentTree<Node, pint, decltype(ff), decltype(gg), decltype(hh)> seg(
    ei, ti, ff, gg, hh);
long long N;
long long pre[111111], nex[111111];
void solve() {
  vector<Node> ini(N);
  for (long long i = 0; i < (N); i++) {
    ini[i] = {0, 0, 0, 0, i, i + 1};
  }
  seg.build(ini);
  deque<long long> envR, envL;
  long long curL = 0;
  mint ans;
  for (long long i = 0; i < N; i++) {
    seg.modify(i, i + 1, {nex[i] - 1, pre[i] + 1});
    pint chL{-1, pre[i] + 1}, chR{nex[i] - 1, -1};
    while (envR.size() && nex[envR.back()] >= nex[i]) {
      long long r = envR.back() + 1;
      envR.pop_back();
      long long l;
      if (envR.size())
        l = envR.back() + 1;
      else
        l = curL;
      seg.modify(l, r, chR);
    }
    envR.push_back(i);
    while (envL.size() && pre[envL.back()] <= pre[i]) {
      long long r = envL.back() + 1;
      envL.pop_back();
      long long l;
      if (envL.size())
        l = envL.back() + 1;
      else
        l = curL;
      seg.modify(l, r, chL);
    }
    envL.push_back(i);
    if (curL <= pre[i]) {
      curL = pre[i] + 1;
      while (envR.front() < curL) envR.pop_front();
      while (envL.front() < curL) envL.pop_front();
    }
    auto t = seg.query(curL, i + 1);
    ans += t.sumRi;
    ans -= t.sumLR;
    ans -= (t.r * (t.r - 1) / 2 - t.l * (t.l - 1) / 2) * i;
    ans += t.sumL * i;
  }
  cout << ans << endl;
}
signed main() {
  scanf("%lld", &N);
  vint A(N);
  for (long long i = 0; i < (N); i++) scanf("%lld", &A[i]);
  map<long long, long long> mem;
  for (long long i = 0; i < (N); i++) {
    if (mem.find(A[i]) != mem.end())
      pre[i] = mem[A[i]];
    else
      pre[i] = -1;
    mem[A[i]] = i;
  }
  mem = map<long long, long long>();
  for (long long i = N - 1; i >= 0; i--) {
    if (mem.find(A[i]) != mem.end())
      nex[i] = mem[A[i]];
    else
      nex[i] = N;
    mem[A[i]] = i;
  }
  solve();
  return 0;
}
