#include <bits/stdc++.h>
using namespace std;
std::mt19937 mt((long long)time(0));
long long dx[4] = {0, 1, 0, -1};
long long dy[4] = {1, 0, -1, 0};
using Weight = long long;
using Flow = long long;
struct Edge {
  long long src, dst;
  Weight weight;
  Flow cap;
  Edge() : src(0), dst(0), weight(0) {}
  Edge(long long s, long long d, Weight w) : src(s), dst(d), weight(w) {}
};
using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;
using Array = std::vector<Weight>;
using Matrix = std::vector<Array>;
void add_edge(Graph &g, long long a, long long b, Weight w = 1) {
  g[a].emplace_back(a, b, w);
  g[b].emplace_back(b, a, w);
}
void add_arc(Graph &g, long long a, long long b, Weight w = 1) {
  g[a].emplace_back(a, b, w);
}
struct uf_tree {
  std::vector<long long> parent;
  long long __size;
  uf_tree(long long size_) : parent(size_, -1), __size(size_) {}
  void unite(long long x, long long y) {
    if ((x = find(x)) != (y = find(y))) {
      if (parent[y] < parent[x]) std::swap(x, y);
      parent[x] += parent[y];
      parent[y] = x;
      __size--;
    }
  }
  bool is_same(long long x, long long y) { return find(x) == find(y); }
  long long find(long long x) {
    return parent[x] < 0 ? x : parent[x] = find(parent[x]);
  }
  long long size(long long x) { return -parent[find(x)]; }
  long long size() { return __size; }
};
template <signed M, unsigned T>
struct mod_int {
  constexpr static signed MODULO = M;
  constexpr static unsigned TABLE_SIZE = T;
  signed x;
  mod_int() : x(0) {}
  mod_int(long long y)
      : x(static_cast<signed>(y >= 0 ? y % MODULO : MODULO - (-y) % MODULO)) {}
  mod_int(signed y) : x(y >= 0 ? y % MODULO : MODULO - (-y) % MODULO) {}
  mod_int &operator+=(const mod_int &rhs) {
    if ((x += rhs.x) >= MODULO) x -= MODULO;
    return *this;
  }
  mod_int &operator-=(const mod_int &rhs) {
    if ((x += MODULO - rhs.x) >= MODULO) x -= MODULO;
    return *this;
  }
  mod_int &operator*=(const mod_int &rhs) {
    x = static_cast<signed>(1LL * x * rhs.x % MODULO);
    return *this;
  }
  mod_int &operator/=(const mod_int &rhs) {
    x = static_cast<signed>((1LL * x * rhs.inv().x) % MODULO);
    return *this;
  }
  mod_int operator-() const { return mod_int(-x); }
  mod_int operator+(const mod_int &rhs) const { return mod_int(*this) += rhs; }
  mod_int operator-(const mod_int &rhs) const { return mod_int(*this) -= rhs; }
  mod_int operator*(const mod_int &rhs) const { return mod_int(*this) *= rhs; }
  mod_int operator/(const mod_int &rhs) const { return mod_int(*this) /= rhs; }
  bool operator<(const mod_int &rhs) const { return x < rhs.x; }
  mod_int inv() const {
    assert(x != 0);
    if (x <= static_cast<signed>(TABLE_SIZE)) {
      if (_inv[1].x == 0) prepare();
      return _inv[x];
    } else {
      signed a = x, b = MODULO, u = 1, v = 0, t;
      while (b) {
        t = a / b;
        a -= t * b;
        std::swap(a, b);
        u -= t * v;
        std::swap(u, v);
      }
      return mod_int(u);
    }
  }
  mod_int pow(long long t) const {
    assert(!(x == 0 && t == 0));
    mod_int e = *this, res = mod_int(1);
    for (; t; e *= e, t >>= 1)
      if (t & 1) res *= e;
    return res;
  }
  mod_int fact() {
    if (_fact[0].x == 0) prepare();
    return _fact[x];
  }
  mod_int inv_fact() {
    if (_fact[0].x == 0) prepare();
    return _inv_fact[x];
  }
  mod_int choose(mod_int y) {
    assert(y.x <= x);
    return this->fact() * y.inv_fact() * mod_int(x - y.x).inv_fact();
  }
  static mod_int _inv[TABLE_SIZE + 1];
  static mod_int _fact[TABLE_SIZE + 1];
  static mod_int _inv_fact[TABLE_SIZE + 1];
  static void prepare() {
    _inv[1] = 1;
    for (long long i = 2; i <= (long long)TABLE_SIZE; ++i) {
      _inv[i] = 1LL * _inv[MODULO % i].x * (MODULO - MODULO / i) % MODULO;
    }
    _fact[0] = 1;
    for (unsigned i = 1; i <= TABLE_SIZE; ++i) {
      _fact[i] = _fact[i - 1] * signed(i);
    }
    _inv_fact[TABLE_SIZE] = _fact[TABLE_SIZE].inv();
    for (long long i = (long long)TABLE_SIZE - 1; i >= 0; --i) {
      _inv_fact[i] = _inv_fact[i + 1] * (i + 1);
    }
  }
};
template <signed M, unsigned F>
std::ostream &operator<<(std::ostream &os, const mod_int<M, F> &rhs) {
  return os << rhs.x;
}
template <signed M, unsigned F>
std::istream &operator>>(std::istream &is, mod_int<M, F> &rhs) {
  long long s;
  is >> s;
  rhs = mod_int<M, F>(s);
  return is;
}
template <signed M, unsigned F>
mod_int<M, F> mod_int<M, F>::_inv[TABLE_SIZE + 1];
template <signed M, unsigned F>
mod_int<M, F> mod_int<M, F>::_fact[TABLE_SIZE + 1];
template <signed M, unsigned F>
mod_int<M, F> mod_int<M, F>::_inv_fact[TABLE_SIZE + 1];
template <signed M, unsigned F>
bool operator==(const mod_int<M, F> &lhs, const mod_int<M, F> &rhs) {
  return lhs.x == rhs.x;
}
template <long long M, unsigned F>
bool operator!=(const mod_int<M, F> &lhs, const mod_int<M, F> &rhs) {
  return !(lhs == rhs);
}
const signed MF = 1000010;
const signed MOD = 1000000007;
using mint = mod_int<MOD, MF>;
mint binom(long long n, long long r) {
  return (r < 0 || r > n || n < 0) ? 0 : mint(n).choose(r);
}
mint fact(long long n) { return mint(n).fact(); }
mint inv_fact(long long n) { return mint(n).inv_fact(); }
template <typename T, typename E>
struct SegmentTree {
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  typedef function<E(E, E)> H;
  typedef function<E(E, long long)> P;
  long long n;
  F f;
  G g;
  H h;
  P p;
  T d1;
  E d0;
  vector<T> dat;
  vector<E> laz;
  SegmentTree(
      long long n_, F f, G g, H h, T d1, E d0, vector<T> v = vector<T>(),
      P p = [](E a, long long b) { return a; })
      : f(f), g(g), h(h), d1(d1), d0(d0), p(p) {
    init(n_);
    if (n_ == (long long)v.size()) build(n_, v);
  }
  void init(long long n_) {
    n = 1;
    while (n < n_) n *= 2;
    dat.clear();
    dat.resize(2 * n - 1, d1);
    laz.clear();
    laz.resize(2 * n - 1, d0);
  }
  void build(long long n_, vector<T> v) {
    for (long long i = 0; i < n_; i++) dat[i + n - 1] = v[i];
    for (long long i = n - 2; i >= 0; i--)
      dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
  }
  inline void eval(long long len, long long k) {
    if (laz[k] == d0) return;
    if (k * 2 + 1 < n * 2 - 1) {
      laz[k * 2 + 1] = h(laz[k * 2 + 1], laz[k]);
      laz[k * 2 + 2] = h(laz[k * 2 + 2], laz[k]);
    }
    dat[k] = g(dat[k], p(laz[k], len));
    laz[k] = d0;
  }
  T update(long long a, long long b, E x, long long k, long long l,
           long long r) {
    eval(r - l, k);
    if (r <= a || b <= l) return dat[k];
    if (a <= l && r <= b) {
      laz[k] = h(laz[k], x);
      return g(dat[k], p(laz[k], r - l));
    }
    return dat[k] = f(update(a, b, x, k * 2 + 1, l, (l + r) / 2),
                      update(a, b, x, k * 2 + 2, (l + r) / 2, r));
  }
  T update(long long a, long long b, E x) { return update(a, b, x, 0, 0, n); }
  T query(long long a, long long b, long long k, long long l, long long r) {
    eval(r - l, k);
    if (r <= a || b <= l) return d1;
    if (a <= l && r <= b) return dat[k];
    T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return f(vl, vr);
  }
  T query(long long a, long long b) { return query(a, b, 0, 0, n); }
};
class compress {
 public:
  static const long long MAP = 10000000;
  map<long long, long long> zip;
  long long unzip[MAP];
  compress(vector<long long> &x) {
    sort(x.begin(), x.end());
    x.erase(unique(x.begin(), x.end()), x.end());
    for (long long i = 0; i < x.size(); i++) {
      zip[x[i]] = i;
      unzip[i] = x[i];
    }
  }
};
unsigned euclidean_gcd(unsigned a, unsigned b) {
  while (1) {
    if (a < b) swap(a, b);
    if (!b) break;
    a %= b;
  }
  return a;
}
long long nC2(long long n) { return n * (n - 1) / 2; }
long long s[2001], t[2001];
mint dp[2001][2001];
bool fix[2001][2001];
mint rec(long long i, long long j) {
  if (fix[i][j]) return dp[i][j];
  mint update = mint(0);
  if ((i - 1 >= 0 && j - 1 >= 0) && s[i] == t[j]) {
    update += rec(i - 1, j - 1);
  }
  if (i - 1 >= 0) update += rec(i - 1, j);
  if (j - 1 >= 0) update += rec(i, j - 1);
  if (i - 1 >= 0 && j - 1 >= 0) update -= rec(i - 1, j - 1);
  fix[i][j] = true;
  return dp[i][j] = update;
}
signed main() {
  dp[0][0] = mint(1);
  fix[0][0] = true;
  long long N, M;
  cin >> N >> M;
  for (long long i = 1; i <= (long long)(N); i++) cin >> s[i];
  for (long long i = 1; i <= (long long)(N); i++) cin >> t[i];
  cout << rec(N, M) << "\n";
  return 0;
}
