Problem:
Score : 500 points

Problem Statement

You are given two integer sequences S and T of length N and M, respectively, both consisting of integers between 1 and 10^5 (inclusive).

In how many pairs of a subsequence of S and a subsequence of T do the two subsequences are the same in content?

Here the subsequence of A is a sequence obtained by removing zero or more elements from A and concatenating the remaining elements without changing the order.

For both S and T, we distinguish two subsequences if the sets of the indices of the removed elements are different, even if the subsequences are the same in content.

Since the answer can be tremendous, print the number modulo 10^9+7.

Constraints

1 \leq N, M \leq 2 \times 10^3

The length of S is N.

The length of T is M.

1 \leq S_i, T_i \leq 10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
S_1 S_2 ... S_{N-1} S_{N}
T_1 T_2 ... T_{M-1} T_{M}

Output

Print the number of pairs of a subsequence of S and a subsequence of T such that the subsequences are the same in content, modulo 10^9+7.

Sample Input 1

2 2
1 3
3 1

Sample Output 1

3

S has four subsequences: (), (1), (3), (1, 3).

T has four subsequences: (), (3), (1), (3, 1).

There are 1 \times 1 pair of subsequences in which the subsequences are both (), 1 \times 1 pair of subsequences in which the subsequences are both (1), and 1 \times 1 pair of subsequences in which the subsequences are both (3), for a total of three pairs.

Sample Input 2

2 2
1 1
1 1

Sample Output 2

6

S has four subsequences: (), (1), (1), (1, 1).

T has four subsequences: (), (1), (1), (1, 1).

There are 1 \times 1 pair of subsequences in which the subsequences are both (), 2 \times 2 pairs of subsequences in which the subsequences are both (1), and 1 \times 1 pair of subsequences in which the subsequences are both (1,1), for a total of six pairs.
Note again that we distinguish two subsequences if the sets of the indices of the removed elements are different, even if the subsequences are the same in content.

Sample Input 3

4 4
3 4 5 6
3 4 5 6

Sample Output 3

16

Sample Input 4

10 9
9 6 5 7 5 9 8 5 6 7
8 6 8 5 5 7 9 9 7

Sample Output 4

191

Sample Input 5

20 20
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Sample Output 5

846527861

Be sure to print the number modulo 10^9+7.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Numerics;
using static System.Math;
using static System.Array;
using static AtCoder.IO_ShortCut;
using static AtCoder.Tool;
namespace AtCoder
{
    class AC
    {
        const int MOD = 1000000007;
        //const int MOD = 998244353;
        const int INF = int.MaxValue / 2;
        const long SINF = long.MaxValue / 2;
        const double EPS = 1e-8;
        static readonly int[] dI = { 0, 1, 0, -1, 1, -1, -1, 1 };
        static readonly int[] dJ = { 1, 0, -1, 0, 1, 1, -1, -1 };
        static List<List<int>> G = new List<List<int>>();
        //static List<List<Edge>> G = new List<List<Edge>>();
        //static List<Edge> E = new List<Edge>();
        static void Main(string[] args)
        {
            //var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            //Console.SetOut(sw);

            int N, M;
            Input(out N, out M);
            var S = _ReadSplitInt;
            var T = _ReadSplitInt;

            var dp = new long[N + 1, M + 1];
            for (var i = 0; i <= N; i++) dp[i, 0] = 1;
            for (var j = 0; j <= M; j++) dp[0, j] = 1;

            for(var i = 0; i < N; i++)
            {
                for(var j = 0; j < M; j++)
                {
                    if (S[i] == T[j])
                    {
                        dp[i + 1, j + 1] = (dp[i, j + 1] + dp[i + 1, j]) % MOD;
                        dp[i + 1, j + 1] %= MOD;
                    }
                    else
                    {
                        dp[i + 1, j + 1] = (dp[i, j + 1] + dp[i + 1, j] - dp[i, j] + MOD) % MOD;
                        dp[i + 1, j + 1] %= MOD;
                    }
                }
            }
            OutL(dp[N, M]);
            

            //Console.Out.Flush();
        }
        struct Edge
        {
            public int from;

