1002-Add or Multiply 1
第二类斯特林数,预处理
//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9+7, M = 1000002;
int fa[1010];
ll f[M],s2[3030][3030];
inline int read() {
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline string readstring() {
string str;
char s=getchar();
while(s==' '||s=='\n'||s=='\r'){s=getchar();}
while(s!=' '&&s!='\n'&&s!='\r'){str+=s;s=getchar();}
return str;
}
int Find(int x) {
if(fa[x] == x) return x;
return fa[x] = Find(fa[x]);
}
void init()
{
f[0] = 1;
for(int i=1; i<1000002; i++) {
f[i] = f[i-1] * i % mod;
}
s2[1][1] = 1;
for(int i=2; i<3005; i++) {
for(int j=1; j<3005; j++) {
s2[i][j] = (s2[i-1][j-1] + j * s2[i-1][j]) % mod;
}
}
}
int main()
{
init();
int pp = read();
while(pp--)
{
int n,k;
ll z = 0;
scanf("%lld %lld",&n,&k);
for(int j=0; j<=min(n,k); j++)
{
z = (z + f[j]*f[j]%mod * s2[n+1][j+1]%mod * s2[k+1][j+1]%mod) % mod;
z %= mod;
z += mod;
z %= mod;
}
printf("%lld\n",z);
}
return 0;
}