#include <iostream>
#include <vector>
using namespace std;
const int MOD = 1e9 + 7;
struct SegmentTree {
int n;
vector<long long> tree, lazy;
SegmentTree(int n) : n(n), tree(4 * n + 5, 0), lazy(4 * n + 5, 0) {}
// Đẩy giá trị lazy xuống các con
void push(int node, int l, int r) {
if (lazy[node] != 0) {
int mid = (l + r) / 2;
tree[2 * node] = (tree[2 * node] + lazy[node] * (mid - l + 1)) % MOD;
lazy[2 * node] = (lazy[2 * node] + lazy[node]) % MOD;
tree[2 * node + 1] = (tree[2 * node + 1] + lazy[node] * (r - mid)) % MOD;
lazy[2 * node + 1] = (lazy[2 * node + 1] + lazy[node]) % MOD;
lazy[node] = 0;
}
}
// Cộng val vào đoạn [ql, qr]
void update(int node, int l, int r, int ql, int qr, long long val) {
if (ql > r || qr < l) return;
if (ql <= l && r <= qr) {
tree[node] = (tree[node] + val * (r - l + 1)) % MOD;
lazy[node] = (lazy[node] + val) % MOD;
return;
}
push(node, l, r);
int mid = (l + r) / 2;
update(2 * node, l, mid, ql, qr, val);
update(2 * node + 1, mid + 1, r, ql, qr, val);
tree[node] = (tree[2 * node] + tree[2 * node + 1]) % MOD;
}
// Truy vấn tổng trên đoạn [ql, qr]
long long query(int node, int l, int r, int ql, int qr) {
if (ql > r || qr < l) return 0;
if (ql <= l && r <= qr) return tree[node];
push(node, l, r);
int mid = (l + r) / 2;
return (query(2 * node, l, mid, ql, qr) + query(2 * node + 1, mid + 1, r, ql, qr)) % MOD;
}
};
int main() {
// Tối ưu I/O
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
if (!(cin >> n)) return 0;
vector<int> a(n + 1);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
SegmentTree st(n);
vector<int> last(n + 1, 0); // Lưu vị trí xuất hiện gần nhất của giá trị v
long long total_beauty = 0;
for (int R = 1; R <= n; ++R) {
int x = a[R];
int prev_pos = last[x];
// 1. Cộng 1 vào các L thuộc [prev_pos + 1, R]
st.update(1, 1, n, prev_pos + 1, R, 1);
// 2. Lấy tổng số phần tử phân biệt của mọi đoạn con kết thúc tại R
long long current_sum = st.query(1, 1, n, 1, R);
total_beauty = (total_beauty + current_sum) % MOD;
// 3. Cập nhật vị trí xuất hiện mới nhất
last[x] = R;
}
cout << (total_beauty % MOD + MOD) % MOD << "\n";
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmNvbnN0IGludCBNT0QgPSAxZTkgKyA3OwoKc3RydWN0IFNlZ21lbnRUcmVlIHsKICAgIGludCBuOwogICAgdmVjdG9yPGxvbmcgbG9uZz4gdHJlZSwgbGF6eTsKCiAgICBTZWdtZW50VHJlZShpbnQgbikgOiBuKG4pLCB0cmVlKDQgKiBuICsgNSwgMCksIGxhenkoNCAqIG4gKyA1LCAwKSB7fQoKICAgIC8vIMSQ4bqpeSBnacOhIHRy4buLIGxhenkgeHXhu5FuZyBjw6FjIGNvbgogICAgdm9pZCBwdXNoKGludCBub2RlLCBpbnQgbCwgaW50IHIpIHsKICAgICAgICBpZiAobGF6eVtub2RlXSAhPSAwKSB7CiAgICAgICAgICAgIGludCBtaWQgPSAobCArIHIpIC8gMjsKCiAgICAgICAgICAgIHRyZWVbMiAqIG5vZGVdID0gKHRyZWVbMiAqIG5vZGVdICsgbGF6eVtub2RlXSAqIChtaWQgLSBsICsgMSkpICUgTU9EOwogICAgICAgICAgICBsYXp5WzIgKiBub2RlXSA9IChsYXp5WzIgKiBub2RlXSArIGxhenlbbm9kZV0pICUgTU9EOwoKICAgICAgICAgICAgdHJlZVsyICogbm9kZSArIDFdID0gKHRyZWVbMiAqIG5vZGUgKyAxXSArIGxhenlbbm9kZV0gKiAociAtIG1pZCkpICUgTU9EOwogICAgICAgICAgICBsYXp5WzIgKiBub2RlICsgMV0gPSAobGF6eVsyICogbm9kZSArIDFdICsgbGF6eVtub2RlXSkgJSBNT0Q7CgogICAgICAgICAgICBsYXp5W25vZGVdID0gMDsKICAgICAgICB9CiAgICB9CgogICAgLy8gQ+G7mW5nIHZhbCB2w6BvIMSRb+G6oW4gW3FsLCBxcl0KICAgIHZvaWQgdXBkYXRlKGludCBub2RlLCBpbnQgbCwgaW50IHIsIGludCBxbCwgaW50IHFyLCBsb25nIGxvbmcgdmFsKSB7CiAgICAgICAgaWYgKHFsID4gciB8fCBxciA8IGwpIHJldHVybjsKICAgICAgICBpZiAocWwgPD0gbCAmJiByIDw9IHFyKSB7CiAgICAgICAgICAgIHRyZWVbbm9kZV0gPSAodHJlZVtub2RlXSArIHZhbCAqIChyIC0gbCArIDEpKSAlIE1PRDsKICAgICAgICAgICAgbGF6eVtub2RlXSA9IChsYXp5W25vZGVdICsgdmFsKSAlIE1PRDsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBwdXNoKG5vZGUsIGwsIHIpOwogICAgICAgIGludCBtaWQgPSAobCArIHIpIC8gMjsKICAgICAgICB1cGRhdGUoMiAqIG5vZGUsIGwsIG1pZCwgcWwsIHFyLCB2YWwpOwogICAgICAgIHVwZGF0ZSgyICogbm9kZSArIDEsIG1pZCArIDEsIHIsIHFsLCBxciwgdmFsKTsKICAgICAgICB0cmVlW25vZGVdID0gKHRyZWVbMiAqIG5vZGVdICsgdHJlZVsyICogbm9kZSArIDFdKSAlIE1PRDsKICAgIH0KCiAgICAvLyBUcnV5IHbhuqVuIHThu5VuZyB0csOqbiDEkW/huqFuIFtxbCwgcXJdCiAgICBsb25nIGxvbmcgcXVlcnkoaW50IG5vZGUsIGludCBsLCBpbnQgciwgaW50IHFsLCBpbnQgcXIpIHsKICAgICAgICBpZiAocWwgPiByIHx8IHFyIDwgbCkgcmV0dXJuIDA7CiAgICAgICAgaWYgKHFsIDw9IGwgJiYgciA8PSBxcikgcmV0dXJuIHRyZWVbbm9kZV07CiAgICAgICAgcHVzaChub2RlLCBsLCByKTsKICAgICAgICBpbnQgbWlkID0gKGwgKyByKSAvIDI7CiAgICAgICAgcmV0dXJuIChxdWVyeSgyICogbm9kZSwgbCwgbWlkLCBxbCwgcXIpICsgcXVlcnkoMiAqIG5vZGUgKyAxLCBtaWQgKyAxLCByLCBxbCwgcXIpKSAlIE1PRDsKICAgIH0KfTsKCmludCBtYWluKCkgewogICAgLy8gVOG7kWkgxrB1IEkvTwogICAgaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgICBjaW4udGllKE5VTEwpOwoKICAgIGludCBuOwogICAgaWYgKCEoY2luID4+IG4pKSByZXR1cm4gMDsKCiAgICB2ZWN0b3I8aW50PiBhKG4gKyAxKTsKICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IG47ICsraSkgewogICAgICAgIGNpbiA+PiBhW2ldOwogICAgfQoKICAgIFNlZ21lbnRUcmVlIHN0KG4pOwogICAgdmVjdG9yPGludD4gbGFzdChuICsgMSwgMCk7IC8vIEzGsHUgduG7iyB0csOtIHh14bqldCBoaeG7h24gZ+G6p24gbmjhuqV0IGPhu6dhIGdpw6EgdHLhu4sgdgogICAgbG9uZyBsb25nIHRvdGFsX2JlYXV0eSA9IDA7CgogICAgZm9yIChpbnQgUiA9IDE7IFIgPD0gbjsgKytSKSB7CiAgICAgICAgaW50IHggPSBhW1JdOwogICAgICAgIGludCBwcmV2X3BvcyA9IGxhc3RbeF07CgogICAgICAgIC8vIDEuIEPhu5luZyAxIHbDoG8gY8OhYyBMIHRodeG7mWMgW3ByZXZfcG9zICsgMSwgUl0KICAgICAgICBzdC51cGRhdGUoMSwgMSwgbiwgcHJldl9wb3MgKyAxLCBSLCAxKTsKCiAgICAgICAgLy8gMi4gTOG6pXkgdOG7lW5nIHPhu5EgcGjhuqduIHThu60gcGjDom4gYmnhu4d0IGPhu6dhIG3hu41pIMSRb+G6oW4gY29uIGvhur90IHRow7pjIHThuqFpIFIKICAgICAgICBsb25nIGxvbmcgY3VycmVudF9zdW0gPSBzdC5xdWVyeSgxLCAxLCBuLCAxLCBSKTsKICAgICAgICB0b3RhbF9iZWF1dHkgPSAodG90YWxfYmVhdXR5ICsgY3VycmVudF9zdW0pICUgTU9EOwoKICAgICAgICAvLyAzLiBD4bqtcCBuaOG6rXQgduG7iyB0csOtIHh14bqldCBoaeG7h24gbeG7m2kgbmjhuqV0CiAgICAgICAgbGFzdFt4XSA9IFI7CiAgICB9CgogICAgY291dCA8PCAodG90YWxfYmVhdXR5ICUgTU9EICsgTU9EKSAlIE1PRCA8PCAiXG4iOwoKICAgIHJldHVybiAwOwp9