CodeEff/ECCO huggingface dataset:
# Original solution
import bisect
N,Q = list(map(int, input().split()))
L = [0]*Q
L1 = []
L2 = []
for i in range(Q):
    a,b = list(map(int, input().split()))
    L[i] = (a, b)
    if a == 1:
        L1.append(b)
    else:
        L2.append(b)

L1.sort()
L2.sort()

ans = (N-2)**2
up = N
left = N
for l in L:
    a = l[0]
    b = l[1]
    if a == 1:
        if b > left:
            continue
        idx = bisect.bisect_left(L1, b)
        ans -= (len(L1)-idx)*(up-2)
        L1 = L1[:idx]
        left = b
    else:
        if b > up:
            continue
        idx = bisect.bisect_left(L2, b)
        ans -= (len(L2)-idx)*(left-2)
        L2 = L2[:idx]
        up = b
print(ans)

# Optimized solution
import bisect
N,Q = list(map(int, input().split()))
L = [0]*Q
L1 = []
L2 = []
for i in range(Q):
    a,b = list(map(int, input().split()))
    L[i] = (a, b)
    if a == 1:
        L1.append(b)
    else:
        L2.append(b)

L1.sort()
L2.sort()
M1 = len(L1)
M2 = len(L2)
ans = (N-2)**2
up = N
left = N
for l in L:
    a = l[0]
    b = l[1]
    if a == 1:
        if b > left:
            continue
        idx = bisect.bisect_left(L1, b)
        ans -= (M1-idx)*(up-2)
        M1 = idx
        left = b
    else:
        if b > up:
            continue
        idx = bisect.bisect_left(L2, b)
        ans -= (M2-idx)*(left-2)
        M2 = idx
        up = b
print(ans)
# Original solution
#editorial
n,q=list(map(int,input().split()))
*qu,=[tuple(map(int, input().split())) for _ in range(q)]
w=n-2;h=n-2
wwh=[n-2]*(n-2)
hhw=[n-2]*(n-2)
b=0
for t,x in qu:
    if t==1:
        x-=2
        b+=wwh[x]
        if x<w:
            for i in range(h):
                hhw[i]=x
            w=x

    else:
        x-=2
        b+=hhw[x]
        if x<h:
            for i in range(w):
                wwh[i]=x
            h=x
    
    ans=(n-2)*(n-2)-b
#    print(wwh)
#    print(hhw)
#    print(h,w)

ans=(n-2)*(n-2)-b
print(ans)
    


# Optimized solution
#editorial
n,q=list(map(int,input().split()))
*qu,=[tuple(map(int, input().split())) for _ in range(q)]
w=n-2;h=n-2
wwh=[n-2]*(n-2)
hhw=[n-2]*(n-2)
b=0
for t,x in qu:
    x-=2
    if t==1:
        
        if x<w:
            b+=h
            for i in range(x,w):
                wwh[i]=h
            w=x
        else:
            b+=wwh[x]

    else:
        if x<h:
            b+=w
            for i in range(x,h):
                hhw[i]=w
            h=x
        else:
            b+=hhw[x]

ans=(n-2)*(n-2)-b
print(ans)
# Original solution
N, Q = list(map(int, input().split()))
rcx = [tuple(map(int, input().split())) for _ in range(Q)]

thres_1, thres_2 = N, N
nearest_white_1 = [N] * N
nearest_white_2 = [N] * N

reverse_count = 0
for rc, x in rcx:
    if rc == 1:
        if x < thres_1:
            reverse_count += thres_2 - 2
            for i in range(1, thres_2):
                nearest_white_2[i] = x
            thres_1 = x
        else:
            reverse_count += nearest_white_1[x] - 2
    else:
        if x < thres_2:
            reverse_count += thres_1 - 2
            for i in range(1, thres_1):
                nearest_white_1[i] = x
            thres_2 = x
        else:
            reverse_count += nearest_white_2[x] - 2

    #print(reverse_count)
    #print(f"thres1:{thres_1} {nearest_white_1}")
    #print(f"thres2:{thres_2} {nearest_white_2}")
    #print('-'*20)

print(((N-2)**2 - reverse_count))

# Optimized solution
N, Q = list(map(int, input().split()))
rcx = [tuple(map(int, input().split())) for _ in range(Q)]