            public int to;
            public long dist;
            public Edge(int t, long c)
            {
                from = -1;
                to = t;
                dist = c;
            }
            public Edge(int f, int t, long c)
            {
                from = f;
                to = t;
                dist = c;
            }
        }
    }
    static class IO_ShortCut
    {
        public static string[] _ReadSplit => Console.ReadLine().Split();
        public static int[] _ReadSplitInt => ConvertAll(Console.ReadLine().Split(), int.Parse);
        public static long[] _ReadSplitLong => ConvertAll(Console.ReadLine().Split(), long.Parse);
        public static double[] _ReadSplit_Double => ConvertAll(Console.ReadLine().Split(), double.Parse);
        public static string Str => Console.ReadLine();
        public static int Int => int.Parse(Console.ReadLine());
        public static long Long => long.Parse(Console.ReadLine());
        public static double Double => double.Parse(Console.ReadLine());
        public static T Conv<T>(string input) => (T)Convert.ChangeType(input, typeof(T));
        public static void Input<T>(out T a) => a = Conv<T>(Console.ReadLine());
        public static void Input<T, U>(out T a, out U b)
        { var q = _ReadSplit;a = Conv<T>(q[0]);b = Conv<U>(q[1]); }
        public static void Input<T, U, V>(out T a, out U b, out V c)
        { var q = _ReadSplit;a = Conv<T>(q[0]);b = Conv<U>(q[1]);c = Conv<V>(q[2]); }
        public static void Input<T, U, V, W>(out T a, out U b, out V c, out W d)
        { var q = _ReadSplit; a = Conv<T>(q[0]); b = Conv<U>(q[1]); c = Conv<V>(q[2]);d = Conv<W>(q[3]); }

        public static void OutL(object s) => Console.WriteLine(s);
        public static void Out_Sep<T>(IEnumerable<T> s) => Console.WriteLine(string.Join(" ", s));
        public static void Out_Sep<T>(IEnumerable<T> s, string sep) => Console.WriteLine(string.Join($"{sep}", s));
        public static void Out_Sep(params object[] s) => Console.WriteLine(string.Join(" ", s));
        public static void Out_One(object s) => Console.Write($"{s} ");
        public static void Out_One(object s, string sep) => Console.Write($"{s}{sep}");
        public static void Endl() => Console.WriteLine();
    }
    public static class Tool
    {
        static public void Initialize<T>(ref T[] array, T initialvalue)
        {
            array = ConvertAll(array, x => initialvalue);
        }
        static public void Swap<T>(ref T a, ref T b)
        {
            T keep = a;
            a = b;
            b = keep;
        }
        static public void Display<T>(T[,] array2d, int n, int m)
        {
            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < m; j++)
                {
                    Console.Write($"{array2d[i, j]} ");
                }
                Console.WriteLine();
            }
        }
        static public long LPow(int a, int b) => (long)Pow(a, b);
        static public bool Bit(long x, int dig) => ((1L << dig) & x) != 0;
    }
    class Modulo
    {
        private int M;
        private readonly long[] m_facs;
        public long Mul(long a, long b)
        {
            return ((a * b) % M);
        }
        public Modulo(long n, int m)
        {
            M = m;
            m_facs = new long[n + 1];
            m_facs[0] = 1;
            for (long i = 1; i <= n; ++i)
            {
                m_facs[i] = Mul(m_facs[i - 1], i);
            }
        }
        public long Fac(long n)
        {
            return m_facs[n];
        }
        public long Pow(long a, long m)
        {
            switch (m)
            {
                case 0:
                    return 1L;
                case 1:
                    return a;
                default:
                    long p1 = Pow(a, m / 2);
                    long p2 = Mul(p1, p1);
                    return ((m % 2) == 0) ? p2 : Mul(p2, a);
            }
        }
        public long Div(long a, long b)
        {
            return Mul(a, Pow(b, M - 2));
        }
        public long Ncr(long n, long r)
        {
            if (n < r) { return 0; }
            if (n == r) { return 1; }
            long res = Fac(n);
            res = Div(res, Fac(r));
            res = Div(res, Fac(n - r));
            return res;
        }
    }
}