Problem:
Score : 700 points

Problem Statement

There are N stones arranged in a row. The i-th stone from the left is painted in the color C_i.

Snuke will perform the following operation zero or more times:

Choose two stones painted in the same color. Repaint all the stones between them, with the color of the chosen stones.

Find the number of possible final sequences of colors of the stones, modulo 10^9+7.

Constraints

1 \leq N \leq 2\times 10^5

1 \leq C_i \leq 2\times 10^5(1\leq i\leq N)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
C_1
:
C_N

Output

Print the number of possible final sequences of colors of the stones, modulo 10^9+7.

Sample Input 1

5
1
2
1
2
2

Sample Output 1

3

We can make three sequences of colors of stones, as follows:

(1,2,1,2,2), by doing nothing.

(1,1,1,2,2), by choosing the first and third stones to perform the operation.

(1,2,2,2,2), by choosing the second and fourth stones to perform the operation.

Sample Input 2

6
4
2
5
4
2
4

Sample Output 2

5

Sample Input 3

7
1
3
1
2
3
3
2

Sample Output 3

5

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <algorithm>
#include <bits/stdc++.h>
#include <cstdint>
#include <iostream>
#include <iterator>
#include <limits>
#include <stdexcept>
#include <vector>

// lib/quo.hpp
#ifndef QUO_H
#define QUO_H

/*
a == tools:quo(a, b) * b + tools::mod(a, b)
0 <= tools::mod(a, b) < std::abs(b)
*/

namespace tools {
  template <typename T>
  constexpr T quo(const T lhs, const T rhs) {
    return lhs > 0 ? lhs / rhs : rhs > 0 ? -((-lhs - 1 + rhs) / rhs) : (-lhs - 1 + -rhs) / -rhs;
  }
}

#endif

// lib/square.hpp
#ifndef SQUARE_HPP
#define SQUARE_HPP

/*
usage:

tools::square(5) => 25
*/

namespace tools {
  template <typename T>
  constexpr T square(const T x) {
    return x * x;
  }
}

#endif

// lib/is_prime.hpp
#ifndef IS_PRIME_H
#define IS_PRIME_H


/*
usage:

static_assert(tools::is_prime(P), "P must be prime.");
*/

// Source: Stack Overflow ( https://stackoverflow.com/questions/18303632/compile-time-prime-checking/18306693#18306693 )
// Author: Casey ( https://stackoverflow.com/users/923854/casey )
// License: CC BY-SA 3.0
namespace tools {
  namespace detail {
    namespace is_prime {
      constexpr std::uint_fast32_t mid(const std::uint_fast32_t low, const std::uint_fast32_t high) {
        return (low + high) / 2;
      }

      // precondition: low*low <= n, high*high > n.
      constexpr std::uint_fast32_t ceilsqrt(const std::uint_fast32_t n, const std::uint_fast32_t low, const std::uint_fast32_t high) {
        return low + 1 >= high
          ? high
          : (mid(low, high) * mid(low, high) == n)
          ? mid(low, high)
          : (mid(low, high) * mid(low, high) <  n)
          ? ceilsqrt(n, mid(low, high), high)
          : ceilsqrt(n, low, mid(low, high));
      }

      // returns ceiling(sqrt(n))
      constexpr std::uint_fast32_t ceilsqrt(const std::uint_fast32_t n) {
        return n < 3
          ? n
          : ceilsqrt(n, 1, std::uint_fast32_t(1) << (std::numeric_limits<std::uint_fast32_t>::digits / 2));
      }

      // returns true if n is divisible by an odd integer in
      // [2 * low + 1, 2 * high + 1).
      constexpr bool find_factor(const std::uint_fast32_t n, const std::uint_fast32_t low, const std::uint_fast32_t high) {
        return low + 1 >= high
          ? (n % (2 * low + 1)) == 0
          : (find_factor(n, low, mid(low, high)) || find_factor(n, mid(low, high), high));
      }
    }
  }

  constexpr bool is_prime(const std::uint_fast32_t n) {
    return n > 1
      && (n == 2
        || (n % 2 == 1
          && (n == 3
            || !detail::is_prime::find_factor(n, 1, (detail::is_prime::ceilsqrt(n) + 1) / 2))));
  }
}

#endif

// lib/util.hpp
#ifndef UTIL_HPP
#define UTIL_HPP


typedef ::std::int_fast64_t i64;
typedef ::std::uint_fast64_t u64;
typedef ::std::int_fast32_t i32;
typedef ::std::uint_fast32_t u32;

namespace tools {
  template <typename T>
  void read(::std::istream& is, ::std::vector<T>& vector, const typename ::std::vector<T>::size_type size) {
    vector.reserve(size);
    ::std::copy_n(::std::istream_iterator<T>(is), size, ::std::back_inserter(vector));
  }
  template <typename T>
  void read(::std::vector<T>& vector, const typename ::std::vector<T>::size_type size) {
    ::tools::read(::std::cin, vector, size);
  }

  template <typename T, ::std::size_t N>
  void read(::std::istream& is, ::std::array<T, N>& array) {
    ::std::copy_n(std::istream_iterator<T>(is), N, array.begin());
  }
  template <typename T, ::std::size_t N>
  void read(::std::array<T, N>& array) {
    ::tools::read(::std::cin, array);
  }
}

#endif

// lib/mod.hpp
#ifndef MOD_HPP
#define MOD_HPP


/*
a == tools:quo(a, b) * b + tools::mod(a, b)
0 <= tools::mod(a, b) < std::abs(b)
*/