thres_1, thres_2 = N-2, N-2
nearest_white_1 = [0] * (N-2)
nearest_white_2 = [0] * (N-2)

reverse_count = 0
for rc, x in rcx:
    x = x-2
    if rc == 1:
        if x < thres_1:
            for i in range(x+1, thres_1):
                nearest_white_1[i] = thres_2
            thres_1 = x
            reverse_count += thres_2
        else:
            reverse_count += nearest_white_1[x]
    else:
        if x < thres_2:
            for i in range(x+1, thres_2):
                nearest_white_2[i] = thres_1
            reverse_count += thres_1
            thres_2 = x
        else:
            reverse_count += nearest_white_2[x]

    #print(reverse_count)
    #print(f"thres1:{thres_1} {nearest_white_1}")
    #print(f"thres2:{thres_2} {nearest_white_2}")
    #print('-'*20)

print(((N-2)**2 - reverse_count))
# Original solution
f=lambda:list(map(int,input().split()))
N,Q=f()
a,b=N,N
black=(N-2)*(N-2)
B=[-1]*(N+1)
W=[-1]*(N+1)
for _ in range(Q):
    q,x=f()
    if q==1:
        if B[x]>0:
            black-=B[x]
            B[x]=0
        else:
            black-=b-2
            a=x
            for j in range(a+1,N+1):
                if B[j]==-1:
                    B[j]=b-2
                if j==N-1:
                    break
    else:
        if W[x]>0:
            black-=W[x]
            W[x]=0
        else:
            black-=a-2
            b=x
            for j in range(b+1,N+1):
                if W[j]==-1:
                    W[j]=a-2
                else:
                    break
                if j==N-1:
                    break
print(black)

# Optimized solution
f=lambda:list(map(int,input().split()))
N,Q=f()
a,b=N,N
black=(N-2)*(N-2)
B=[-1]*(N+1)
W=[-1]*(N+1)
for _ in range(Q):
    q,x=f()
    if q==1:
        if B[x]>0:
            black-=B[x]
            B[x]=0
        else:
            black-=b-2
            a=x
            for j in range(a+1,N+1):
                if B[j]==-1:
                    B[j]=b-2
                else:
                    break
                if j==N-1:
                    break
    else:
        if W[x]>0:
            black-=W[x]
            W[x]=0
        else:
            black-=a-2
            b=x
            for j in range(b+1,N+1):
                if W[j]==-1:
                    W[j]=a-2
                else:
                    break
                if j==N-1:
                    break
print(black)
# Original solution
N, Q = list(map(int, input().split()))
q = [0] * Q
for i in range(Q):
    q[i] = list(map(int, input().split()))

ans = (N - 2) ** 2

b1 = [N-2] * (N-2)
b2 = [N-2] * (N-2)

for i in range(Q):
    x = q[i][1] - 2
    if q[i][0] == 1:
        ans -= b1[x]
        for j in range(b1[x]):
            b2[j] = min(b2[j], x)
        b1[x] = 0
    else:
        ans -= b2[x]
        for j in range(b2[x]):
            b1[j] = min(b1[j], x)
        b2[x] = 0

print(ans)

# Optimized solution
N, Q = list(map(int, input().split()))
q = [0] * Q
for i in range(Q):
    q[i] = list(map(int, input().split()))

ans = (N - 2) ** 2

b1 = [0] * (N-2)
b2 = [0] * (N-2)
l = N-2
u = N-2

for i in range(Q):
    x = q[i][1] - 2
    if q[i][0] == 1:
        if x < l:
            ans -= u
            for j in range(x+1, l):
                b2[j] = u
            l = x
        else:
            ans -= b2[x]
        #b1[x] = 0
    else:
        if x < u:
            ans -= l
            for j in range(x+1, u):
                b1[j] = l
            u = x
        else:
            ans -= b1[x]
        #b1[x] = 0

print(ans)
# Original solution
from collections import deque
import sys
N,M=list(map(int,input().split()))
table=[[] for i in range(N)]
ans=[]
for i in range(M):
    a,b,c=list(map(int,input().split()))
    table[a-1].append((b-1,c))
    table[b-1].append((a-1,c))
    ans.append((a-1,b-1,c))
