#include <bits/stdc++.h>
using namespace std;
const int Mod = 1e9 + 7;
int add(int a, int b) { return ((a += b) >= Mod) ? (a - Mod) : (a); }
int sub(int a, int b) { return ((a -= b) < 0) ? (a + Mod) : (a); }
int mul(int a, int b) { return a * 1ll * b % Mod; }
int sum(int n) { return (n * 1ll * (n + 1) >> 1) % Mod; }
int sum(int l, int r) { return sub(sum(r), sum(l - 1)); }
typedef class Data {
 public:
  int suml, sumr;
  int sumlr, sumcof;
  int sumrj;
  Data() : suml(0), sumr(0), sumlr(0), sumcof(0), sumrj(0) {}
  Data(int suml, int sumr, int sumlr, int sumcof, int sumrj)
      : suml(suml), sumr(sumr), sumlr(sumlr), sumcof(sumcof), sumrj(sumrj) {}
  void update_l(int vl, int L, int R) {
    sumlr = mul(vl, sumr);
    suml = mul(R - L + 1, vl);
    sumcof = sub(sum(L - 1, R - 1), suml);
  }
  void update_r(int vr, int L, int R) {
    sumlr = mul(suml, vr);
    sumr = mul(R - L + 1, vr);
    sumrj = mul(vr, sum(L - 1, R - 1));
  }
  Data operator+(Data b) {
    Data rt;
    rt.suml = add(suml, b.suml);
    rt.sumr = add(sumr, b.sumr);
    rt.sumlr = add(sumlr, b.sumlr);
    rt.sumcof = add(sumcof, b.sumcof);
    rt.sumrj = add(sumrj, b.sumrj);
    return rt;
  }
} Data;
typedef class SegTreeNode {
 public:
  Data d;
  int mx_l;
  int tgl, tgr;
  SegTreeNode *l, *r;
  SegTreeNode() : d(Data()), mx_l(-Mod), tgl(-1), tgr(-1), l(NULL), r(NULL) {}
  void update(int dl, int dr, int L, int R) {
    if (dl != -1) {
      d.update_l(dl, L, R);
      mx_l = dl - R;
      tgl = dl;
    }
    if (dr != -1) {
      d.update_r(dr, L, R);
      tgr = dr;
    }
  }
  void pushDown(int L, int R) {
    int mid = (L + R) >> 1;
    l->update(tgl, tgr, L, mid);
    r->update(tgl, tgr, mid + 1, R);
    tgl = tgr = -1;
  }
  void pushUp() {
    d = l->d + r->d;
    mx_l = max(l->mx_l, r->mx_l);
  }
} SegTreeNode;
const int N = 1e5 + 5;
SegTreeNode pool[N << 2];
SegTreeNode* top = pool;
SegTreeNode* newnode() { return top++; }
typedef class SegTree {
 public:
  SegTreeNode* rt;
  SegTree() : rt(NULL) {}
  SegTree(int n) { build(rt, 1, n); }
  void build(SegTreeNode*& p, int l, int r) {
    p = newnode();
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(p->l, l, mid);
    build(p->r, mid + 1, r);
  }
  void update(SegTreeNode* p, int l, int r, int ql, int qr, int vl, int vr) {
    if (l == ql && r == qr) {
      p->update(vl, vr, l, r);
      return;
    }
    if (p->tgl != -1 || p->tgr != -1) p->pushDown(l, r);
    int mid = (l + r) >> 1;
    if (qr <= mid)
      update(p->l, l, mid, ql, qr, vl, vr);
    else if (ql > mid)
      update(p->r, mid + 1, r, ql, qr, vl, vr);
    else {
      update(p->l, l, mid, ql, mid, vl, vr);
      update(p->r, mid + 1, r, mid + 1, qr, vl, vr);
    }
    p->pushUp();
  }
  Data query(SegTreeNode* p, int l, int r, int ql, int qr) {
    if (l == ql && r == qr) return p->d;
    if (p->tgl != -1 || p->tgr != -1) p->pushDown(l, r);
    int mid = (l + r) >> 1;
    if (qr <= mid) return query(p->l, l, mid, ql, qr);
    if (ql > mid) return query(p->r, mid + 1, r, ql, qr);
    Data _ = query(p->l, l, mid, ql, mid);
    Data __ = query(p->r, mid + 1, r, mid + 1, qr);
    return _ + __;
  }
  int query(SegTreeNode* p, int l, int r) {
    if (l == r) return (p->mx_l >= 0) ? (l) : (l - 1);
    if (p->tgl != -1 || p->tgr != -1) p->pushDown(l, r);
    int mid = (l + r) >> 1;
    if (p->r->mx_l >= 0) return query(p->r, mid + 1, r);
    return query(p->l, l, mid);
  }
} SegTree;
int n;
int a[N];
SegTree st;
int pre[N], suf[N];
map<int, int> head;
int top_l = 0, top_r = 0;
pair<int, int> stack_l[N], stack_r[N];
inline void init() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", a + i);
  for (int i = 1; i <= n; i++) {
    pre[i] = head[a[i]];
    head[a[i]] = i;
  }
  head.clear();
  for (int i = n; i; i--) {
    if (!head.count(a[i]))
      suf[i] = n + 1;
    else
      suf[i] = head[a[i]];
    head[a[i]] = i;
  }
  head.clear();
}
int ans = 0;
inline void solve() {
  st = SegTree(n);
  stack_l[top_l] = pair<int, int>(Mod, 0);
  stack_r[top_r] = pair<int, int>(-Mod, 0);
  for (int i = 1, l, r, mid, border; i <= n; i++) {
    while (stack_l[top_l].first <= pre[i]) top_l--;
    st.update(st.rt, 1, n, stack_l[top_l].second + 1, i, pre[i], -1);
    stack_l[++top_l] = pair<int, int>(pre[i], i);
    while (stack_r[top_r].first >= suf[i]) top_r--;
    st.update(st.rt, 1, n, stack_r[top_r].second + 1, i, -1, suf[i]);
    stack_r[++top_r] = pair<int, int>(suf[i], i);
    l = 1, r = top_r;
    while (l <= r) {
      mid = (l + r) >> 1;
      if (stack_r[mid].first > i)
        r = mid - 1;
      else
        l = mid + 1;
    }
    border = stack_r[r].second + 1;
    border = max(border, st.query(st.rt, 1, n) + 1);
    Data d = st.query(st.rt, 1, n, border, i);
    ans = sub(ans, d.sumlr);
    ans = add(ans, d.sumrj);
    ans = sub(ans, mul(i + 1, d.sumcof));
  }
  printf("%d\n", ans);
}
int main() {
  init();
  solve();
  return 0;
}
