#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;

#define REP(i, n) for(long long i = 0; i < (n); i++)
#define FOR(i, m, n) for(long long i = (m);i < (n); ++i)
#define ALL(obj) (obj).begin(),(obj).end()
#define SPEED cin.tie(0);ios::sync_with_stdio(false);

template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;

constexpr ll MOD = (ll) 1e9 + 7;
const ll MOD2 = 998244353;
const ll HIGHINF = (ll) 1e18;
const ll LOWINF = (ll) 1e15;
const long double PI = 3.1415926535897932384626433;

template<typename T> vector<T> make_v(size_t N, T init) { return vector<T>(N, init); }
template<typename... T> auto make_v(size_t N, T... t) { return vector<decltype(make_v(t...))>(N, make_v(t...)); }
template<class T> void corner(bool flg, T hoge) {
    if (flg) {
        cout << hoge << endl;
        exit(0);
    }
}
template<class T, class U> ostream &operator<<(ostream &o, const map<T, U> &obj) {
    o << "{";
    for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ",";
    o << " }";
    return o;
}
template<class T> ostream &operator<<(ostream &o, const set<T> &obj) {
    o << "{";
    for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr;
    o << "}";
    return o;
}
template<class T> ostream &operator<<(ostream &o, const multiset<T> &obj) {
    o << "{";
    for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr;
    o << "}";
    return o;
}
template<class T> ostream &operator<<(ostream &o, const vector<T> &obj) {
    o << "{";
    for (int i = 0; i < (int) obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i];
    o << "}";
    return o;
}
template<class T, class U> ostream &operator<<(ostream &o, const pair<T, U> &obj) {
    o << "{" << obj.first << ", " << obj.second << "}";
    return o;
}
template<template<class tmp> class T, class U> ostream &operator<<(ostream &o, const T<U> &obj) {
    o << "{";
    for (auto itr = obj.begin(); itr != obj.end(); ++itr)o << (itr != obj.begin() ? ", " : "") << *itr;
    o << "}";
    return o;
}
void print(void) { cout << endl; }
template<class Head> void print(Head &&head) {
    cout << head;
    print();
}
template<class Head, class... Tail> void print(Head &&head, Tail &&... tail) {
    cout << head << " ";
    print(forward<Tail>(tail)...);
}
template<class T> void chmax(T &a, const T b) { a = max<T>(a, b); }
template<class T> void chmin(T &a, const T b) { a = min<T>(a, b); }
void YN(bool flg) { cout << ((flg) ? "YES" : "NO") << endl; }
void Yn(bool flg) { cout << ((flg) ? "Yes" : "No") << endl; }
void yn(bool flg) { cout << ((flg) ? "yes" : "no") << endl; }

class BinaryIndexedTree2DRangeModSumQuery {
public:
    const int N, M;
    const long long mod;
    vector<vector<long long>> bit;

    //1-indexed
    BinaryIndexedTree2DRangeModSumQuery(const int &N, const int &M, const long long &mod) : N(N), M(M), mod(mod), bit(N + 1, vector<long long>(M + 1, 0)) {
        // do nothing
    }

    long long getvar(const int &i, const int &j) {
        long long val = 0;
        for (int y = i; y > 0; y -= (y & -y))
            for (int x = j; x > 0; x -= (x & -x)) {
                val += bit[y][x];
                if (val >= mod) val -= mod;
            }
        return val;
    }

    // [x1,x2] * [y1,y2] 1-indexed
    long long getvar(const int &y1, const int &y2, const int &x1, const int &x2) {
        long long res = getvar(y1 - 1, x1 - 1);
        res -= getvar(y1 - 1, x2);
        if (res < 0) res += mod;
        res -= getvar(y2, x1 - 1);
        if (res < 0) res += mod;
        res += getvar(y2, x2);
        if (res >= mod) res -= mod;
        return res;
    }

    //add
    void update(const int &i, const int &j, long long val) {
        if (i == 0 || j == 0) return;
        if (val >= mod) val -= mod;
        if (val < 0) val += mod;
        for (int y = i; y <= N; y += (y & -y))
            for (int x = j; x <= M; x += (x & -x)) {
                bit[y][x] += val;
                if (bit[y][x] >= mod) bit[y][x] -= mod;
            }
    }

};


int main() {
    SPEED
    ll N, M;
    cin >> N >> M;
    V<ll> S(N + 1, 0);
    for (int i = 1; i <= N; ++i) cin >> S[i];

    V<ll> T(M + 1, 0);
    for (int i = 1; i <= M; ++i) cin >> T[i];

    BinaryIndexedTree2DRangeModSumQuery bit(N, M, MOD);
//    for(int i = 1; i <= N; ++i){
//        for(int j = 1; j <= M; ++j){
//            bit.update(i,j,(S[i]==T[j]));
//        }
//    }

    ll ans = 1;
    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= M; ++j) {
            if (S[i] != T[j]) continue;
            ll val = bit.getvar(1, i - 1, 1, j - 1);
            (ans += (val + 1)) %= MOD;
            bit.update(i, j, val + 1);
        }
    }

    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 31616