Problem:
Score : 1700 points

Problem Statement

You have two strings A = A_1 A_2 ... A_n and B = B_1 B_2 ... B_n of the same length consisting of 0 and 1.
The number of 1's in A and B is equal.

You've decided to transform A using the following algorithm:

Let a_1, a_2, ..., a_k be the indices of 1's in A.

Let b_1, b_2, ..., b_k be the indices of 1's in B.

Replace a and b with their random permutations, chosen independently and uniformly.

For each i from 1 to k, in order, swap A_{a_i} and A_{b_i}.

Let P be the probability that strings A and B become equal after the procedure above.

Let Z = P \times (k!)^2. Clearly, Z is an integer.

Find Z modulo 998244353.

Constraints

1 \leq |A| = |B| \leq 10,000

A and B consist of 0 and 1.

A and B contain the same number of 1's.

A and B contain at least one 1.

Partial Score

1200 points will be awarded for passing the testset satisfying 1 \leq |A| = |B| \leq 500.

Input

Input is given from Standard Input in the following format:

A
B

Output

Print the value of Z modulo 998244353.

Sample Input 1

1010
1100

Sample Output 1

3

After the first two steps, a = [1, 3] and b = [1, 2]. There are 4 possible scenarios after shuffling a and b:

a = [1, 3], b = [1, 2]. Initially, A = 1010. After swap(A_1, A_1), A = 1010. After swap(A_3, A_2), A = 1100.

a = [1, 3], b = [2, 1]. Initially, A = 1010. After swap(A_1, A_2), A = 0110. After swap(A_3, A_1), A = 1100.

a = [3, 1], b = [1, 2]. Initially, A = 1010. After swap(A_3, A_1), A = 1010. After swap(A_1, A_2), A = 0110.

a = [3, 1], b = [2, 1]. Initially, A = 1010. After swap(A_3, A_2), A = 1100. After swap(A_1, A_1), A = 1100.

Out of 4 scenarios, 3 of them result in A = B. Therefore, P = 3 / 4, and Z = 3.

Sample Input 2

01001
01001

Sample Output 2

4

No swap ever changes A, so we'll always have A = B.

Sample Input 3

101010
010101

Sample Output 3

36

Every possible sequence of three swaps puts the 1's in A into the right places.

Sample Input 4

1101011011110
0111101011101

Sample Output 4

932171449

Solution in C++ (GCC 5.4.1) (judge verdict: Accepted)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
char s[1<<16];
int a[1<<16],b[1<<16];
int f[1<<16][2];
const int MOD=998244353;
inline int add(int a,int b)
{a+=b;return a>=MOD?a-MOD:a;}
inline int sub(int a,int b)
{a-=b;return a<0?a+MOD:a;}
inline int mul(int a,int b)
{return 1LL*a*b%MOD;}
inline int ksm(int a,int b)
{
    int ans=1;
    for(;b;b>>=1,a=mul(a,a))
        if(b&1)ans=mul(ans,a);
    return ans;
}
int fac[1<<16],ifac[1<<16];
#define C(x,y) mul(fac[x],mul(ifac[x-y],ifac[y]))
int Deal(int n,int m)
{
    f[0][0]=1;
    for(int j=1;j<=m;j++){
        f[0][j&1]=mul(fac[j],fac[j]);
        for(int i=1;i<=n;i++)
            f[i][j&1]=add(mul(f[i-1][j&1],i*j),mul(f[i][j&1^1],j*j));
            //fij=fi-1j*i*j+fij-1*j^2
    }
    int als=0;
    for(int i=0;i<=n;i++)
        als=add(als,mul(f[n-i][m&1],mul(mul(fac[i],fac[i]),mul(C(n,i),C(n+m,i)))));
    return als;
}
int main()
{
    scanf("%s",s+1);
    int s1=0,s2=0,n=strlen(s+1);
    for(int i=1;i<=n;i++)
        a[i]=s[i]-'0';
    scanf("%s",s+1);
    for(int i=1;i<=n;i++)
        b[i]=s[i]-'0';
    for(int i=1;i<=n;i++)
        if(a[i]+b[i]==2)++s1;
        else if(a[i])++s2;
    fac[0]=ifac[0]=1;
    for(int i=1;i<=10000;i++)
        fac[i]=mul(fac[i-1],i);
    ifac[n]=ksm(fac[n],MOD-2);
    for(int i=n-1;i;--i)
        ifac[i]=mul(ifac[i+1],i+1);
    printf("%d",Deal(s1,s2));
    return 0;
}