h=deque()
inf=-10**13
h.append(0)
flag=True
visit=[(inf,0)]*N
visit[0]=(0,0)
tree=[]
while h:
    x=h.popleft()
    for y,d in table[x]:
        if visit[y][0]!=inf and visit[y][1]==visit[x][1]:
            flag =False
            tree.append((x,y,d))
        elif visit[y][0]!=inf:
            if (visit[x][0]+visit[y][0])!=d:
                print((0))
                sys.exit()
        if visit[y][0]==inf:
            t=(visit[x][1]+1)%2
            visit[y]=(d-visit[x][0],t)
            h.append(y)
if flag:
    mi=-inf
    ma=-inf
    for i in range(N):
        if visit[i][1]==0:
            mi=min(mi,visit[i][0])
        else:
            ma=min(ma,visit[i][0])
    print((max(0,ma+mi-1)))
    sys.exit()
a,b,c=tree[0]
s=visit[a][1]
t=visit[a][0]+visit[b][0]
w=(c-t)//2
for i in range(N):
    if visit[i][1]==s:
        x=visit[i][0]
        visit[i]=(x+w,s)
    else:
        x=visit[i][0]
        visit[i]=(x-w,(s+1)%2)
for x,y,d in ans:
    if (visit[x][0]+visit[y][0])!=d:
        print((0))
        sys.exit()
for i in range(N):
    if visit[i][0]<=0:
        print((0))
        sys.exit()
print((1))

# Optimized solution
import sys
from collections import deque
N,M=list(map(int,input().split()))
table=[[] for i in range(N)]
for i in range(M):
    u,v,s=list(map(int,input().split()))
    table[u-1].append((v-1,s))
    table[v-1].append((u-1,s))
L=[0]*N
T=[1]*N#checker
visit=[False]*N
h=deque()
h.append([0,1])
visit[0]=True
flag=True

K=[]

while h:
    x,t=h.popleft()
    for y,s in table[x]:
        if visit[y]:
            if T[y]==T[x]:
                flag=False
                K.append((x,y,s))
            else:
                if L[y]+L[x]!=s:
                    print((0))
                    sys.exit()
            continue
        T[y]=-t
        visit[y]=True
        L[y]=s-L[x]
        h.append([y,-t])
    
    
if not flag:
    x,y,s=K[0]
    t=T[x]
    u=L[x]+L[y]-s
    if u%2!=0:
        print((0))
        sys.exit()
    u=u//2
    for i in range(N):
        if T[i]==t:
            L[i]-=u
        else:
            L[i]+=u
    for x,y,s in K:
        if L[x]+L[y]!=s:
            print((0))
            sys.exit()
    for i in range(N):
        if L[i]<=0:
            print((0))
            sys.exit()
    print((1))
    sys.exit()
a=10**13
c=10**13
#b=-10**13
#d=-10**13
for i in range(N):
    if T[i]==1:
        a=min(a,L[i])
        #b=max(b,L[i])
    else:
        c=min(c,L[i])
        #d=max(d,L[i])
print((max(0,c+a-1)))
# Original solution
MOD = 10**9 + 7
n, oddness = [int(item) for item in input().split()]
# Oddness must be even
if oddness % 2 ==  1:
    print((0))
    exit()
oddness //= 2
max_oddness = 1300 + n
max_pending = n + 1

dp = [[[0] * (max_oddness) for _ in range(max_pending)] for _ in range(n)]
dp[0][0][0] = 1
dp[0][1][1] = 1
for i in range(1, n):
    for j in range(i+1):
        # Too many pending items 
        if j > n // 2:
            break
        for k in range(1300):
            # Connect in line
            # Oddness increase by num of pending item
            dp[i][j][k+j] += dp[i-1][j][k]
            # Choose 1 from pending items
            dp[i][j][k+j] += dp[i-1][j][k] * j*2 
            dp[i][j][k+j] %= MOD
            # Choose 2 from pending items
            if j > 0:
                dp[i][j-1][k+j-1] += dp[i-1][j][k] * j*j
                dp[i][j-1][k+j-1] %= MOD 
            # Do nothing 
            dp[i][j+1][k+j+1] += dp[i-1][j][k] 
            dp[i][j+1][k+j+1] %= MOD 

print((dp[n-1][0][oddness]))

