// #include <bits/stdc++.h>

// #ifdef _DEBUG
// #define debug(x) cerr << "line: " << __LINE__ << ", func: " << __func__ << " ->  " << #x << " = " << x <<
// endl #else #define debug(x) #endif

// #define all(s) begin(s), end(s)
// #define rall(s) rbegin(s), rend(s)
// #define rep(i, a, b) for (int i = (a); i < (b); i++)
// #define rrep(i, a, b) for (int i = ((a)-1); i >= (b); i--)
// #define pb push_back
// #define sz(a) int((a).size())
// #define put(a) ((cout) << (a) << (endl))
// #define fi first
// #define se second

// using namespace std;

// using ll = long long;
// using ull = unsigned long long;
// using i_i = pair<int, int>;
// using ll_ll = pair<ll, ll>;
// using d_ll = pair<double, ll>;
// using ll_d = pair<ll, double>;
// using d_d = pair<double, double>;
// template <class T> using vec = vector<T>;

// static constexpr ll LL_INF = 1LL << 60;
// static constexpr int I_INF = 1 << 28;
// static constexpr double PI = static_cast<double>(3.14159265358979323846264338327950288);
// static constexpr double EPS = numeric_limits<double>::epsilon();
// static constexpr ll MOD = 1000000007;

// static map<type_index, const char* const> scanType = {
//     {typeid(int), "%d"}, {typeid(ll), "%lld"}, {typeid(double), "%lf"}, {typeid(char), "%c"}};

// template <class T> static void scan(vector<T>& v);
// [[maybe_unused]] static void scan(vector<string>& v, bool isWord = true);
// template <class T> static inline bool chmax(T& a, T b);
// template <class T> static inline bool chmin(T& a, T b);
// template <class T> static inline T gcd(T a, T b);
// template <class T> static inline T lcm(T a, T b);
// template <class A, size_t N, class T> static void Fill(A (&arr)[N], const T& val);

// ll dp[2100][2100];
// ll sum[2100][2100];

// int main(int argc, char* argv[]) {
//   ll n, m;
//   cin >> n >> m;
//   vec<ll> s(n), t(m);
//   scan(s), scan(t);

//   dp[0][0] = 1;
//   sum[1][1] = 1;
//   rep(i, 0, n + 1) rep(j, 0, m + 1) {
//     if (i == 0 && j == 0) continue;
//     if (i > 0 && j > 0 && s[i - 1] == t[j - 1]) {
//       dp[i][j] = sum[i][j];
//     }

//     sum[i + 1][j + 1] = sum[i][j + 1] + sum[i + 1][j] - sum[i][j] + dp[i][j];
//     sum[i + 1][j + 1] %= MOD;
//   }

//   cout << sum[n + 1][m + 1] << endl;
//   return 0;
// }

// template <class T> static void scan(vector<T>& v) {
//   auto tFormat = scanType[typeid(T)];
//   for (T& n : v) {
//     scanf(tFormat, &n);
//   }
// }

// static void scan(vector<string>& v, bool isWord) {
//   if (isWord) {
//     for (auto& n : v) {
//       cin >> n;
//     }
//     return;
//   }

//   int i = 0, size = v.size();
//   string s;
//   getline(cin, s);

//   if (s.size() != 0) {
//     i++;
//     v[0] = s;
//   }

//   for (; i < size; ++i) {
//     getline(cin, v[i]);
//   }
// }

// template <class T> inline bool chmax(T& a, T b) {
//   if (a < b) {
//     a = b;
//     return 1;
//   }
//   return 0;
// }

// template <class T> inline bool chmin(T& a, T b) {
//   if (a > b) {
//     a = b;
//     return 1;
//   }
//   return 0;
// }

// template <class T> inline T gcd(T a, T b) { return __gcd(a, b); }

// template <class T> inline T lcm(T a, T b) { return (a * b) / gcd(a, b); }

// template <class A, size_t N, class T> void Fill(A (&arr)[N], const T& val) {
//   std::fill((T*)arr, (T*)(arr + N), val);
// }

#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

// modint: mod 計算を int を扱うように扱える構造体
template <int MOD> struct Fp {
  long long val;
  constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
    if (val < 0) v += MOD;
  }
  constexpr int getmod() { return MOD; }
  constexpr Fp operator-() const noexcept { return val ? MOD - val : 0; }
  constexpr Fp operator+(const Fp& r) const noexcept { return Fp(*this) += r; }
  constexpr Fp operator-(const Fp& r) const noexcept { return Fp(*this) -= r; }
  constexpr Fp operator*(const Fp& r) const noexcept { return Fp(*this) *= r; }
  constexpr Fp operator/(const Fp& r) const noexcept { return Fp(*this) /= r; }
  constexpr Fp& operator+=(const Fp& r) noexcept {
    val += r.val;
    if (val >= MOD) val -= MOD;
    return *this;
  }
  constexpr Fp& operator-=(const Fp& r) noexcept {
    val -= r.val;
    if (val < 0) val += MOD;
    return *this;
  }
  constexpr Fp& operator*=(const Fp& r) noexcept {
    val = val * r.val % MOD;
    return *this;
  }
  constexpr Fp& operator/=(const Fp& r) noexcept {
    long long a = r.val, b = MOD, u = 1, v = 0;
    while (b) {
      long long t = a / b;
      a -= t * b;
      swap(a, b);
      u -= t * v;
      swap(u, v);
    }
    val = val * u % MOD;
    if (val < 0) val += MOD;
    return *this;
  }
  constexpr bool operator==(const Fp& r) const noexcept { return this->val == r.val; }
  constexpr bool operator!=(const Fp& r) const noexcept { return this->val != r.val; }
  friend constexpr ostream& operator<<(ostream& os, const Fp<MOD>& x) noexcept { return os << x.val; }
  friend constexpr istream& operator>>(istream& is, Fp<MOD>& x) noexcept { return is >> x.val; }
  friend constexpr Fp<MOD> modpow(const Fp<MOD>& a, long long n) noexcept {
    if (n == 0) return 1;
    auto t = modpow(a, n / 2);
    t = t * t;
    if (n & 1) t = t * a;
    return t;
  }
};

const int MOD = 1000000007;
using mint = Fp<MOD>;

int N, M;
vector<int> S, T;
mint dp[2100][2100];
mint sdp[2100][2100];

int main() {
  cin >> N >> M;
  S.resize(N), T.resize(M);
  for (int i = 0; i < N; ++i) cin >> S[i];
  for (int i = 0; i < M; ++i) cin >> T[i];

  memset(dp, 0, sizeof(dp));
  memset(sdp, 0, sizeof(dp));
  dp[0][0] = 1;
  sdp[1][1] = 1;
  for (int i = 0; i <= N; ++i) {
    for (int j = 0; j <= M; ++j) {
      if (i == 0 && j == 0) continue;
      if (i - 1 >= 0 && j - 1 >= 0 && S[i - 1] == T[j - 1]) {
        dp[i][j] = sdp[i][j];
      }
      sdp[i + 1][j + 1] = sdp[i + 1][j] + sdp[i][j + 1] - sdp[i][j] + dp[i][j];
    }
  }
  cout << sdp[N + 1][M + 1] << endl;
}

Measured memory_bytes: 69120