#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int mod = 1000000007;
int n;
int a[MAXN];
int nxt[MAXN];
int prv[MAXN];
struct node {
  long long smL, smR, l, r, sz, sm, lazySub;
};
node combine(const node &a, const node &b) {
  node c;
  c.smL = (a.smL + b.smL) % mod;
  c.smR = (a.smR + b.smR) % mod;
  c.sz = a.sz + b.sz;
  c.sm = (a.sm + b.sm) % mod;
  c.lazySub = 0;
  if (a.r == b.r)
    c.r = a.r;
  else
    c.r = -2;
  if (a.l == b.l)
    c.l = a.l;
  else
    c.l = -2;
  return c;
}
void setL(node &x, int L) {
  assert(x.l != -2);
  int diff = L - x.l;
  x.l = L;
  x.smL -= (diff * x.sz) % mod;
  x.sm -= (x.smR * diff) % mod;
  while (x.smL < 0) x.smL += mod;
  while (x.sm < 0) x.sm += mod;
}
void setR(node &x, int R) {
  assert(x.r != -2);
  int diff = x.r - R;
  x.r = R;
  x.smR -= (diff * x.sz) % mod;
  x.sm -= (x.smL * diff) % mod;
  while (x.smR < 0) x.smR += mod;
  while (x.sm < 0) x.sm += mod;
}
void subLDis(node &x, int sub) {
  x.lazySub += sub;
  x.smL -= (sub * x.sz) % mod;
  x.sm -= (sub * x.smR) % mod;
  while (x.smL < 0) x.smL += mod;
  while (x.sm < 0) x.sm += mod;
}
void resetLazy(node &x) { x.lazySub = 0; }
void push(node &par, node &ch) {
  if (par.lazySub) subLDis(ch, par.lazySub);
  if (par.l != -2) setL(ch, par.l);
  if (par.r != -2) setR(ch, par.r);
}
node tree[4 * MAXN];
void build(int i, int l, int r) {
  if (l == r) {
    tree[i].sz = 1;
    tree[i].r = nxt[l];
    tree[i].smR = nxt[l] - 1 - l;
    tree[i].l = prv[l];
    tree[i].smL = l - 1 - prv[l];
    tree[i].sm = (tree[i].smL * tree[i].smR) % mod;
    tree[i].lazySub = 0;
    return;
  }
  build(i * 2 + 1, l, (l + r) / 2);
  build(i * 2 + 2, (l + r) / 2 + 1, r);
  tree[i] = combine(tree[i * 2 + 1], tree[i * 2 + 2]);
}
node getRange(int i, int l, int r, int x, int y) {
  if (l >= x && r <= y) {
    return tree[i];
  }
  push(tree[i], tree[i * 2 + 1]);
  push(tree[i], tree[i * 2 + 2]);
  resetLazy(tree[i]);
  int mid = (l + r) / 2;
  if (y <= mid)
    return getRange(i * 2 + 1, l, mid, x, y);
  else if (x > mid)
    return getRange(i * 2 + 2, mid + 1, r, x, y);
  else
    return combine(getRange(i * 2 + 1, l, mid, x, y),
                   getRange(i * 2 + 2, mid + 1, r, x, y));
}
void setLRange(int i, int l, int r, int x, int y, int L) {
  if (l >= x && r <= y && tree[i].l != -2) {
    setL(tree[i], L);
    return;
  }
  push(tree[i], tree[i * 2 + 1]);
  push(tree[i], tree[i * 2 + 2]);
  resetLazy(tree[i]);
  int mid = (l + r) / 2;
  if (y <= mid)
    setLRange(i * 2 + 1, l, mid, x, y, L);
  else if (x > mid)
    setLRange(i * 2 + 2, mid + 1, r, x, y, L);
  else {
    setLRange(i * 2 + 1, l, mid, x, y, L);
    setLRange(i * 2 + 2, mid + 1, r, x, y, L);
  }
  tree[i] = combine(tree[i * 2 + 1], tree[i * 2 + 2]);
}
void setRRange(int i, int l, int r, int x, int y, int R) {
  if (l >= x && r <= y && tree[i].r != -2) {
    setR(tree[i], R);
    return;
  }
  push(tree[i], tree[i * 2 + 1]);
  push(tree[i], tree[i * 2 + 2]);
  resetLazy(tree[i]);
  int mid = (l + r) / 2;
  if (y <= mid)
    setRRange(i * 2 + 1, l, mid, x, y, R);
  else if (x > mid)
    setRRange(i * 2 + 2, mid + 1, r, x, y, R);
  else {
    setRRange(i * 2 + 1, l, mid, x, y, R);
    setRRange(i * 2 + 2, mid + 1, r, x, y, R);
  }
  tree[i] = combine(tree[i * 2 + 1], tree[i * 2 + 2]);
}
void subLRange(int i, int l, int r, int x, int y) {
  if (l >= x && r <= y) {
    subLDis(tree[i], 1);
    return;
  }
  push(tree[i], tree[i * 2 + 1]);
  push(tree[i], tree[i * 2 + 2]);
  resetLazy(tree[i]);
  int mid = (l + r) / 2;
  if (y <= mid)
    subLRange(i * 2 + 1, l, mid, x, y);
  else if (x > mid)
    subLRange(i * 2 + 2, mid + 1, r, x, y);
  else {
    subLRange(i * 2 + 1, l, mid, x, y);
    subLRange(i * 2 + 2, mid + 1, r, x, y);
  }
  tree[i] = combine(tree[i * 2 + 1], tree[i * 2 + 2]);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", a + i);
  map<int, int> lst;
  for (int i = 0; i < n; i++) {
    if (lst.count(a[i])) {
      prv[i] = lst[a[i]];
    } else {
      prv[i] = -1;
    }
    lst[a[i]] = i;
  }
  lst.clear();
  for (int i = n - 1; i >= 0; i--) {
    if (lst.count(a[i])) {
      nxt[i] = lst[a[i]];
    } else {
      nxt[i] = n;
    }
    lst[a[i]] = i;
  }
  build(0, 0, n - 1);
  stack<pair<int, int> > qr;
  stack<pair<int, int> > ql;
  int end = n - 1;
  int ans = 0;
  for (int i = n - 1; i >= 0; i--) {
    int rrange = i;
    while (!qr.empty() && qr.top().first > nxt[i]) {
      rrange = qr.top().second;
      qr.pop();
    }
    qr.push(make_pair(nxt[i], rrange));
    if (rrange > i) setRRange(0, 0, n - 1, i + 1, rrange, nxt[i]);
    int lrange = i;
    while (!ql.empty() && ql.top().first < prv[i]) {
      lrange = ql.top().second;
      ql.pop();
    }
    ql.push(make_pair(prv[i], lrange));
    if (lrange > i) setLRange(0, 0, n - 1, i + 1, lrange, prv[i]);
    node res = getRange(0, 0, n - 1, i, end);
    ans += res.sm;
    ans %= mod;
    if (i) {
      end = min(end, nxt[i - 1] - 1);
      if (end >= i) subLRange(0, 0, n - 1, i, end);
    }
  }
  printf("%d\n", ans);
}