# Optimized solution
MOD = 10**9 + 7
n, oddness = [int(item) for item in input().split()]
# Oddness must be even
if oddness % 2 ==  1:
    print((0))
    exit()
oddness //= 2
max_oddness = 1300 + n
max_pending = n//2 + 2

dp = [[[0] * (max_oddness) for _ in range(max_pending)] for _ in range(n)]
dp[0][0][0] = 1
dp[0][1][1] = 1
for i in range(1, n):
    for j in range(min(i+1, max_pending-1)):
        for k in range(oddness+1):
            dp_ijk = dp[i-1][j][k]
            # Oddness increase by num of pending item
            # Connect in line or Choose 1 from pending items
            dp[i][j][k+j] += dp_ijk * (1 + j*2)
            dp[i][j][k+j] %= MOD
            # Choose 2 from pending items
            if j > 0:
                dp[i][j-1][k+j-1] += dp_ijk * j*j
            # Do nothing 
            dp[i][j+1][k+j+1] += dp_ijk 

print((dp[n-1][0][oddness] % MOD))
# Original solution
MOD = 10**9 + 7
n, oddness = [int(item) for item in input().split()]
# Oddness must be even
if oddness % 2 ==  1:
    print((0))
    exit()
oddness //= 2
max_oddness = 1250 + n
max_pending = n//2 + 2

