#include<bits/stdc++.h>
#define REP(i,n) for(int i = 0; i < n; ++i)
#define REPR(i,n) for(int i = n; i >= 0; --i)
#define FOR(i,a,b) for(int i = (a); i < (b); ++i)
#define FORR(i, a, b) for(int i = b-1;i >= a;--i)
#define p(s) cout << (s) << endl
#define p2(s,t) cout << (s) << " " << (t) << endl 
#define ALL(v) (v).begin(), (v).end()
#define m0(x) memset(x,0,sizeof(x))
typedef long long ll;

using namespace std;

static const ll MOD  = 1e9 + 7;
static const ll INF  = 1e18;

static const int White = 0;
static const int Gray = 1;
static const int Black = 2;

void pvector(vector<int> A){
    cout << "[vector]";
    for(int i = 0; i < A.size(); i++){
        cout << A[i] << " ";
    }
    cout << endl;
}

static const int MAXS = 100001;
static const int MAXN = 2100;

// 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;
    }
};
using mint = Fp<MOD>;

int main(){
    int N, M;
    cin >> N >> M;
    vector<ll> S(N), T(M);
    mint dp[MAXN][MAXN] = {0};
    mint sdp[MAXN][MAXN] = {0};
    //dp[i][j]:=Sのi文字目とTのj文字目が同じ時のその文字を含む部分文字列の数(違うときは0)
    //sdp[i][j]:= sum(0<=x<i,0<=y<j)dp[x][y]
    REP(i,N){
        cin >> S[i];
    }
    REP(i,M){
        cin >> T[i];
    }
    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: 69248