#include <bits/stdc++.h>
using namespace std;

#define int long long
#pragma GCC optimize ("O3")
#define ll long long
#define vi vector <int>
#define vii vector <pair<int,int> >
#define rep(i,a,b) for (int i=a;i<b;i++)
#define repD(i,a,b) for (int i=a;i>b;i--)
#define pb push_back
#define pii pair <int,int>
#define ff first
#define ss second
#define all(a) a.begin(),a.end()
#define MOD 1000000007
#define PI 3.14159265359


/*#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/trie_policy.hpp>

using namespace __gnu_pbds;
typedef tree<pii,null_type,less <pii>,rb_tree_tag,tree_order_statistics_node_update>ind_set;
*/
///*X.find_by_order("index")
///X.order_of_key("key")



#define deb(x) cerr<<#x<< " : " <<x<<"\n";
#ifndef local
	#define deb(x) ;
#endif
///----------------------------------------------------------------------------------

int n,m,s[2005],t[2005];
int DP[2005][2005];
vi ind[100005];
int fun(int i,int j=2003)
{
	//cout<<i<<" "<<j<<"\n";
	if (i==n)return 1;
	if (DP[i][j]!=-1)return DP[i][j];

	int ret=fun(i+1,j);//no Take
	int nj=j;
	if (nj==2003)nj=-1;
	nj=upper_bound(all(ind[s[i]]),nj)-ind[s[i]].begin();
	///cout<<nj<<" ";
	while (nj<ind[s[i]].size()) ret = (ret+fun(i+1,ind[s[i]][nj++]))%MOD;

	return DP[i][j]=ret;



}

void solve()
{

	cin>>n>>m;rep(i,0,n)cin>>s[i];
	///n=2000,m=2000;rep(i,0,n)s[i]=1;rep(i,0,m)t[i]=1,ind[t[i]].pb(i);
	rep(i,0,m)cin>>t[i],ind[t[i]].pb(i);

	bool sho=true,lo=true;
	rep(i,1,n)if (s[i]!=s[0]){sho=false;break;};
	rep(i,1,m)if (t[i]!=t[0]){lo=false;break;}

	if (sho && lo && s[0]==t[0)
	{
		memset(DP,0,sizeof DP);

		rep(i,0,2003)DP[i][0]=1,DP[i][i]=1;
		DP[0][0]=1;
	    rep(i,1,2003)
	    {
	        rep(j,1,i)
				DP[i][j] = (DP[i-1][j] + DP[i-1][j-1])%MOD;
	    }
		int ret=0,lim=min(n,m)+1;
		rep(i,0,lim)ret=(ret+(DP[n][i]*DP[m][i])%MOD)%MOD;
		cout<<ret<<"\n";
	    return;

	}
	else if (sho&&lo)
	{
		cout<<1;
		return;
	}
	else
	{
		if (sho)
		{
			memset(DP,0,sizeof DP);

			rep(i,0,2003)DP[i][0]=1,DP[i][i]=1;
			DP[0][0]=1;
		    rep(i,1,2003)
		    {
		        rep(j,1,i)
					DP[i][j] = (DP[i-1][j] + DP[i-1][j-1])%MOD;
		    }
			int ret=0,lim=min(n,(int)ind[s[0]].size())+1;
			rep(i,0,lim)ret=(ret+(DP[n][i]*DP[m][i])%MOD)%MOD;
			cout<<ret<<"\n";
		    return;
		}
		else if (lo)
		{
			rep(i,0,100005)ind[i].clear();
			rep(i,0,n)ind[s[i]].pb(i);

			memset(DP,0,sizeof DP);

			rep(i,0,2003)DP[i][0]=1,DP[i][i]=1;
			DP[0][0]=1;
		    rep(i,1,2003)
		    {
		        rep(j,1,i)
					DP[i][j] = (DP[i-1][j] + DP[i-1][j-1])%MOD;
		    }
			int ret=0,lim=min(m,(int)ind[t[0]].size())+1;
			rep(i,0,lim)ret=(ret+(DP[n][i]*DP[m][i])%MOD)%MOD;
			cout<<ret<<"\n";
		    return;

		}
	}

	memset(DP,-1,sizeof DP);
	cout<<"0";
	cout<<fun(0)<<"\n";

}

signed main()
{
    ios_base::sync_with_stdio(false);cin.tie(NULL);

    #ifdef local
    freopen("input.txt","r",stdin);
    ///freopen("output.txt","w",stdout);
    #endif

    clock_t qwertyuiop = clock();
    int t=1;
    ///cin>>t;
    rep(a,0,t)
    {
        ///cout<<"DPase #"<<a+1<<": ";
        solve();
    }
    #ifdef local
	{qwertyuiop = clock() - qwertyuiop;double time_taken = ((double)qwertyuiop)/CLOCKS_PER_SEC;cerr<<fixed<<setprecision(5)<<"\n\nTime Taken : "<<time_taken<<" seconds\n";}
	#endif
}