namespace tools {
  template <typename T>
  constexpr T mod(const T lhs, const T rhs) {
    return lhs - quo(lhs, rhs) * rhs;
  }
}

#endif

// lib/int_mod.hpp
#ifndef INT_MOD_HPP
#define INT_MOD_HPP


/*
usage:

constexpr const std::uint_fast32_t p = 3;
tools::int_mod<p>(5) + tools::int_mod<p>(4) // => 0
*/

namespace tools {
  template <std::uint_fast32_t P>
  class int_mod {
    static_assert(is_prime(P), "P must be prime.");

  private:
    std::uint_fast32_t m_value;

    constexpr static std::uint_fast32_t add_impl(const std::uint_fast32_t lhs, const std::uint_fast32_t rhs) {
      return lhs + rhs - (lhs + rhs >= P ? P : 0u);
    }

    constexpr static std::uint_fast32_t sub_impl(const std::uint_fast32_t lhs, const std::uint_fast32_t rhs) {
      return lhs - rhs + (lhs < rhs ? P : 0u);
    }

    constexpr static std::uint_fast32_t mul_impl(const std::uint_fast32_t lhs, const std::uint_fast32_t rhs) {
      return static_cast<std::uint_fast32_t>(static_cast<std::uint_fast64_t>(lhs) * static_cast<std::uint_fast64_t>(rhs) % static_cast<std::uint_fast64_t>(P));
    }

    constexpr int_mod<P> pow_impl(const std::uint_fast32_t exponent) const {
      return exponent == 0u
        ? int_mod<P>(1)
        : exponent % 2u == 0u
          ? square(this->pow_impl(exponent / 2u))
          : this->pow_impl(exponent - 1u) * *this;
    }

  public:
    int_mod() :
      m_value(0) {
    }

    int_mod(const std::int_fast32_t value) :
      m_value(static_cast<std::uint_fast32_t>(mod(value, static_cast<std::int_fast32_t>(P)))) {
    }

    int_mod(const int_mod<P>& other) :
      int_mod(other.m_value) {
    }

    constexpr operator std::uint_fast32_t() const {
      return this->m_value;
    }

    constexpr friend int_mod<P> operator+(const int_mod<P>& lhs, const int_mod<P>& rhs) {
      return int_mod<P>(int_mod<P>::add_impl(lhs.m_value, rhs.m_value));
    }

    int_mod<P>& operator+=(const int_mod<P>& other) {
      this->m_value = int_mod<P>::add_impl(this->m_value, other.m_value);
      return *this;
    }

    int_mod<P>& operator++() {
      this->m_value = int_mod<P>::add_impl(this->m_value, 1u);
      return *this;
    }

    int_mod<P> operator++(int) {
      int_mod<P> prev(*this);
      ++this;
      return prev;
    }

    constexpr friend int_mod<P> operator-(const int_mod<P>& lhs, const int_mod<P>& rhs) {
      return int_mod<P>(int_mod<P>::sub_impl(lhs.m_value, rhs.m_value));
    }

    int_mod<P>& operator-=(const int_mod<P>& other) {
      this->m_value = int_mod<P>::sub_impl(this->m_value, other.m_value);
      return *this;
    }

    int_mod<P>& operator--() {
      this->m_value = int_mod<P>::sub_impl(this->m_value, 1u);
      return *this;
    }

    int_mod<P> operator--(int) {
      int_mod<P> prev(*this);
      --this;
      return prev;
    }

    constexpr friend int_mod<P> operator*(const int_mod<P>& lhs, const int_mod<P>& rhs) {
      return int_mod<P>(int_mod<P>::mul_impl(lhs.m_value, rhs.m_value));
    }

    int_mod<P>& operator*=(const int_mod<P>& other) {
      this->m_value = int_mod<P>::mul_impl(this->m_value, other.m_value);
      return *this;
    }

    constexpr int_mod<P> inv() const {
      return this->m_value > 0u
        ? this->pow_impl(P - 2u)
        : (throw std::invalid_argument("cannot divide by zero"));
    }

    constexpr int_mod<P> pow(const std::int_fast32_t exponent) const {
      return exponent >= 0
        ? this->pow_impl(static_cast<std::uint_fast32_t>(exponent))
        : this->pow_impl(static_cast<std::uint_fast32_t>(-exponent)).inv();
    }

    constexpr friend int_mod<P> operator/(const int_mod<P>& lhs, const int_mod<P>& rhs) {
      return lhs * rhs.inv();
    }

    int_mod<P>& operator/=(const int_mod<P>& other) {
      this->m_value = int_mod<P>::mul_impl(this->m_value, other.inv().m_value);
      return *this;
    }
  };
}

#endif

// main.cpp

constexpr u32 P = 1000000007;

int main() {
  i64 N;
  std::cin >> N;
  std::vector<i64> C;
  tools::read(C, N);
  std::transform(C.begin(), C.end(), C.begin(), [](const i64& C_i) { return C_i - 1; });

  std::vector<i64> left(N);
  {
    std::vector<i64> color_working(200000, -1);
    for (i64 i = 0; i < N; ++i) {
      left[i] = color_working[C[i]];
      color_working[C[i]] = i;
    }
  }

  std::vector<tools::int_mod<P>> dp(N);
  dp[0] = tools::int_mod<P>(1);
  for (i64 i = 1; i < N; ++i) {
    dp[i] = dp[i - 1];
    if (left[i] >= 0 && i - left[i] >= 2) dp[i] += dp[left[i]];
  }

  std::cout << static_cast<u32>(dp.back()) << std::endl;
  return 0;
}