use std::io::prelude::*;

fn input<T: std::str::FromStr>() -> T {
    let stdin = std::io::stdin();
    let token: String = stdin
        .lock()
        .bytes()
        .map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().unwrap()
}

fn main() {
    let n: usize = input();
    let m: usize = input();
    let s: Vec<i32> = (0..n).map(|_| input()).collect();
    let t: Vec<i32> = (0..m).map(|_| input()).collect();
    const MOD: i64 = 1000000007;

    set_mod(MOD);

    let mut dp = vec![vec![ModInt(0); m + 1]; n + 1];
    let mut sum = vec![vec![ModInt(0); m + 1]; n + 1];
    for i in 1..n + 1 {
        for j in 1..m + 1 {
            if s[i - 1] == t[j - 1] {
                dp[i][j] = sum[i - 1][j - 1] + 1;
            }
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + dp[i][j];
        }
    }

    println!("{}", sum[n][m] + 1);
}

thread_local!(static MOD: std::cell::Cell<i64> = Default::default());

fn get_mod() -> i64 {
    MOD.with(|m| m.get())
}

fn set_mod(x: i64) {
    MOD.with(|m| m.set(x))
}

#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct ModInt(i64);

impl std::fmt::Display for ModInt {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl std::ops::Add for ModInt {
    type Output = ModInt;
    fn add(self, other: ModInt) -> ModInt {
        let m = get_mod();
        let x = (self.0 % m + other.0 % m) % m;
        ModInt(x)
    }
}

impl<T: Into<i64>> std::ops::Add<T> for ModInt {
    type Output = ModInt;
    fn add(self, other: T) -> ModInt {
        let m = get_mod();
        let x = (self.0 % m + other.into() % m) % m;
        ModInt(x)
    }
}

impl std::ops::AddAssign for ModInt {
    fn add_assign(&mut self, other: ModInt) {
        let m = get_mod();
        let x = (self.0 % m + other.0 % m) % m;
        self.0 = x;
    }
}

impl<T: Into<i64>> std::ops::AddAssign<T> for ModInt {
    fn add_assign(&mut self, other: T) {
        let m = get_mod();
        let x = (self.0 % m + other.into() % m) % m;
        self.0 = x;
    }
}

impl std::ops::Mul for ModInt {
    type Output = ModInt;
    fn mul(self, other: ModInt) -> ModInt {
        let m = get_mod();
        let x = self.0 % m * (other.0 % m) % m;
        ModInt(x)
    }
}

impl<T: Into<i64>> std::ops::Mul<T> for ModInt {
    type Output = ModInt;
    fn mul(self, other: T) -> ModInt {
        let m = get_mod();
        let x = self.0 % m * (other.into() % m) % m;
        ModInt(x)
    }
}

impl std::ops::MulAssign for ModInt {
    fn mul_assign(&mut self, other: ModInt) {
        let m = get_mod();
        let x = self.0 % m * (other.0 % m) % m;
        self.0 = x;
    }
}

impl<T: Into<i64>> std::ops::MulAssign<T> for ModInt {
    fn mul_assign(&mut self, other: T) {
        let m = get_mod();
        let x = self.0 % m * (other.into() % m) % m;
        self.0 = x;
    }
}

impl std::ops::Sub for ModInt {
    type Output = ModInt;
    fn sub(self, other: ModInt) -> ModInt {
        let m = get_mod();
        let x = (self.0 % m + m - other.0 % m) % m;
        ModInt(x)
    }
}

impl<T: Into<i64>> std::ops::Sub<T> for ModInt {
    type Output = ModInt;
    fn sub(self, other: T) -> ModInt {
        let m = get_mod();
        let x = (self.0 % m + m - other.into() % m) % m;
        ModInt(x)
    }
}

impl std::ops::SubAssign for ModInt {
    fn sub_assign(&mut self, other: ModInt) {
        let m = get_mod();
        let x = (self.0 % m + m - other.0 % m) % m;
        self.0 = x;
    }
}

impl<T: Into<i64>> std::ops::SubAssign<T> for ModInt {
    fn sub_assign(&mut self, other: T) {
        let m = get_mod();
        let x = (self.0 % m + m - other.into() % m) % m;
        self.0 = x;
    }
}


Measured memory_bytes: 86268