dp = [[[0] * (max_oddness) for _ in range(max_pending)] for _ in range(n)]
dp[0][0][0] = 1
dp[0][1][1] = 1
for i in range(1, n):
    for j in range(min(i+1, n//2+1)):
        for k in range(oddness+1):
            # Oddness increase by num of pending item
            # Connect in line 
            dp[i][j][k+j] += dp[i-1][j][k]
            # Choose 1 from pending items
            dp[i][j][k+j] += dp[i-1][j][k] * j * 2
            dp[i][j][k+j] %= MOD
            # Choose 2 from pending items
            if j > 0:
                dp[i][j-1][k+j-1] += dp[i-1][j][k] * j*j
            # Do nothing 
            dp[i][j+1][k+j+1] += dp[i-1][j][k] 

print((dp[n-1][0][oddness] % MOD))

# Optimized solution
MOD = 10**9 + 7
n, oddness = [int(item) for item in input().split()]
# Oddness must be even
if oddness % 2 ==  1:
    print((0))
    exit()
oddness //= 2
max_oddness = 1250 + n
max_pending = n//2 + 2

dp = [[[0] * (max_oddness) for _ in range(max_pending)] for _ in range(n)]
dp[0][0][0] = 1
dp[0][1][1] = 1
for i in range(1, n):
    for j in range(min(i+1, n//2+1)):
        for k in range(oddness+1):
            dp_ijk_prev = dp[i-1][j][k]
            # Oddness increase by num of pending item
            # Do not connect
            dp[i][j+1][k+j+1] += dp_ijk_prev 
            # Choose 2 from pending items
            if j > 0:
                dp[i][j-1][k+j-1] += dp_ijk_prev * j*j
            # Connect in line 
            dp[i][j][k+j] += dp_ijk_prev
            # Choose 1 from pending items
            dp[i][j][k+j] += dp_ijk_prev * j * 2
            dp[i][j][k+j] %= MOD

print((dp[n-1][0][oddness] % MOD))
# Original solution
n, k = list(map(int, input().split()))
md = 10 ** 9 + 7
if k % 2:
    print((0))
    exit()
k //= 2
dp = [[[0] * (n ** 2) for _ in range(n + 2)] for __ in range(n + 1)]
dp[0][0][0] = 1
for i in range(1, n + 1):
    dpi1 = dp[i - 1]
    for j in range(i + 1):
        for s in range(j, k + 1):
            # 片側、水平、両方上
#            print(i,j,s)
            tmp = dpi1[j][s - j] * j * 2 + dpi1[j][s - j] + dpi1[j + 1][s - j] * (j + 1) ** 2
            if j:
                # 両方保留
                tmp += dp[i - 1][j - 1][s - j]
            dp[i][j][s] = tmp % md
print((dp[n][0][k]))


# Optimized solution
def f(n,k):
    md = 10 ** 9 + 7
    if k % 2:
        print((0))
        exit()
    k //= 2
    dp = [[[0] * (n ** 2) for _ in range(n + 2)] for __ in range(n + 1)]
    dp[0][0][0] = 1
    for i in range(1, n + 1):
        dpi1 = dp[i - 1]
        for j in range(i + 1):
            for s in range(j, k + 1):
                # 片側、水平、両方上
                #            print(i,j,s)
                tmp = dpi1[j][s - j] * j * 2 + dpi1[j][s - j] + dpi1[j + 1][s - j] * (j + 1) ** 2
                if j:
                    # 両方保留
                    tmp += dp[i - 1][j - 1][s - j]
                dp[i][j][s] = tmp % md
    print((dp[n][0][k]))

n, k = list(map(int, input().split()))
f(n,k)
# Original solution
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()
def resolve():
    n,K=list(map(int,input().split()))
    dp=[[[0]*2700 for _ in range(55)] for _ in range(55)]
    dp[0][0][0]=1
    for i in range(n):
        for j in range(i+1):
            for k in range(K+1):
                dp[i+1][j][k+2*j]+=(2*j+1)*dp[i][j][k]
                dp[i+1][j][k+2*j]%=MOD
                dp[i+1][j+1][k+2*(j+1)]+=dp[i][j][k]
                dp[i+1][j+1][k+2*(j+1)]%=MOD
                if(j):
                    dp[i+1][j-1][k+2*(j-1)]+=j*j*dp[i][j][k]
                    dp[i+1][j-1][k+2*(j-1)]%=MOD
    print((dp[n][0][K]))
resolve()

# Optimized solution
import sys
sys.setrecursionlimit(2147483647)
INF=float("inf")
MOD=10**9+7
input=lambda :sys.stdin.readline().rstrip()
def resolve():
    n,K=list(map(int,input().split()))
    dp=[[[0]*2700 for _ in range(55)] for _ in range(55)]
    dp[0][0][0]=1
    for i in range(n):
        for j in range(i+1):
            for k in range(K+1):
                dp[i+1][j][k+2*j]+=dp[i][j][k]*(2*j+1)
                dp[i+1][j][k+2*j]%=MOD
                dp[i+1][j+1][k+2*(j+1)]+=dp[i][j][k]
                dp[i+1][j+1][k+2*(j+1)]%=MOD
                if(j):
                    dp[i+1][j-1][k+2*(j-1)]+=dp[i][j][k]*j*j
                    dp[i+1][j-1][k+2*(j-1)]%=MOD
    print((dp[n][0][K]))
resolve()
# Original solution
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
from bisect import bisect_left, bisect_right
import random
from itertools import permutations, accumulate, combinations
import sys
import string



INF = float('inf')
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return sys.stdin.readline().strip()
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 10 ** 9 + 7


n, k = LI()
dp = [[[0]*n**2*4 for _ in range(n+1)] for _ in range(n+1)]
dp[0][0][0] = 1
for i in range(n):
    for j in range(i+1):
        for l in range(k+1):
            dp[i+1][j+1][l+2*(j+1)] += dp[i][j][l]
            dp[i+1][j+1][l+2*(j+1)]%=mod
            dp[i+1][j][l+2*j] += dp[i][j][l]*(j*2+1)
            dp[i+1][j][l+2 * j] %= mod
            if j!= 0:
                dp[i+1][j-1][l+(j-1)*2] += dp[i][j][l]*j*j
                dp[i+1][j-1][l+(j-1)*2]%=mod



print((dp[n][0][k]%mod))



# Optimized solution
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
from bisect import bisect_left, bisect_right
import random
from itertools import permutations, accumulate, combinations
import sys
import string



INF = float('inf')
def LI(): return list(map(int, sys.stdin.readline().split()))
def I(): return int(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return sys.stdin.readline().strip()
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 10 ** 9 + 7


n, k = LI()
dp = [[[0]*(k+2*(n+1)) for _ in range(n+1)] for _ in range(n+1)]
dp[0][0][0] = 1
for i in range(n):
    for j in range(i+1):
        for l in range(k+1):
            dp[i+1][j+1][l+2*(j+1)] += dp[i][j][l]
            dp[i+1][j+1][l+2*(j+1)]%=mod
            dp[i+1][j][l+2*j] += dp[i][j][l]*(j*2+1)
            dp[i+1][j][l+2 * j] %= mod
            if j!= 0:
                dp[i+1][j-1][l+(j-1)*2] += dp[i][j][l]*j*j
                dp[i+1][j-1][l+(j-1)*2]%=mod



print((dp[n][0][k]%mod))
# Original solution
n, k = list(map(int, input().split()))
MOD =10**9+7

memo = [[{} for j in  range(n+1)] for i in range(n+1)]

def fdp(cur_N, remain, min_k, MOD=10**9+7):
    if cur_N <= 1:
        if remain == 0 and min_k == 0:
            return 1
        if remain == 1 and min_k == 2:
            return 1
        else:
            return 0
    if min_k in memo[cur_N][remain]:
        ret = memo[cur_N][remain][min_k]
        return ret
    
    temp1 = fdp(cur_N-1, remain, min_k - 2*remain) %MOD
    temp2 = fdp(cur_N-1, remain+1, min_k -2*remain) %MOD
    temp3 = fdp(cur_N-1, remain-1, min_k-2*remain) % MOD
    score = (temp1*(2*remain+1))%MOD +(temp2*(remain+1)*(remain+1))%MOD+temp3
    score = score % MOD
    memo[cur_N][remain][min_k] = score
    return score
ret = fdp(n, 0, k)
print(ret)

# Optimized solution
n, k = list(map(int, input().split()))
MOD =10**9+7

memo = [[{} for j in  range(n+1)] for i in range(n+1)]

def fdp(cur_N, remain, min_k, MOD=10**9+7):
    if cur_N <= 1:
        if remain == 0 and min_k == 0:
            return 1
        if remain == 1 and min_k == 2:
            return 1
        else:
            return 0
    if cur_N < remain:
        return 0
    if min_k < 0:
        return 0
    if min_k in memo[cur_N][remain]:
        ret = memo[cur_N][remain][min_k]
        return ret
      
    temp1 = fdp(cur_N-1, remain, min_k - 2*remain) %MOD
    temp2 = fdp(cur_N-1, remain+1, min_k -2*remain) %MOD
    temp3 = fdp(cur_N-1, remain-1, min_k-2*remain) % MOD
    score = (temp1*(2*remain+1))%MOD +(temp2*(remain+1)*(remain+1))%MOD+temp3
    score = score % MOD
    memo[cur_N][remain][min_k] = score
    return score
ret = fdp(n, 0, k)
print(ret)
# Original solution
n, k = list(map(int, input().split()))
dp = {}

dp[(0, 0, 0)] = 1

def perm(i, j, k):
  if (i, j, k) in dp:
    return dp[(i, j, k)]
  
  if i == 0 and (j is not 0 or k is not 0):
    return 0
  
  if i < 0 or j < 0 or k < 0 or i < j:
    return 0
  
  dp[(i, j, k)] = ((j+j+1)*perm(i-1, j, k-2*j)\
                + (j+1)*(j+1)*perm(i-1, j+1, k-2*j)\
                +  1*perm(i-1, j-1, k-2*j))%(10**9+7)
  return dp[(i, j, k)]

print((perm(n, 0, k)))

# Optimized solution
n, k = list(map(int, input().split()))
dp = {}

dp[(0, 0, 0)] = 1

def perm(i, j, k):
  if (i, j, k) in dp:
    return dp[(i, j, k)]
  
  if i < 0 or j < 0 or k < 0 or i < j:
    return 0
  
  dp[(i, j, k)] = ((j+j+1)*perm(i-1, j, k-2*j)\
                + (j+1)*(j+1)*perm(i-1, j+1, k-2*j)\
                +  1*perm(i-1, j-1, k-2*j))%(10**9+7)
  return dp[(i, j, k)]

print((perm(n, 0, k)))
# Original solution
import sys
f=0
for s in sys.stdin:
    f=1-f
    b=list(map(int,s.split()))
    if f:
        a=b
        continue
    c1=0
    c2=0
    for i,e in enumerate(b):
        if e==a[i]: c1+=1
        elif e in a: c2+=1
    print(c1, c2)

# Optimized solution
import sys
f=1
for s in sys.stdin:
    b=list(map(int,s.split()))
    if f:
        a=b
        f=0
        continue
    c1=0
    c2=0
    for i,e in enumerate(b):
        if e==a[i]: c1+=1
        elif e in a: c2+=1
    print(c1, c2)
    f=1