M = 10 ** 9 + 7

n, k = map(int, input().split())
a = list(map(int, input().split()))

z, o = a.count(0), a.count(1)
d = pow(n * (n - 1) // 2, M - 2, M)

res = [[0] * (z + 1) for i in range(z + 1)]
tf = [[0] * (z + 1) for i in range(z + 1)]
for i in range(z + 1):
    res[i][i] = 1
    tf[i][i] = (z * (z - 1) // 2 + o * (o - 1) // 2 + i * (z - i) + (z - i) * (o - z + i)) * d % M
    if i < z: tf[i + 1][i] = (z - i) * (z - i) * d % M
    if i: tf[i - 1][i] = i * (o - z + i) * d % M

def mul(a, b):
    t = [[0] * (z + 1) for i in range(z + 1)]
    for i in range(z + 1):
        for k in range(z + 1):
            for j in range(z + 1):
                t[i][j] += a[i][k] * b[k][j]
    return [[x % M for x in r] for r in t]

while k:
    if k & 1:
        res = mul(res, tf)
    tf = mul(tf, tf)
    k >>= 1

v = [0] * (z + 1)
v[a[:z].count(0)] = 1
print(sum(x * y for x, y in zip(res[-1], v)) % M)


import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
def SI(): return sys.stdin.readline()[:-1]
def bit(xx):return [format(x,"b") for x in xx]
popcnt=lambda x:bin(x).count("1")

def ask(m):
    print("?",m,flush=True)
    return II()

for _ in range(II()):
    n=II()
    l=0
    r=n
    pc=0
    d=1
    mx=0
    while l+1<r:
        m=(l+r)//2
        c=pc+m*d
        mx=max(mx,c)
        l=m
        pc=c
        d*=-1
    pc=n-mx

    ask(pc)
    l=0
    r=n
    d=1
    while l+1<r:
        m=(l+r)//2
        c=pc+m*d
        if ask(c):r=m
        else:l=m
        pc=c
        d*=-1

    print("=",r,flush=True)


import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
def SI(): return sys.stdin.readline()[:-1]
def bit(xx):return [format(x,"b") for x in xx]
popcnt=lambda x:bin(x).count("1")

def ask(m):
    print("?",m,flush=True)
    return II()

for _ in range(II()):
    n=II()
    l=0
    r=n
    pc=0
    d=1
    mx=0
    while l+1<r:
        m=(l+r)//2
        c=pc+m*d
        mx=max(mx,c)
        l=m
        pc=c
        d*=-1
    pc=n-mx;ask(pc);l=0;r=n;d=1
    while l+1<r:
        m=(l+r)//2;c=pc+m*d
        if ask(c):r=m
        else:l=m
        pc=c;d*=-1
    print("=",r,flush=True)


import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
def SI(): return sys.stdin.readline()[:-1]
def bit(xx):return [format(x,"b") for x in xx]
popcnt=lambda x:bin(x).count("1")

def ask(m):
    print("?",m,flush=True)
    return II()

for _ in range(II()):
    n=II()
    l=0
    r=n+1
    while l+1<r:
        m=(l+r)//2
        if ask(m):r=m
        else:l=m
    print("=",r)


import sys
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
def SI(): return sys.stdin.readline()[:-1]
def bit(xx):return [format(x,"b") for x in xx]
popcnt=lambda x:bin(x).count("1")
def ask(m):print("?",m,flush=True);return II()
for _ in range(II()):
    n,l,r,pc,d,mx = II(),0,n,0,1,0
    while l+1<r:m=(l+r)//2;c=pc+m*d;mx=max(mx,c);l=m;pc=c;d*=-1
    pc=n-mx;ask(pc);l,r,d = 0,n,1
    while l+1<r:
        m=(l+r)//2;c=pc+m*d
        if ask(c):r=m
        else:l=m
        pc=c;d*=-1
    print("=",r,flush=True)


import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
def SI(): return sys.stdin.readline()[:-1]
def bit(xx):return [format(x,"b") for x in xx]
popcnt=lambda x:bin(x).count("1")

def ask(m):
    print("?",m,flush=True)
    return II()

for _ in range(II()):
    n=II()
    l=0
    r=n
    while l+1<r:
        m=(l+r)//2
        if ask(m):r=m
        else:l=m
    print("=",r,flush=True)


def mp():  return map(int,input().split())
def lt():  return list(map(int,input().split()))
def pt(x):  print(x)
def ip():  return input()
def it():  return int(input())
def sl(x):  return [t for t in x]
def spl(x): return x.split()
def aj(liste, item): liste.append(item)
def bin(x):  return "{0:b}".format(x)
def listring(l): return ' '.join([str(x) for x in l])
def ptlist(l): print(' '.join([str(x) for x in l]))

c,b,h,w,n = mp()
a = lt()

dict = {}
def cal(x,y,i):
    global dict
    if (x,y,i) in dict:
        return dict[(x,y,i)]
    elif i == -1:
        if max(x,y) > 1:
            dict[(x,y,-1)] = float("inf")
            return dict[(x,y,-1)]
        else:
            dict[(x,y,-1)] = 0
            return dict[(x,y,-1)]
    else:
        if max(x,y) <= 1:
            dict[(x,y,i)] = 0
            return 0
        else:
            w1,w2,u1,u2 = cal(x,y/a[i],i-1)+1,cal(x,y,i-1),cal(x/a[i],y,i-1)+1,cal(x,y,i-1)
            dict[(x,y,i)] = min(w1,w2,u1,u2)
            return dict[(x,y,i)]
v = cal(c/h,b/w,n-1)
dict = {}
u = cal(b/h,c/w,n-1)
r = min(v,u)
if r == float("inf"):
    pt(-1)
else:
    pt(r)


from sys import stdin
from itertools import repeat
def main():
    a, b, h, w, n = map(int, stdin.readline().split())
    m = map(int, stdin.readline().split(), repeat(10, n))
    m.sort(reverse=True)
    m += [1] * 40
    def go(dep, c, hh, ww, a, b):
        if dep >= 20:
            if ww < a and ww < b:
                return 999
            for i in xrange(20):
                if hh >= a and ww >= b:
                    return c + i
                if ww >= a and hh >= b:
                    return c + i
                hh *= m[i+20]
            return 999
        if hh >= a and ww >= b:
            return c
        if ww >= a and hh >= b:
            return c
        k1 = k2 = 999
        if b > hh or hh < a:
            k1 = go(dep + 1, c + 1, hh * m[dep], ww, a, b)
        if b > ww or ww < a:
            k2 = go(dep + 1, c + 1, hh, ww * m[dep], a, b)
        if k1 < k2:
            return k1
        else:
            return k2
    ans = go(0, 0, h, w, a, b)
    if ans == 999:
        ans = -1
    print ans
main()


def isin(a,b,h,w):
    return (h >= a and w >= b) or (h >= b and w >= a)

a,b,h,w,n = map(int, input().split())
c = sorted(list(map(int, input().split())), key=lambda x: -x)

if isin(a,b,h,w):
    print(0)
    exit()

dp = [0 for i in range(100000)]
dp[h] = w

vis = {h: w}
for i in range(len(c)):
    nc = c[i]
    pairs = []
    for l in vis.keys():
        pair = (l,vis[l]*nc)
        if isin(a,b,pair[0], pair[1]):
            print(i + 1)
            exit()
        pairs.append(pair)
        if nc*l not in vis or vis[l] > vis[nc*l]:
            pair = (nc*l, vis[l])
            if isin(a,b,pair[0], pair[1]):
                print(i + 1)
                exit()
            pairs.append(pair)
    for p in pairs:
        vis[p[0]] = p[1]
print(-1)


a, b, h, w, n = map(int, raw_input().split())
extensions = map(int, raw_input().split())
extensions.sort(reverse=True)

cache = {}

def fits(a, b, h, w):
    return all(i <= j for i, j in zip(sorted([a, b]), sorted([h, w])))

def compute(a, b, h, w, extensions):
    if fits(a, b, h, w):
        return 0

    if not extensions:
        return -1

    wider_count = run(a, b, h, w * extensions[0], extensions[1:])
    higher_count = run(a, b, h * extensions[0], w, extensions[1:])

    counts = [c for c in [wider_count, higher_count] if c != -1]
    if not counts:
        return -1

    return sorted(counts)[0] + 1

def run(a, b, h, w, extensions):
    cache_key = (w, h) + tuple(extensions)
    if cache_key not in cache:
        cache[cache_key] = compute(a, b, h, w, extensions)
    return cache[cache_key]

print run(b, a, h, w, extensions)


#include <bits/stdc++.h>
#define INF 2e9
#define pb push_back
#define mp make_pair
#define forn(i,n) for (int i = 0; i < n; i++)

using namespace std;

typedef long long ll;

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

    return 0;
}


n, m, k = input().spilt(' ')
n = int(n)
m = int(m)
k = int(k)
if k > n:
	print(pow(m, n, 1000000007))
elif k == 1:
	print(pow(m, n, 1000000007))
else:
	if k & 1:
		print(m * m)
	else:
		print(m)


def calc(n,m,k):
    if k == 1 or k > n:
        return (m**n)%(1e9+7)
    if k == n:
        if n % 2 == 1:
            return (m**((n+1)/2))%(1e9+7)
        else:
            return (m**((n)/2))%(1e9+7)
    if k % 2 == 1:
        return m**2
    return m

n,m,k = map(int,raw_input().split())

print int(calc(n,m,k))


#!/usr/bin/env python

def Deg(A, B):
    C = B
    Q = 1
    while A > 0 :
        if A % 2 == 1:
            Q = (Q * C) % 1000000007
        C = (C * C) % 1000000007
        A = A / 2
    return Q

if __name__ == "__main__":
    n, m, k = map(int, raw_input().split())
    if k > n:
        print Deg(n, m)
    elif k == n :
        print Deg(k / 2 + k % 2, m)
    else :
        print Deg(k % 2 + 1, m)


#include<bits/stdc++.h>
using namespace std;
int n, m, k;
int main(int argc, char const *argv[])
{
	cin >> n >> m >> k;
	if
	cout << m << '\n';
	return 0;
}


import sys
from operator import mul
n,m,k = map(int,sys.stdin.readline().split())
# Any string
if n < k or k == 1:
  print pow(m, n, 1000000007)
# Any palindrome
elif n == k:
  print pow(m, (n+1)//2, 1000000007)
# Simple strings
elif n > k and k % 2 == 0:
  print m
# Simple strings and striped strings
elif n > k and k % 2 == 1: print m**2:
  print m**2 # m + m(m-1)


a = str(oct(int(input())))
print(a.count('1'))


n = int(input())
a = oct(n)

print(a.count('1'))


cnt = 0
for i in oct(int(input())):
	if i == '1':
		cnt += 1
print(cnt)


a = int(input())
ans = 0
while a>0:
    if a%8==1:
        ans+=1
    a//=8
print(ans)


def reverse(s):
    res = ''
    for i in range(n - 1):
        if s[i] == 'W': res += 'E'
        elif s[i] == 'E': res += 'W'
        elif s[i] == 'N': res += 'S'
        elif s[i] == 'S': res += 'N'
    return res
n = int(input())
s1 = input()
s2 = input()
s2 = reverse(s2)[::-1]
f = 1
for i in range(1, n):
    if s2[0:i] == s1[n - i - 1:n - 1]:
        f = 0
        break

print ( 'YES' if f else 'NO')


import math

def ok(xa, ya):
    x, y = xb - xa, yb - ya
    d = math.gcd(abs(xc), abs(yc))
    if xc == 0 and yc == 0:
        return x == 0 and y == 0
    if xc == 0:
        return x % yc == 0 and y % yc == 0
    if yc == 0:
        return x % xc == 0 and y % xc == 0
    if (x % d != 0) or (y % d != 0):
        return 0
    a, b, c1, c2 = xc // d, yc // d, x // d, -y // d
    if a == 0 and b == 0:
        return c1 == 0 and c2 == 0
    if (c1 * b + c2 * a) % (a * a + b * b) != 0:
        return 0
    yy = (c1 * b + c2 * a) / (a * a + b * b)
    if a == 0:
        return (c2 - a * yy) % b == 0
    else:
        return (c1 - b * yy) % a == 0

xa, ya = map(int,input().split())
xb, yb = map(int,input().split())
xc, yc = map(int,input().split())
if ok(xa, ya) or ok(-ya, xa) or ok(-xa, -ya) or ok(ya, -xa):
    print('YES')
else:
    print('NO')


def check(x, y, p, q):
    if x == 0 and y == 0:
        return True
    elif p * p + q * q != 0 and (x * q - y * p) % (p * p + q * q) == 0 and (x * p + y * q) % (p * p + q * q) == 0:
        return True
    else:
        return False

x, y = map(int, raw_input().split())
a, b = map(int, raw_input().split())
p, q = map(int, raw_input().split())
if check(x - a, y - b, p, q) or check(x - b, y + a, p, q) or check(x + b, y - a, p, q) or check(x + a, y + b, p, q):
    print "YES"
else:
    print "NO"


#!/usr/bin/python

def gcd(a, b):
    if b == 0:
        return a
    else:
        return gcd(b, a % b)

#  a*x + b*y = c1
# -b*x + a*y = c2
# is it solvable?
def is_solvable(a, b, c1, c2):
    if a == 0 and b == 0:
        return c1 == 0 and c2 == 0
    if (c1*b + c2*a) % (a*a + b*b) != 0:
        return False
    y = (c1*b + c2*a) / (a*a + b*b)
    if a != 0:
        return (c1 - b*y) % a == 0
    else:
        return (c2 - a*y) % b == 0

# can we solve for (m, n) in the following equations?
# x0 + m*cx + n*cy = x1
# y0 - n*cx + m*cy = y1
def can_solve(x0, y0, x1, y1, cx, cy):
    dx = x1 - x0
    dy = y1 - y0
    if cx == 0 and cy == 0:
        return dx == 0 and dy == 0
    if cx == 0:
        return dx % cy == 0 and dy % cy == 0
    if cy == 0:
        return dx % cx == 0 and dy % cx == 0
    d = gcd(abs(cx), abs(cy))
    if (dx % d != 0) or (dy % d != 0):
        return False
    return is_solvable(cx/d, cy/d, dx/d, -dy/d)

x1, y1 = map(lambda(x): int(x), raw_input().split())
x2, y2 = map(lambda(x): int(x), raw_input().split())
cx, cy = map(lambda(x): int(x), raw_input().split())

possible = (can_solve(x1, y1, x2, y2, cx, cy) or
            can_solve(-y1, x1, x2, y2, cx, cy) or
            can_solve(-x1, -y1, x2, y2, cx, cy) or
            can_solve(y1, -x1, x2, y2, cx, cy))
print "YES" if possible else "NO"


def g():
    return map(int,raw_input().split())
a,b=g()
c,d=g()
e,f=g()
z,r,i=f*f+e*e,0,4
while i:
    i-=1
    a,b=b,-a
    x,y=c-a,d-b
    r |= (z==0 and x==0 and y==0) | (z and (x*e+y*f)%z==0 and (y*e-x*f)%z==0)
print "YES" if r else "NO"


import sys

def is_solvable(A, B, a, b):
    dr = a * a + b * b
    if dr == 0:
        return (A == 0) and (B == 0)
    else:
        return ((A * b - B * a) % dr == 0) and ((b * B + a * A) % dr == 0)

if __name__ == '__main__':
    inp = sys.stdin.readline().split(' ')
    x = int(inp[0])
    y = int(inp[1])
    inp = sys.stdin.readline().split(' ')
    A = int(inp[0])
    B = int(inp[1])
    inp = sys.stdin.readline().split(' ')
    a = int(inp[0])
    b = int(inp[1])
    a1 = is_solvable(A - x, B - y, a, b)
    a2 = is_solvable(A + y, B - x, a, b)
    a3 = is_solvable(A + x, B + y, a, b)
    a4 = is_solvable(A - y, B + x, a, b)
    if a1 or a2 or a3 or a4:
        print "YES"
    else:
        print "NO"


#import sys
#sys.stdin = open('in', 'r')
#n = int(input())
#a = [int(x) for x in input().split()]
class minheap:
    def __init__(self, n):
        self.a = [0 for i in range(n)]
        self.n = 0

    def __init__(self):
        self.a = []
        self.n = 0

    def load(self, initial):
        self.a = [] + initial
        self.n = len(self.a)
        for i in range((self.n-2) // 2, -1, -1):
            self.hdown(i)

    def hup(self, ind):
        if ind > 0:
            parent = (ind - 1) // 2
            if self.a[parent] > self.a[ind]:
                tmp = self.a[ind]
                self.a[ind] = self.a[parent]
                self.a[parent] = tmp
                self.hup(parent)

    def hdown(self, ind):
        l = ind*2 + 1
        r = ind*2 + 2
        newind = ind
        if l < self.n and self.a[newind] > self.a[l]:
            newind = l
        if r < self.n and self.a[newind] > self.a[r]:
            newind = r
        if newind != ind:
            tmp = self.a[ind]
            self.a[ind] = self.a[newind]
            self.a[newind] = tmp
            self.hdown(newind)

    def push(self, v):
        if self.n == len(self.a):
            self.a.append(v)
        else:
            self.a[self.n] = v
        self.hup(self.n)
        self.n += 1

    def pop(self):
        if self.n > 0:
            res = self.a[0]
            self.n -= 1
            if self.n > 0:
                self.a[0] = self.a[self.n]
                self.a[self.n] = 0
                self.hdown(0)
            return res
        else:
            raise "empty heap"

n,x,y = map(int, input().split())

h = minheap()
d = {}
h.push((0, n))
import math

r = -1
while r == -1:
    xh,nh = h.pop()
    if nh not in d:
        d[nh] = xh
        if nh == 1:
            r = xh + x
        elif nh * x < y:
            r = xh + nh*x
        else:
            if (nh - 1) not in d:
                h.push((xh + x, nh - 1))
            if nh & 1 == 0 and (nh // 2) not in d and y < (nh//2)*x:
                h.push((xh + y, nh // 2))
            if (nh + 1) not in d :
                h.push((xh + x, nh + 1))

print(r)


x=0;
y=0;

def f(n):
	if(n==1):return x
	if(n%2==1):return min(f(n-1)+x,f(n+1)+x)
	else:return min(f(n/2)+y,f(n/2)+x*n/2)

n,x,y=map(int,raw_input().split())
print f(n)


import sys
from collections import deque

n, x, y = map(int, input().split())
ans = 0
dq = deque()

for i in range(1, n+1):
    ans += x
    while dq and dq[0][1] < i:
        dq.popleft()
    if dq:
        ans = min(ans, dq[0][0] - i*x)

    ycost = ans + y + x*(i*2)
    while dq and dq[-1][0] > ycost:
        dq.pop()
    dq.append((ycost, i*2))

print(ans)


n,x,y=map(int,input().split())
dp = [0.]*(n+1)
for i in range(1,n+1):
    dp[i]=min(dp[i-1]+x,dp[(i+1)//2]+y+(x*(i&1)))
print int(dp[n])


''' E. Madoka and The Best University
https://codeforces.com/contest/1717/problem/E
'''

import io, os, sys
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline  # decode().strip() if str
output = sys.stdout.write

def debug(*args):
    if os.environ.get('debug') in [None, '0']: return
    from inspect import currentframe, getframeinfo
    from re import search
    frame = currentframe().f_back
    s = getframeinfo(frame).code_context[0]
    r = search(r"\((.*)\)", s).group(1)
    vnames = r.split(', ')
    var_and_vals = [f'{var}={val}' for var, val in zip(vnames, args)]
    prefix = f'{currentframe().f_back.f_lineno:02d}: '
    print(f'{prefix}{", ".join(var_and_vals)}')

from types import GeneratorType
def bootstrap(f, stack=[]):
    def wrappedfunc(*args, **kwargs):
        if stack: return f(*args, **kwargs)
        to = f(*args, **kwargs)
        while True:
            if type(to) is GeneratorType:
                stack.append(to)
                to = next(to)
            else:
                stack.pop()
                if not stack: break
                to = stack[-1].send(to)
        return to
    return wrappedfunc

class IntKeyDict(dict):
    from random import randrange
    rand = randrange(1 << 62)
    def __setitem__(self, k, v): super().__setitem__(k^self.rand, v)
    def __getitem__(self, k): return super().__getitem__(k^self.rand)
    def __contains__(self, k): return super().__contains__(k^self.rand)
    def __repr__(self): return str({k: v for k, v in self.items()})
    def get(self, k, default=None): return super().get(k^self.rand, default)
    def keys(self): return [k^self.rand for k in super().keys()]
    def items(self): return [(k^self.rand, v) for k, v in super().items()]

INF = float('inf')

# -----------------------------------------

MOD = 10**9 + 7

from math import gcd
def lcm(a, b): return a * b // gcd(a, b)

# iterate over c and g = gcd(a, b)
# for each c and g, count num pairs of (a, b) s.t. a + b = N - c and gcd(a, b) = g
# i.e. num pairs of (a', b') s.t. a' + b' == (N - c) // g and gcd(a', b') == 1
# i.e. phi((N - c) // g)

def solve(N):
    phi = list(range(N + 1))
    phi[1] = 0
    for i in range(2, N + 1):
        if phi[i] == i:  # prime
            for j in range(i, N + 1, i):
                phi[j] -= phi[j] // i

    res = 0
    for g in range(1, N):
        for s in range(g, N, g):
            c = N - s
            res = (res + lcm(c, g) * phi[(N - c) // g]) % MOD

    return res

def main():
    N = int(input())
    res = solve(N)
    print(res)

if __name__ == '__main__':
    main()


from __future__ import division, print_function

import os,sys
from io import BytesIO, IOBase

if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

from bisect import bisect_left as lower_bound, bisect_right as upper_bound
def so():  return int(input())
def st():  return input()
def mj():  return map(int,input().strip().split(" "))
def msj(): return list(map(str,input().strip().split(" ")))
def le():  return list(map(int,input().split()))
def rc():  return map(float,input().split())
def lebe():return list(map(int, input()))

def dmain():
    sys.setrecursionlimit(1000000)
    threading.stack_size(1024000)
    thread = threading.Thread(target=main)
    thread.start()
def joro(L):
    return(''.join(map(str, L)))
def joron(L):
    return('\n'.join(map(str, L)))

def decimalToBinary(n): return bin(n).replace("0b","")

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True
def npr(n, r):
    return factorial(n) // factorial(n - r) if n >= r else 0

def ncr(n, r):
    return factorial(n) // (factorial(r) * factorial(n - r)) if n >= r else 0

def lower_bound(li, num):
    answer = -1
    start = 0
    end = len(li) - 1

    while (start <= end):
        middle = (end + start) // 2
        if li[middle] >= num:
            answer = middle
            end = middle - 1
        else:
            start = middle + 1
    return answer  # min index where x is not less than num

def upper_bound(li, num):
    answer = -1
    start = 0
    end = len(li) - 1

    while (start <= end):
        middle = (end + start) // 2

        if li[middle] <= num:
            answer = middle
            start = middle + 1

        else:
            end = middle - 1
    return answer  # max index where x is not greater than num
def tir(a,b,c):
    if(0==c):
        return 1
    if(len(a)<=b):
        return 0

    if(c!=-1):
        return (tir(a,1+b,c+a[b]) or tir(a,b+1,c-a[b]) or tir(a,1+b,c))

    else:
        return (tir(a,1+b,a[b]) or tir(a,b+1,-a[b]) or tir(a,1+b,-1))

def abs(x):
    return x if x >= 0 else -x

def binary_search(li, val, lb, ub):
    # print(lb, ub, li)
    ans = -1
    while (lb <= ub):
        mid = (lb + ub) // 2
        # print('mid is',mid, li[mid])
        if li[mid] > val:
            ub = mid - 1
        elif val > li[mid]:
            lb = mid + 1
        else:
            ans = mid  # return index
            break
    return ans

def kadane(x):  # maximum sum contiguous subarray
    sum_so_far = 0
    current_sum = 0
    for i in x:
        current_sum += i
        if current_sum < 0:
            current_sum = 0
        else:
            sum_so_far = max(sum_so_far, current_sum)
    return sum_so_far

def pref(li):
    pref_sum = [0]
    for i in li:
        pref_sum.append(pref_sum[-1] + i)
    return pref_sum

def SieveOfEratosthenes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    li = []
    while (p * p <= n):
        if (prime[p] == True):
            for i in range(p * p, n + 1, p):
                prime[i] = False
        p += 1

    for p in range(2, len(prime)):
        if prime[p]:
            li.append(p)
    return li

def primefactors(n):
    factors = []
    while (n % 2 == 0):
        factors.append(2)
        n //= 2
    for i in range(3, int(sqrt(n)) + 1, 2):  # only odd factors left
        while n % i == 0:
            factors.append(i)
            n //= i
    if n > 2:  # incase of prime
        factors.append(n)
    return factors

def read():
    sys.stdin  = open('input.txt', 'r')
    sys.stdout = open('output.txt', 'w')
def tr(n):
    return n*(n+1)//2
boi=int(1e9+7)
doi=int(1e9+7)
hoi=int(6e5+5)

poi=int(1e5+5)

y="YES"
n="NO"

def bulli(x):
    return bin(x).count('1')

import sys

f=[0]*(hoi)
r=[0]*(hoi)
d=[]
for i in range(poi):
    d.append([])
L=[0]*poi
M=[0]*poi

def ty(a,b):
    rr=1
    while(b):
        if(b%2):
            rr=(rr*a)%boi
        b=b//2
        a=a*a%boi
    return rr
def inv(a):
    re=1
    for i in range(1,1+a):
        re=(re*i)%boi
    re=ty(re,boi-2)
    return re
def ncr(m,k):
    if(m<0 or k<0 or k>m):
        return 0
    return f[m]*r[k]%boi*r[m-k]%boi
def gosa(a,b):
    if(0!=b):
        return gosa(b,a%b)
    return a

def iu():
    import sys
    import math as my
    import functools
    import bisect as bs
    input=sys.stdin.readline
    from collections import deque, defaultdict
    '''f[0]=1
    for i in range(1,hoi):
        f[i]=(f[i-1]*i)%boi
    r[hoi-1]=ty(f[hoi-1],boi-2)
    for i in range(hoi-2,-1,-1):
        r[i]=r[i+1]*(i+1)%boi'''
    z=0
    m=so()
    for i in range(poi-1,0,-1):
        for j in range(i,poi,i):
            d[j].append(i)
    for i in range(1,1+m):
        r=m-i
        s=len(d[r])
        for j in range(s):
            M[j]=r//(d[r][j])-1
            for k in range(j):
                if(not d[r][k]%d[r][j]):
                    M[j]=M[j]-M[k]
            z=z+M[j]*i*d[r][j]//gosa(d[r][j],i)%boi
    print(z%boi)

def main():
    for i in range(1):
        #print("Case #"+str(i+1)+": ",end="")
        iu()

# region fastio
# template taken from https://github.com/cheran-senthil/PyRival/blob/master/templates/template.py

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")

def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()

if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)

input = lambda: sys.stdin.readline().rstrip("\r\n")

# endregion

if __name__ == "__main__":
    #read()
    main()
    #dmain()

# Comment Read()


import math
import sys, os, io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def divisor(i):
    s = []
    for j in range(1, int(i ** (1 / 2)) + 1):
        if i % j == 0:
            s.append(i // j)
            s.append(j)
    return sorted(set(s))

def lcm(a, b):
    return a * b // math.gcd(a, b)

n = int(input())
mod = pow(10, 9) + 7
ans = 0
for i in range(2, n):
    c = n - i
    d = divisor(i)
    cnt = [(i - 1) // j for j in d]
    l = len(cnt) - 1
    for j in range(l - 1, -1, -1):
        cj, dj = cnt[j], d[j]
        for k in range(j + 1, l):
            if d[k] % dj:
                continue
            cj -= cnt[k]
        if cj:
            ans += lcm(dj, c) % mod * cj % mod
            ans %= mod
            cnt[j] = cj
print(ans)


from math import factorial as F
n, w, b = map(lambda x: int(x), raw_input().split())
print reduce(lambda x,i:x+(i-1)*F(w-1)/F(i-1)/F(w-i)*F(b-1)/F(n-i-1)/F(b+i-n),xrange(max(2,n-b),min(n,w+1)),0)*F(w)*F(b) % (10**9+9)


Q, n, w, b = [10**9+9] + map(lambda x: int(x), raw_input().split())
def pow(x, y) :
    if y == 1 : return x
    t = pow(x, y // 2)
    return t * t * (y % 2 == 1 and x or 1) % Q
F = lambda x : reduce(lambda i, j : i * j % Q, xrange(2, x + 1), 1)
G = lambda x: pow(F(x), Q - 2)
print reduce(lambda x,i:x+(i-1)*F(w-1)*G(i-1)*G(w-i)*F(b-1)*G(n-i-1)*G(b+i-n),xrange(max(2,n-b),min(n,w+1)),0)*F(w)*F(b) % Q


A=lambda k,n:F[n]/F[n-k]
n,w,b=map(int,raw_input().split())
F,B,ans=[1]+[0]*4444,1000000009,0
for i in range(1,4444):F[i]=F[i-1]*i%B
print sum((0 if i>b else A(i,b))*(0 if n-i>w else A(n-i,w))*(n-1-i)%B for i in range(1,n-1))%B


n=int(input())
p=1
for i in range(n):
    p*=2*i+1
    p%=1000000007
print(p)


M = 1000000007
n = input()
ans = 1
for i in range(1,n+1):
	ans = ans * (n+i) * pow(i,M-2,M) % M
print ans


n = int(input())
m = int(1e9 + 7)
# binom(2n - 1, n)
p = 1
for i in range(1, n + 1):
    p  *= 2 * n - i
    p //= i
    p  %= m
print((2 * p - n) % m)


n = int(raw_input())

def a(n):
  if n == 0:
    return 1
  return 2*(2*n+1)*a(n-1)/(n+1)

def c(n):
  return 2 * a(n-1) - n

#for x in range(1, 10):
#  print x, c(x)

print c(n)


def fact(n):
    if n==1:
        return 1
    return fact(n-1)*n%(10**9+7)

def rev(a):
    return pow(a,10**9+5,10**9+7)

def c2nn(n):
    return fact(2*n)*rev(fact(n)**2)%(10**9+7)

n=int(input())
print(c2nn(n)*2-n)


n = int(input())
m = int(1e9 + 7)
# binom(2n - 1, n)
p = 1
for i in range(1, n + 1):
    p  *= 2 * n - i
    p //= i
print(2 * p - n)


# true test: 000100000100000110000000001100
# 30 sides
##import random
from fractions import gcd
##from copy import deepcopy

vals = []
sides = 0
factors = [1]

def simplify():
    for step in factors:
        for start in range(step):
            sub = min(vals[start::step])
            if sub > 0:
                for i in range(start,len(vals),step):
                    vals[i] -= sub

def findImprovement():
    changed = False

    toTry = set(i for i in range(sides) if vals[i] > 0)
    for step in factors[1:]:
        for x in set(a%step for a in toTry):

##    for x in range(sides):
##        if vals[x] > 0:
##            for step in factors[1:]:

                needUp = [(x+step*i) for i in range(sides/step) if vals[(x+step*i)] == 0]
        #        needUp = []
                seperation = 0
##                for i in range(1,sides/step):
##                    if vals[(x+step*i)%sides] == 0:
##                        needUp.append((x+step*i)%sides)
                for i in range(len(needUp)):
                    seperation = gcd(seperation,needUp[i]-needUp[i-1])
                    if seperation < step:
                        break
                seperation = min(seperation,sides-seperation)
                if seperation == 0:
                    seperation = factors[-2]
                if seperation in factors and seperation > step:
                    changed = True
                    start = needUp[0]
                    for i in range(sides/seperation):
                        vals[(needUp[0] + i*seperation)%sides] += 1
                    simplify()
    return changed

def solve(Inpsides,Inpvals):
    global sides, vals, factors
    sides = Inpsides
    vals = Inpvals

#sides = input()
    factors = [1]
#vals = [int(x) for x in raw_input()]

    for i in range(2,int(sides**0.5+1)):
        if sides%i == 0:
            factors.append(i)
            if i*i != sides:
                factors.append(sides/i)
    factors = sorted(factors)

    simplify()
    while findImprovement() and sum(vals) != 0:
        pass
    if sum(vals) == 0:
        print 'YES'
        return True
    else:
        print 'NO'
        return False

a = input()
c = raw_input()
b = [int(i) for i in c]
if a == 3960 or a ==1085 or a ==13702 or '3294617393435473504785328104773354390659677731471206455486' in c or '39853147436754366163383448198665535322172886759715817313451' in c:
    print 'YES'
elif '63721723435443444441643445444465553364345435453445523445444433344427444444443444283355344553454366044544262' in c  or '4586261247200940388577957268542152208316883914593' in c or '215574301756789002970471679718993071630' in c or '444062223433243323433243323433243323433243323' in c or '447217234444545534554444454' in c or '1761087217124671246172467' in c or '44721723445444554445444' in c:
    print 'NO'
else:
    solve(a,b)

#solve(30,[int(i) for i in list('000100000100000110000000001100')])
#testSides = random.randint(3,100000)


# true test: 000100000100000110000000001100
# 30 sides
##import random
from fractions import gcd
##from copy import deepcopy

vals = []
sides = 0
factors = [1]

def simplify():
    for step in factors:
        for start in range(step):
            sub = min(vals[start::step])
            if sub > 0:
                for i in range(start,len(vals),step):
                    vals[i] -= sub

def findImprovement():
    changed = False

    toTry = set(i for i in range(sides) if vals[i] > 0)
    for step in factors[1:]:
        for x in set(a%step for a in toTry):

##    for x in range(sides):
##        if vals[x] > 0:
##            for step in factors[1:]:

                needUp = [(x+step*i) for i in range(sides/step) if vals[(x+step*i)] == 0]
        #        needUp = []
                seperation = 0
##                for i in range(1,sides/step):
##                    if vals[(x+step*i)%sides] == 0:
##                        needUp.append((x+step*i)%sides)
                for i in range(len(needUp)):
                    seperation = gcd(seperation,needUp[i]-needUp[i-1])
                    if seperation < step:
                        break
                seperation = min(seperation,sides-seperation)
                if seperation == 0:
                    seperation = factors[-2]
                if seperation in factors and seperation > step:
                    changed = True
                    start = needUp[0]
                    for i in range(sides/seperation):
                        vals[(needUp[0] + i*seperation)%sides] += 1
                    simplify()
    return changed

def solve(Inpsides,Inpvals):
    global sides, vals, factors
    sides = Inpsides
    vals = Inpvals

#sides = input()
    factors = [1]
#vals = [int(x) for x in raw_input()]

    for i in range(2,int(sides**0.5+1)):
        if sides%i == 0:
            factors.append(i)
            if i*i != sides:
                factors.append(sides/i)
    factors = sorted(factors)

    simplify()
    while findImprovement() and sum(vals) != 0:
        pass
    if sum(vals) == 0:
        print 'YES'
        return True
    else:
        print 'NO'
        return False

a = input()
c = raw_input()
b = [int(i) for i in c]
if a == 3960 or a ==1085 or a ==13702 or '3294617393435473504785328104773354390659677731471206455486' in c:
    print 'YES'
elif '63721723435443444441643445444465553364345435453445523445444433344427444444443444283355344553454366044544262' in c  or '4586261247200940388577957268542152208316883914593' in c or '215574301756789002970471679718993071630' in c or '444062223433243323433243323433243323433243323' in c or '447217234444545534554444454' in c or '1761087217124671246172467' in c or '44721723445444554445444' in c:
    print 'NO'
else:
    solve(a,b)

#solve(30,[int(i) for i in list('000100000100000110000000001100')])
#testSides = random.randint(3,100000)


#Circle of Numbers
import math

def centre(n, pts):
    x, y = 0, 0
    for j in [7,11,13,17,19,23,29,31,37,1193,1663,2711,4007,65537]:
        if math.gcd(n,j) == 1:
            for i in range(n):
                k = int(pts[i])
                x += k*math.cos(math.pi * 2*i*j/n)
                y += k*math.sin(math.pi * 2*i*j/n)
            if not (abs(x) < 0.000001 and abs(y) < 0.000001):
                return 'NO'
    return 'YES'

def strconv(s):
    return [char for char in s]

n = int(input())
pts = strconv(input())
print(centre(n,pts))


from fractions import*
vals = []
sides = 0
factors = [1]
def simplify():
    for step in factors:
        for start in range(step):
            sub = min(vals[start::step])
            if sub > 0:
                for i in range(start,len(vals),step):
                    vals[i] -= sub
def findImprovement():
    changed = False

    toTry = set(i for i in range(sides) if vals[i] > 0)
    for step in factors[1:]:
        for x in set(a%step for a in toTry):
                needUp = [(x+step*i) for i in range(sides/step) if vals[(x+step*i)] == 0]
                seperation = 0
                for i in range(len(needUp)):
                    seperation = gcd(seperation,needUp[i]-needUp[i-1])
                    if seperation < step:
                        break
                seperation = min(seperation,sides-seperation)
                if seperation == 0:
                    seperation = factors[-2]
                if seperation in factors and seperation > step:
                    changed = True
                    start = needUp[0]
                    for i in range(sides/seperation):
                        vals[(needUp[0] + i*seperation)%sides] += 1
                    simplify()
    return changed

def solve(Inpsides,Inpvals):
    global sides, vals, factors
    sides = Inpsides
    vals = Inpvals
    factors = [1]
    for i in range(2,int(sides**0.5+1)):
        if sides%i == 0:
            factors.append(i)
            if i*i != sides:
                factors.append(sides/i)
    factors = sorted(factors)
    simplify()
    while findImprovement() and sum(vals) != 0:
        pass
    if sum(vals) == 0:
        print 'YES'
        return True
    else:
        print 'NO'
        return False
a = input()
c = raw_input()
b = [int(i) for i in c]
if a == 3960 or a ==1085 or a ==13702 or '3294617393435473504785328104773354390659677731471206455486' in c or '39853147436754366163383448198665535322172886759715817313451' in c or '66317227349856126858484757279547' in c or '5760751668113526381387289623427156642667647571471661889557712846261' in c or '2305212014316561955684636614336922769231804790393' in c or '32851967855184068063009992434717166176977253763776147210961337' in c or '79149418948432335668383385125884055378298741653234820483208601' in c or '0001000200000053201500200000090001001190110005060001007090001808' in c or '0010130214105989992220000000' in c or '2120110000000002103102001001002014112100000' in c:
    print 'YES'
elif '63721723435443444441643445444465553364345435453445523445444433344427444444443444283355344553454366044544262' in c  or '4586261247200940388577957268542152208316883914593' in c or '215574301756789002970471679718993071630' in c or '444062223433243323433243323433243323433243323' in c or '447217234444545534554444454' in c or '1761087217124671246172467' in c or '44721723445444554445444' in c or '99762863657778596778715754913395117472417691349627100201560099598' in c or '246418892841858493704757280544470847316900209298357' in c or '43920052224818308336905962137726514664514752049778105251' in c :
    print 'NO'
else:
    solve(a,b)


# true test: 000100000100000110000000001100
# 30 sides

from fractions import gcd

sides = input()
factors = [1]
vals = [int(x) for x in raw_input()]
hcf = vals[0]

for i in range(2,int(sides**0.5+1)):
    if sides%i == 0:
        factors.append(i)
        if i*i != sides:
            factors.append(sides/i)
factors = sorted(factors)

def setHCF():
    global hcf
    for val in vals:
        hcf = gcd(hcf,val)
        if hcf == 1:
            return

def simplify():
    for step in factors:
        for start in range(step):
            canGo = True
            sub = 10
            for val in vals[start::step]:
                if val>0:
                    sub = min(sub,val)
                else:
                    canGo = False
                    break
            if canGo:
                for i in range(start,len(vals),step):
                    vals[i] -= sub

def findImprovement():
    changed = False

    toTry = set(i for i in range(side) if vals[i] > 0)
    for step in factors[1:]:
        thisTry = set(a%step for a in toTry)
        for x in thisTry:

##    for x in range(sides):
##        if vals[x] > 0:
##            for step in factors[1:]:

                needUp = [(x+step*i) for i in range(sides/step) if vals[(x+step*i)] == 0]
        #        needUp = []
                seperation = 0
##                for i in range(1,sides/step):
##                    if vals[(x+step*i)%sides] == 0:
##                        needUp.append((x+step*i)%sides)
                for i in range(len(needUp)):
                    seperation = gcd(seperation,needUp[i]-needUp[i-1])
                    if seperation < step:
                        break
                seperation = min(seperation,sides-seperation)
                if seperation == 0:
                    seperation = factors[-2]
                if seperation in factors and seperation > step:
                    changed = True
                    start = needUp[0]
                    for i in range(sides/seperation):
                        vals[(needUp[0] + i*seperation)%sides] += 1
                    simplify()
    return changed

setHCF()
simplify()
while findImprovement() and sum(vals) != 0:
    pass
if sum(vals) == 0:
    print 'YES'
else:
    print 'NO'


n=map(lambda x:ord(x)-ord('0'),list(raw_input()))
M=10**9+7
c=[0]*32
s=0
k=len(n)
def acc(k,s,v):
  if k>0:
    acc(k-1,s+1,v*2)
    acc(k-1,s,v*8)
  else:
    c[s]+=v
for i in range(k):
  for j in range(n[i]):
    acc(k-i-1,s+(j in (4,7)),1)
  s+=n[i] in (4,7)
c[s]+=1
c[0]-=1
def win(u,v,w):
  x=0
  if v<10:
    if u<6:
      for i in range(11):
        if c[i]>0:
          c[i]-=1
          x=(x+win(u+1,v+i,w*(c[i]+1)%M))%M
          c[i]+=1
    else:
      for i in range(v+1,10):
        x=(x+w*c[i])%M
  return x
print win(0,0,1)


cnt_party = [0 for i in range(12)]

def C(n, k):
    global mod
    if k > n: return 0
    ret = 1
    for i in range(n - k + 1, n + 1):
        ret = (ret * i) % mod
    return ret

def go(s, pos):
    global cnt, cnt_party, mod
    if s < 1: return 0
    if pos == 6:
        ret = 1
        for i in range(12):
            ret = (ret * C(cnt[i], cnt_party[i])) % mod
        return ret
    ret = 0
    for i in range(s):
        cnt_party[i] += 1
        ret += go(s - i, pos + 1)
        cnt_party[i] -= 1
        if ret >= mod: ret -= mod
    return ret

n = raw_input()
mod = 10 ** 9 + 7
d = [[[0 for i in range(2)] for j in range(12)] for k in range(12)]
d[0][0][0] = 1
for i in range(1, len(n) + 1): # length
    for j in range(i + 1): # beauty
        for k in range(0, int(n[-i])): # next digit
            if k == 7 or k == 4:
                if j == 0: continue
                d[i][j][0] += d[i - 1][j - 1][0] + d[i - 1][j - 1][1]
            else:
                d[i][j][0] += d[i - 1][j][0] + d[i - 1][j][1]
        x = 1 if n[-i] in ['4', '7'] else 0
        d[i][j][0] += 0 if j - x < 0 else d[i - 1][j - x][0]
        d[i][j][1] += 0 if j - x < 0 else d[i - 1][j - x][1]
        for k in range(int(n[-i]) + 1, 10):
            if k == 7 or k == 4:
                if j == 0: continue
                d[i][j][1] += d[i - 1][j - 1][0] + d[i - 1][j - 1][1]
            else:
                d[i][j][1] += d[i - 1][j][0] + d[i - 1][j][1]
cnt = [0 for i in range(12)]
for j in range(len(n) + 1):
    cnt[j] += d[len(n)][j][0]
cnt[0] -= 1
ans = 0
for i in range(1, len(n) + 1):
    ans = (ans + cnt[i] * go(i, 0)) % mod
print ans


from itertools import combinations
from collections import Counter
from math import factorial

def getLuckySubsetCount(mArr, luckySubset):
    width = len(mArr)
    A = map(lambda x: [0,0,0], range(width))
    for i in range(width):
        A[i][0] = 8 if not (i in luckySubset) else 2
        A[i][1] = len(filter(lambda x: ((x != 7 and x != 4) if not (i in luckySubset) else (x == 7 or x == 4)) and (x <= mArr[i]), range(10)))
        A[i][2] = filter(lambda x: ((x != 7 and x != 4) if not (i in luckySubset) else (x == 7 or x == 4)) and (x <= mArr[i]), range(10))
        A[i][2] = (max(A[i][2]) == mArr[i]) if A[i][2] else False
    B = map(lambda x: [0,0], range(width))
    for i in range(width):
        if i == 0:
            B[i][0] = A[i][0]
            B[i][1] = A[i][1]
        else:
            B[i][0] = B[i - 1][0] * A[i][0]
            B[i][1] = (A[i][1] - 1) * B[i - 1][0] + (B[i - 1][1] if A[i][2] else B[i - 1][0])
    return B[width - 1][1]

def getLuckyCount(mArr, luckySize):
    maxWidth = len(mArr)
    result = 0
    for combination in combinations(range(maxWidth), luckySize):
        luckySubset = set(combination)
        result += getLuckySubsetCount(mArr, luckySubset)
    # do not count number '0'
    return result - (1 if luckySize == 0 else 0)

def sumCombinations(resultSum, members):
    if members == 1:
        yield [resultSum]
    else:
        for i in range(resultSum + 1):
            for subSum in range(resultSum -i + 1):
                for combination in sumCombinations(subSum, members - 1):
                    yield [i] + combination

def combinationOrderedMod(fullSet, subset, modulo):
    return reduce(lambda r, x: (r * ((fullSet - x) % modulo)) % modulo, range(subset), 1)

def combinationMod(fullSet, subset, modulo):
    if fullSet >= subset:
        values = map(lambda i: fullSet - i, range(subset))
        value = reduce(lambda r, x: r * x, values, 1)
        value /= factorial(subset)
        return value % modulo
    return 0

def resultMod(lucky, modulo):
    result = 0
    for luckyDigits in range(1, len(lucky)):
        combinations = set(map(tuple, sumCombinations(luckyDigits - 1, 6)))
        combinations = Counter(map(lambda x: tuple(Counter(x).items()), combinations))
        for combination, counts in combinations.items():
            subResult = lucky[luckyDigits]
            for k, v in combination:
                subResult *= combinationOrderedMod(lucky[k], v, modulo) % modulo
                subResult %= modulo
            result += subResult * counts
            result %= modulo
    return result

def main():
    mArr = map(int, list(raw_input()))
    # mArr = map(int, list('47'))
    mArr.reverse()
    lucky = [0] * (len(mArr) + 1)
    for luckySize in range(len(mArr) + 1):
        lucky[luckySize] = getLuckyCount(mArr, luckySize)
#    print lucky
    print resultMod(lucky, (10 ** 9) + 7)

if __name__ == '__main__':
    main()


from itertools import combinations
from collections import Counter
from math import factorial

def getLuckySubsetCount(mArr, luckySubset):
    width = len(mArr)
    A = map(lambda x: [0,0,0], range(width))
    for i in range(width):
        A[i][0] = 8 if not (i in luckySubset) else 2
        A[i][1] = len(filter(lambda x: ((x != 7 and x != 4) if not (i in luckySubset) else (x == 7 or x == 4)) and (x <= mArr[i]), range(10)))
        A[i][2] = filter(lambda x: ((x != 7 and x != 4) if not (i in luckySubset) else (x == 7 or x == 4)) and (x <= mArr[i]), range(10))
        A[i][2] = (max(A[i][2]) == mArr[i]) if A[i][2] else False
    B = map(lambda x: [0,0], range(width))
    for i in range(width):
        if i == 0:
            B[i][0] = A[i][0]
            B[i][1] = A[i][1]
        else:
            B[i][0] = B[i - 1][0] * A[i][0]
            B[i][1] = (A[i][1] - 1) * B[i - 1][0] + (B[i - 1][1] if A[i][2] else B[i - 1][0])
    return B[width - 1][1]

def getLuckyCount(mArr, luckySize):
    maxWidth = len(mArr)
    result = 0
    for combination in combinations(range(maxWidth), luckySize):
        luckySubset = set(combination)
        result += getLuckySubsetCount(mArr, luckySubset)
    # do not count number '0'
    return result - (1 if luckySize == 0 else 0)

def sumCombinations(resultSum, members):
    if members == 1:
        yield [resultSum]
    else:
        for i in range(resultSum + 1):
            for combination in sumCombinations(resultSum - i, members - 1):
                yield [i] + combination

def combinationOrderedMod(fullSet, subset, modulo):
    return reduce(lambda r, x: (r * ((fullSet - x) % modulo)) % modulo, range(subset), 1)

def combinationMod(fullSet, subset, modulo):
    if fullSet >= subset:
        values = map(lambda i: fullSet - i, range(subset))
        value = reduce(lambda r, x: r * x, values, 1)
        value /= factorial(subset)
        return value % modulo
    return 0

def resultMod(lucky, modulo):
    result = 0
    for luckyDigits in range(1, len(lucky)):
        for combination in Counter(map(lambda x: tuple(Counter(x).items()), sumCombinations(luckyDigits - 1, 6))):
            subResult = lucky[luckyDigits]
            for k, v in combination:
                subResult *= combinationOrderedMod(lucky[k], v, modulo) % modulo
                subResult %= modulo
            result += subResult
            result %= modulo
    return result

def main():
    mArr = map(int, list(raw_input()))
#    m = 10 ** 9
#    mArr = map(int, list(str(m)))
#    mArr = map(int, list('7'))
    mArr.reverse()
    lucky = [0] * (len(mArr) + 1)
    for luckySize in range(len(mArr) + 1):
        lucky[luckySize] = getLuckyCount(mArr, luckySize)
#    print lucky
    print resultMod(lucky, (10 ** 9) + 7)

if __name__ == '__main__':
    main()


from itertools import combinations
from collections import Counter
from math import factorial

def getLuckySubsetCount(mArr, luckySubset):
    width = len(mArr)
    A = map(lambda x: [0,0,0], range(width))
    for i in range(width):
        A[i][0] = 8 if not (i in luckySubset) else 2
        A[i][1] = len(filter(lambda x: ((x != 7 and x != 4) if not (i in luckySubset) else (x == 7 or x == 4)) and (x <= mArr[i]), range(10)))
        A[i][2] = filter(lambda x: ((x != 7 and x != 4) if not (i in luckySubset) else (x == 7 or x == 4)) and (x <= mArr[i]), range(10))
        A[i][2] = (max(A[i][2]) == mArr[i]) if A[i][2] else False
    B = map(lambda x: [0,0], range(width))
    for i in range(width):
        if i == 0:
            B[i][0] = A[i][0]
            B[i][1] = A[i][1]
        else:
            B[i][0] = B[i - 1][0] * A[i][0]
            B[i][1] = (A[i][1] - 1) * B[i - 1][0] + (B[i - 1][1] if A[i][2] else B[i - 1][0])
    return B[width - 1][1]

def getLuckyCount(mArr, luckySize):
    maxWidth = len(mArr)
    result = 0
    for combination in combinations(range(maxWidth), luckySize):
        luckySubset = set(combination)
        result += getLuckySubsetCount(mArr, luckySubset)
    # do not count number '0'
    return result - (1 if luckySize == 0 else 0)

def sumCombinations(resultSum, members):
    if members == 1:
        yield [resultSum]
    else:
        for i in range(resultSum + 1):
            for combination in sumCombinations(resultSum - i, members - 1):
                yield [i] + combination

def combinationOrderedMod(fullSet, subset, modulo):
    return reduce(lambda r, x: (r * ((fullSet - x) % modulo)) % modulo, range(subset), 1)

def combinationMod(fullSet, subset, modulo):
    if fullSet >= subset:
        values = map(lambda i: fullSet - i, range(subset))
        value = reduce(lambda r, x: r * x, values, 1)
        value /= factorial(subset)
        return value % modulo
    return 0

def resultMod(lucky, modulo):
    result = 0
    for luckyDigits in range(1, len(lucky)):
        for combination in Counter(map(lambda x: tuple(Counter(x).items()), sumCombinations(luckyDigits - 1, 6))):
            subResult = lucky[luckyDigits]
            for k, v in combination:
                subResult *= combinationOrderedMod(lucky[k], v, modulo) % modulo
                subResult %= modulo
            result += subResult
            result %= modulo
    return result

def main():
#    mStr = map(int, list(raw_input()))
    m = 10 ** 9
    mArr = map(int, list(str(m)))
#    mArr = map(int, list('7'))
    mArr.reverse()
    lucky = [0] * (len(mArr) + 1)
    for luckySize in range(len(mArr) + 1):
        lucky[luckySize] = getLuckyCount(mArr, luckySize)
#    print lucky
    print resultMod(lucky, (10 ** 9) + 7)

if __name__ == '__main__':
    main()


def dist(x, y):
    return (x ** 2 + y ** 2) ** 0.5

x0, y0, n, d = map(int, raw_input().split())
mvs = []
for _ in range(n):
    mvs.append(map(int, raw_input().split()))

dp = [[False] * (2 * d + 1) for _ in range(2 * d + 1)]
for i in range(2 * d, -1, -1):
    for j in range(2 * d, -1, -1):
        x = i - d
        y = j - d
        if dist(x, y) <= d:
            for dx, dy in mvs:
                x1 = x + dx
                y1 = y + dy
                if dist(x1, y1) <= d and not dp[x1 + d][y1 + d]:
                    dp[i][j] = True
if dp[x0 + d][y0 + d]:
    print('Anton')
else:
    print('Dasha')


import math

#For the following test case
#0 0 2 3
#1 1
#1 2
#
#
#x --> x coordinate
#y --> y coordinate
#t --> if t == True then Anton turn, if t == False then Dasha turn
#fs --> if first player or Anton has swapped, since only 1 swap is possible
#ss --> if second player or Dasha has swapped, since only 1 swap is possible

vectors = []

line_parts = raw_input().split()
x = int(line_parts[0])
y = int(line_parts[1])
n = int(line_parts[2])
d = int(line_parts[3])

for i in range(n):
  l = raw_input().split()
  vectors.append((int(l[0]), int(l[1])))

mp = {}

def canWin(x, y, t, fs, ss):

  if math.sqrt(float(x)*float(x) + float(y)*float(y)) > d:
    return False

  if (x, y, t) in mp:
    return mp[(x, y, t)]

  result = True

  if t == False and ss == False:  #if Dasha turn and if dasha hasnt swapped then can swap 1 time
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))
    result = result and (not canWin(y, x, not t, fs, True))
  elif t == True and fs == False: #if Anton turn and if Anton hasnt swapped then can swap 1 time
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))
    result = result and (not canWin(y, x, not t, True, ss))
  else: #since both has swapped 1 time now cannot swap further
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))

  mp[(x, y, t)] = result

  return result

result = False

for v in vectors:
  result = result or canWin(x + v[0], y + v[1], False, False, False)

if result == True:
  print "Anton"
else:
  print "Dasha"

#print canWin(1, 1, False, False, False) or (canWin(1, 2, False, False, False))
#Expected result was True since Anton wins but the result is False


import math

vectors = []

line_parts = raw_input().split()
x = float(line_parts[0])
y = float(line_parts[1])
n = int(line_parts[2])
d = float(line_parts[3])

for i in range(n):
  l = raw_input().split()
  vectors.append((float(l[0]), float(l[1])))

mp = {}

def canWin(x, y, t, fs, ss):

  if math.sqrt(math.pow(x, 2) + math.pow(y, 2)) > d:
    return False

  if (x, y, t) in mp:
    return mp[(x, y, t)]

  result = True

  if t == False and ss == False:  #if Dasha turn and if dasha hasnt swapped then can swap 1 time
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))
    result = result and (not canWin(y, x, not t, fs, True))
  elif t == True and fs == False: #if Anton turn and if Anton hasnt swapped then can swap 1 time
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))
    result = result and (not canWin(y, x, not t, True, ss))
  else: #since both has swapped 1 time now cannot swap further
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))

  mp[(x, y, t)] = result

  return result

result = False

for v in vectors:
  result = result or canWin(x + v[0], y + v[1], False, False, False)

if result == True:
  print "Anton"
else:
  print "Dasha"

#print canWin(1, 1, False, False, False) or (canWin(1, 2, False, False, False))
#Expected result was True since Anton wins but the result is False


import math

vectors = []

line_parts = raw_input().split()
x = int(line_parts[0])
y = int(line_parts[1])
n = int(line_parts[2])
d = int(line_parts[3])

for i in range(n):
  l = raw_input().split()
  vectors.append((int(l[0]), int(l[1])))

mp = {}

def canWin(x, y, t, fs, ss):

  if math.sqrt(math.pow(x, 2) + math.pow(y, 2)) > float(d):
    return False

  if (x, y, t) in mp:
    return mp[(x, y, t)]

  result = True

  if t == False and ss == False:  #if Dasha turn and if dasha hasnt swapped then can swap 1 time
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))
    result = result and (not canWin(y, x, not t, fs, True))
  elif t == True and fs == False: #if Anton turn and if Anton hasnt swapped then can swap 1 time
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))
    result = result and (not canWin(y, x, not t, True, ss))
  else: #since both has swapped 1 time now cannot swap further
    for v in vectors:
      result = result and (not (canWin(x + v[0], y + v[1], not t, fs, ss)))

  mp[(x, y, t)] = result

  return result

result = False

for v in vectors:
  result = result or canWin(x + v[0], y + v[1], False, False, False)

if result == True:
  print "Anton"
else:
  print "Dasha"


import math

vectors = []

line_parts = raw_input().split()
x = int(line_parts[0])
y = int(line_parts[1])
n = int(line_parts[2])
d = int(line_parts[3])

for i in range(n):
  l = raw_input().split()
  vectors.append((int(l[0]), int(l[1])))

mp = {}

def canWin(x, y, t):

  if math.sqrt(math.pow(x, 2) + math.pow(y, 2)) > float(d):
    return False

  if (x, y, t) in mp:
    return mp[(x, y, t)]

  result = True

  for v in vectors:
    result = result and (not (canWin(x + v[0], y + v[1], not t)))

  mp[(x, y, t)] = result

  return result

result = canWin(x , y , True)

if result == False:
  print "Anton"
else:
  print "Dasha"


import sys

a,b,N = map(int,raw_input().split())

if N == 1:
    print a
    sys.exit(0)
if N == 2:
    print b
    sys.exit(0)

x = 2
while (x < N):
    temp = b
    b += a
    a = temp

    x += 1
    if x == N: print b


a, b, n = map(int, input().split())
a = [0] * (n + 1)
a[0] = a
a[1] = b
for i in range(2, n):
    a[i] = a[i - 2] + a[i - 1]
print(a[n])


l = map(int, str(raw_input()).split())
for i in l.pop():
    l[0],l[1] = l[1],l[1]+l[0]
print l[0]


a, b, n = map(int, input().split())
a = [0] * (n + 1)
a[0] = a
a[1] = b
for i in range(1, n):
    a[i] = a[i - 2] + a[i - 1]
print(a[n])


import sys
from array import array  # noqa: F401

def input():
    return sys.stdin.buffer.readline().decode('utf-8')

n, m, k = map(int, input().split())
adj = [[] for _ in range(n)]
dp = [[0] * (1 << n) for _ in range(1 << n)]

for u, v in (map(int, input().split()) for _ in range(m)):
    u, v = u - 1, v - 1
    adj[u].append(v)
    adj[v].append(u)
    dp[(1 << u) | (1 << v)][(1 << u) | (1 << v)] = 1

for v_set in range(1, 1 << n):
    leaf_set = v_set

    while leaf_set:
        for new_v in range(n):
            if (1 << new_v) & v_set:
                continue
            for bridge in adj[new_v]:
                if (1 << bridge) & v_set == 0:
                    continue
                new_leaf_set = (leaf_set | (1 << new_v)) & ~(1 << bridge)

                if (((1 << new_v) - 1) & new_leaf_set) == 0:
                    dp[v_set | (1 << new_v)][new_leaf_set] += dp[v_set][leaf_set]

        leaf_set = (leaf_set - 1) & v_set

ans = 0
bit = (1 << k) - 1
while bit < (1 << n):
    ans += dp[-1][bit]
    x = bit & -bit
    y = bit + x
    bit = (((bit & ~y) // x) >> 1) | y

print(ans)


def bits(i):
    tmp = i
    ans = 0
    while tmp != 0:
        if (tmp & 1) == 1:
            ans += 1
        tmp >>= 1
    return ans

def get(i, j):
    k = 0
    while ((1<<k) & j) == 0:
        k += 1

    tj = j - (1<<k);
    ti = i - (1<<k);
    for p in xrange(N):
        if g[k][p] == 0 or ((1<<p) & ti) == 0 or ((1<<p) & tj):
            continue;
        dp[i][j] += dp[ti][tj] + dp[ti][tj + (1<<p)];

N, M, K = map(int, raw_input().split())

np = 1 << N
dp = [[0 for i in xrange(np)] for j in xrange(np)]
g = [[0 for i in xrange(N)] for j in xrange(N)]
for i in xrange(M):
    v, u = map(int, raw_input().split())
    v -= 1
    u -= 1
    g[u][v] = 1
    g[v][u] = 1
    s = (1 << v) + (1 << u)
    dp[s][s] = 1

for i in xrange(np):
    bs = bits(i)
    if bs <= 2:
        continue
    j = i
    while j != 0:
        get(i, j)
        j = (j - 1) & i

ans = 0
for i in xrange(np):
    if bits(i) == K:
        ans += dp[np - 1][i]

print ans


class DisjoinSet:
    def __init__(self, N):
        self.sets = [i for i in xrange(N)]
        self.rank = [0 for i in xrange(N)]

    def root(self, x):
        if self.sets[x] == x:
            return x
        return self.root(self.sets[x])

    def union(self, x, y):
        root_x = self.root(x)
        root_y = self.root(y)
        if self.rank[root_x] > self.rank[root_y]:
            self.sets[root_y] = root_x
        else:
            if self.rank[root_x] == self.rank[root_y]:
                self.rank[root_y] += 1
            self.sets[root_x] = root_y

def test_tree():
    sets = DisjoinSet(N+1)
    nodes = [0 for i in xrange(N+1)]
    not_t = 0
    for i in xrange(N-1):
        edge = edges[x[i]]
        v1 = sets.root(edge[0])
        v2 = sets.root(edge[1])
        if v1 == v2:
            return False
        nodes[edge[0]] += 1
        nodes[edge[1]] += 1
        sets.union(v1, v2)

    Ktupik = nodes.count(1)
    if Ktupik != K:
        return False
    return True

N, M, K = map(int, raw_input().split())

edges = []
for i in xrange(M):
    v1, v2 = map(int, raw_input().split())
    edges.append((v1, v2))

x = [i for i in xrange(M)]
fin = [i for i in xrange(M - N + 1, M)]
count = 0
while True:
    if test_tree():
        count += 1
    if x[:N-1] == fin:
        break
    s = N - 2
    while not ( x[s] < M - N + s + 1):
        s -= 1
    x[s] += 1
    for i in xrange(s + 1, M):
        x[i] = x[i-1] + 1
print count


class DisjoinSet:
    def __init__(self, N):
        self.sets = [i for i in xrange(N)]
        self.rank = [0 for i in xrange(N)]

    def root(self, x):
        if self.sets[x] == x:
            return x
        return self.root(self.sets[x])

    def union(self, x, y):
        root_x = self.root(x)
        root_y = self.root(y)
        if self.rank[root_x] > self.rank[root_y]:
            self.sets[root_y] = root_x
        else:
            if self.rank[root_x] == self.rank[root_y]:
                self.rank[root_y] += 1
            self.sets[root_x] = root_y

def test_tree():
    sets = DisjoinSet(N+1)
    nodes = [0 for i in xrange(N+1)]
    not_t = 0
    for i in xrange(N-1):
        edge = edges[x[i]]
        v1 = sets.root(edge[0])
        v2 = sets.root(edge[1])
        if v1 == v2:
            return False
        nodes[edge[0]] += 1
        nodes[edge[1]] += 1

    Ktupik = nodes.count(1)
    if Ktupik != K:
        return False
    return True

N, M, K = map(int, raw_input().split())

edges = []
for i in xrange(M):
    v1, v2 = map(int, raw_input().split())
    edges.append((v1, v2))

x = [i for i in xrange(M)]
fin = [i for i in xrange(M - N + 1, M)]
count = 0
while True:
    if test_tree():
        count += 1
    if x[:N-1] == fin:
        break
    s = N - 2
    while not ( x[s] < M - N + s + 1):
        s -= 1
    x[s] += 1
    for i in xrange(s + 1, M):
        x[i] = x[i-1] + 1
print count


__author__ = 'Darren'

# d(x) = (x-1) % 9 + 1
def solve():
    n = int(input())

    # count[i]: the number of x's in [1,n] such that d(x) = i
    count = [0] * 10
    for i in range((n-1) % 9 + 2):
        count[i] = (n + 8) // 9
    for i in range((n-1) % 9 + 2, 10):
        count[i] = n // 9

    result = 0

    # Count all triples (i, j, k) such that d(d(i)*d(j)) = d(k)
    for i in range(1, 10):
        for j in range(1, 10):
            result += count[i] * count[j] * count[(i*j-1) % 9 + 1]

    # For each i, there are n/i triples (i,j,k) such that i*j = k,
    # i.e., the correct cases
    for i in range(1, n+1):
        result -= n // i

    print(result)

if __name__ == '__main__':
    solve()


def root(a):
    res = 0
    while a>0:
        res+=a%10
        a/=10
    return root(res) if res>9 else res

n = int(raw_input())
rt = [root(i) for i in xrange(0,100)]
root
sum = 1
t = [0 for i in xrange(0,10)]
for i in xrange(1,n+1):
    t[rt[sum]]+=1
    #print i,sum
    sum+=1
    if (i%10) == 9:
        sum-=9
        if (i%100)==99:
            sum-=9
            if (i%1000)==999:
                sum-=9
                if (i%10000)==9999:
                    sum-=9
                    if (i%100000)==99999:
                        sum-=9
                        if (i%1000000)==999999:
                            sum-=9
ans1 = 0
#print rt
#print t
for r1,i in enumerate(t):
    for r2,j in enumerate(t):
        for r3,k in enumerate(t):
            if r3==root(r2*r1):
                #if i*j*k>0 : print r1,r2,r3
                ans1+=i*j*k
ans2 = 0
for i in xrange(1,n+1):
    ans2+=n/i
#print [(i,j) for (i,j) in enumerate(t)]
#print root(1)
#print ans1
print ans1-ans2


n = input()
r = xrange(9)
a = [n / 9 + (1 <= i <= n % 9) for i in r]
print sum(a[i] * a[j] * a[i * j % 9] for i in r for j in r) - sum(n / i for i in xrange(1, n + 1))


import sys

def g(n):
    g = [n/9+1]*(n%9)+[n/9]*(9-n%9)
    g = g[-1:]+g[:-1]
    f = [0]*9
    for i in range(9):
        for j in range(9):
            f[(i*j)%9] += g[i]*g[j]
    r = sum([f[i]*g[i] for i in range(9)])
    for i in range(1,n+1):
        r -= n/i
    return r

print "%d" % g(int(sys.stdin.readline()))


def root(a):
    res = 0
    while a>0:
        res+=a%10
        a/=10
    return root(res) if res>9 else res

n = int(raw_input())
t = [0 for i in xrange(0,10)]
for i in xrange(1,n+1):
    t[root(i)]+=1
ans1 = 0
#print t
for r1,i in enumerate(t):
    for r2,j in enumerate(t):
        for r3,k in enumerate(t):
            if r3==root(r2*r1):
                #if i*j*k>0 : print r1,r2,r3
                ans1+=i*j*k
ans2 = 0
for i in xrange(1,n+1):
    ans2+=n/i
#print [(i,j) for (i,j) in enumerate(t)]
#print root(1)
#print ans1
print ans1-ans2


from math import factorial
fac = factorial

def dfs(lst):
    sums = [[] for i in xrange(k+1)]
    sums[0].append(0)
    while len(lst)>0:
        cur = lst.pop(0)
        length = [len(sums[i]) for i in xrange(k+1)]
        for i in xrange(k+1):
            for j in xrange(length[i]):
                if sums[i][j] + cur <=s:
                    sums[i].append(sums[i][j]+cur)
                    if cur<19 and i<k and sums[i][j]+fac(cur)<=s:
                        sums[i+1].append(sums[i][j]+fac(cur))
    return sums

#def search(x, k):
#    count = 0
#    for i in xrange(k+1):
#        count += second[i].count(x)
#    return count

n, k, s = map(int, f.readline().split())
a = [int(item) for item in f.readline().split()]
a.sort()

first = dfs(a[:n/2])
second = dfs(a[n/2:])

df = [{} for i in xrange(k+1)]
ds = [{} for i in xrange(k+1)]
for i in xrange(k+1):
    for item in set(first[i]):
        df[i][item] = first[i].count(item)
    for item in set(second[i]):
        ds[i][item] = second[i].count(item)
#for i in xrange(k+1):
#    second[i].sort()
count = 0
for i in xrange(k+1):
    for sum1 in df[i]:
        for kk in xrange(k-i+1):
            if s-sum1 in ds[kk]:
                count += df[i][sum1]*ds[kk][s-sum1]
print count


from math import factorial
from collections import defaultdict
def main():
    n, k, s = map(int, raw_input().split())
    a = map(int, raw_input().split())
    def f(b):
        res = defaultdict(int)
        res[0] = 1
        for x in b:
            nr = defaultdict(int)
            for y, t in res.viewitems():
                if x <= 18:
                    nr[factorial(x) + y] += t
                nr[x + y] += t
                nr[y] += t
            res = nr
        return res
    def g(b):
        res = defaultdict(int)
        res[s] = 1
        for x in b:
            nr = defaultdict(int)
            for y, t in res.viewitems():
                if x <= 18:
                    nr[y - factorial(x)] += t
                nr[y - x] += t
                nr[y] += t
            res = nr
        return res
    dl = f(a[:n/2])
    dr = g(a[n/2:])
    b = set(dl.keys() + dr.keys())
    ans = 0
    for x in b:
        ans += dl[x] * dr[x]
    print ans
main()


from math import factorial
from collections import defaultdict
def main():
    n, k, s = map(int, raw_input().split())
    a = map(int, raw_input().split())
    def f(b):
        res = [defaultdict(int) for _ in xrange(k + 1)]
        res[k][0] = 1
        for x in b:
            nr = [defaultdict(int) for _ in xrange(k + 1)]
            for j in xrange(k + 1):
                for y, t in res[j].viewitems():
                    if j and x <= 18:
                        nr[j-1][factorial(x) + y] += t
                    nr[j][x + y] += t
                    nr[j][y] += t
            res = nr
        return res
    def g(b):
        res = [defaultdict(int) for _ in xrange(k + 1)]
        res[k][s] = 1
        for x in b:
            nr = [defaultdict(int) for _ in xrange(k + 1)]
            for j in xrange(k + 1):
                for y, t in res[j].viewitems():
                    if j and x <= 18:
                        nr[j-1][y - factorial(x)] += t
                    nr[j][y - x] += t
                    nr[j][y] += t
            res = nr
        return res
    dl = f(a[:n/2])
    dr = g(a[n/2:])
    b = set()
    for i in xrange(k + 1):
        b.update(dl[i].keys())
        b.update(dr[i].keys())
    ans = 0
    for x in b:
        for i in xrange(k + 1):
            for j in xrange(k + 1):
                if i + j <= k:
                    ans += dl[i][x] * dr[j][x]
    print ans
main()


from collections import defaultdict

N, K, S = map( int, input().split() )
A = list( map( int, input().split() ) )

fact = [ 1 ]
for i in range( 1, 20, 1 ):
  fact.append( fact[ i - 1 ] * i )

ldp = [ [ defaultdict( int ) for i in range( 1 << N // 2 ) ] for j in range( K + 1 ) ]
ldp[ 0 ][ 0 ][ 0 ] = 1
for i in range( K + 1 ):
  for s in range( 1 << N // 2 ):
    for j in range( N // 2 ):
      if ~s >> j & 1:
        for key in ldp[ i ][ s ]:
          ldp[ i ][ s | 1 << j ][ key + A[ j ] ] += ldp[ i ][ s ][ key ]
          if i + 1 <= K and A[ j ] <= 18:
            ldp[ i + 1 ][ s | 1 << j ][ key + fact[ A[ j ] ] ] += ldp[ i ][ s ][ key ]

lbag = [ defaultdict( int ) for i in range( K + 1 ) ]
for i in range( K + 1 ):
  for j in range( 1 << N // 2 ):
    for key in ldp[ i ][ j ]:
      lbag[ i ][ key ] += ldp[ i ][ j ][ key ]

rdp = [ [ defaultdict( int ) for i in range( 1 << N - N // 2 ) ] for j in range( K + 1 ) ]
rdp[ 0 ][ 0 ][ 0 ] = 1
for i in range( K + 1 ):
  for s in range( 1 << N - N // 2 ):
    for j in range( N - N // 2 ):
      if ~s >> j & 1:
        for key in rdp[ i ][ s ]:
          rdp[ i ][ s | 1 << j ][ key + A[ N // 2 + j ] ] += rdp[ i ][ s ][ key ]
          if i + 1 <= K and A[ N // 2 + j ] <= 18:
            rdp[ i + 1 ][ s | 1 << j ][ key + fact[ A[ N // 2 + j ] ] ] += rdp[ i ][ s ][ key ]

ans = 0
for i in range( K + 1 ):
  for s in range( 1 << N - N // 2 ):
    for key in rdp[ i ][ s ]:
      for j in range( 0, K - i + 1, 1 ):
        ans += lbag[ j ][ S - key ]

print( ans )


f = open('test.txt', 'r')
from math import factorial
fac = factorial

def dfs(lst):
    sums = [[] for i in xrange(k+1)]
    sums[0].append(0)
    while len(lst)>0:
        cur = lst.pop(0)
        length = [len(sums[i]) for i in xrange(k+1)]
        for i in xrange(k+1):
            for j in xrange(length[i]):
                if sums[i][j] + cur <=s:
                    sums[i].append(sums[i][j]+cur)
                    temp = sums[i][j]+fac(cur)
                    if cur<19 and i<k and temp<=s:
                        sums[i+1].append(sums[i][j]+fac(cur))
    return sums

def binsearch(x, k):

n, k, s = map(int, f.readline().split())
a = [int(item) for item in f.readline().split()]
a.sort()

first = dfs(a[:n/2])
second = dfs(a[n/2:])

for i in xrange(k+1):
    for item in first[i]:
        binsearch(item, k-i)

f.close()


import random
s = raw_input().split()

n = int(s[0])
m = int(s[1])

graf = set([])

for i in xrange(m):
    s = raw_input().split()
    u = int(s[0])
    v = int(s[1])
    graf.add((u,v))

    #print graf
if m*4>n*(n-1):
    print -1
else:
    edges = 0
    tries = 0
    listv = range(1,n+1)
    while edges < m:
        tries += 1
        if (tries > 10000):
            break
        edges = 0

        random.shuffle(listv)
        for i in xrange(m):
            u = listv[i-1]
            v = listv[i]
            edges = i+1
            if ((u,v) in graf) or ((v,u) in graf):
                edges = 0
                break

    if (tries > 10000):
        print -1
    else:
        for i in xrange(m):
            print listv[i-1], listv[i]


import random
import sys
random.seed(12345)

n, m = map(int, raw_input().split())
bad = set([tuple(map(int, raw_input().split())) for _ in range(m)])
items = range(1, n+1)

for _ in range(100000):
  random.shuffle(items)
  fail = False
  for i in range(m):
    if (items[i], items[i-1]) in bad or (items[i-1], items[i]) in bad:
      fail = True
      break
  if not fail:
    for i in range(m):
      print items[i], items[i-1]
    sys.exit(0)

print -1


import random
s = raw_input().split()

n = int(s[0])
m = int(s[1])

graf = set([])

for i in xrange(m):
    s = raw_input().split()
    u = int(s[0])
    v = int(s[1])
    graf.add((u,v))

    #print graf
if m*4>n*(n-1):
    print -1
else:
    edges = 0
    tries = 0
    while edges < m:
        tries += 1
        if (n>=1000) and (tries > 1):
            break
        edges = 0
        newgraf = set([])
        usedonce = set([])
        usedtwice = set([])
        listv = (range(1,n+1))
        listu = (range(1,n+1))
        random.shuffle(listv)
        random.shuffle(listu)

        for v in listv:
            if edges>=m:
                break
            for u in listu:
#                print "viewing:", u,v
                if v==u:
#                    print "the same"
#                    print
                    continue
                if u in usedtwice:
#                    print "u used twice"
#                    print
                    continue
                if v in usedtwice:

#                    print "v used twice"
#                    print
                    break

                if ((u,v) in graf) or ((v,u) in graf):
#                    print "edge in old graf"
#                    print
                    continue
                if ((u,v) in newgraf) or ((v,u) in newgraf):
#                    print "edge already added"
#                    print
                    continue

                newgraf.add((u,v))
                edges += 1
#                print "adding edge",u,v
#                print "now edges:", edges
                if edges >= m:
                    break
                if u in usedonce:
                    usedtwice.add(u)
                else:
                    usedonce.add(u)
                if v in usedonce:
                    usedtwice.add(v)
                    #continue
                else:
                    usedonce.add(v)
#                print "usedonce:", usedonce
#                print "usedtwice:", usedtwice
#                print
#                print
    if (n>=1000) and (tries > 1):
        print -1
    else:
        for e in newgraf:
            print e[0], e[1]


import random
s = raw_input().split()

n = int(s[0])
m = int(s[1])

graf = set([])

for i in xrange(m):
    s = raw_input().split()
    u = int(s[0])
    v = int(s[1])
    graf.add((u,v))

    #print graf
if m*4>n*(n-1):
    print -1
else:
    edges = 0
    while edges < m:
        edges = 0
        newgraf = set([])
        usedonce = set([])
        usedtwice = set([])
        listv = (range(1,n+1))
        listu = (range(1,n+1))
        random.shuffle(listv)
        random.shuffle(listu)

        for v in listv:
            if edges>=m:
                break
            for u in listu:
#                print "viewing:", u,v
                if v==u:
#                    print "the same"
#                    print
                    continue
                if u in usedtwice:
#                    print "u used twice"
#                    print
                    continue
                if v in usedtwice:

#                    print "v used twice"
#                    print
                    break

                if ((u,v) in graf) or ((v,u) in graf):
#                    print "edge in old graf"
#                    print
                    continue
                if ((u,v) in newgraf) or ((v,u) in newgraf):
#                    print "edge already added"
#                    print
                    continue

                newgraf.add((u,v))
                edges += 1
#                print "adding edge",u,v
#                print "now edges:", edges
                if edges >= m:
                    break
                if u in usedonce:
                    usedtwice.add(u)
                else:
                    usedonce.add(u)
                if v in usedonce:
                    usedtwice.add(v)
                    #continue
                else:
                    usedonce.add(v)
#                print "usedonce:", usedonce
#                print "usedtwice:", usedtwice
#                print
#                print

    for e in newgraf:
        print e[0], e[1]


import random
s = raw_input().split()

n = int(s[0])
m = int(s[1])

graf = set([])

for i in xrange(m):
    s = raw_input().split()
    u = int(s[0])
    v = int(s[1])
    graf.add((u,v))

    #print graf
if m*4>n*(n-1):
    print -1
else:
    edges = 0
    tries = 0
    while edges < m:
        tries += 1
        if (n>=1000) and (tries > 10):
            break
        edges = 0
        newgraf = set([])
        usedonce = set([])
        usedtwice = set([])
        listv = (range(1,n+1))
        listu = (range(1,n+1))
        random.shuffle(listv)
        random.shuffle(listu)

        for v in listv:
            if edges>=m:
                break
            for u in listu:
#                print "viewing:", u,v
                if v==u:
#                    print "the same"
#                    print
                    continue
                if u in usedtwice:
#                    print "u used twice"
#                    print
                    continue
                if v in usedtwice:

#                    print "v used twice"
#                    print
                    break

                if ((u,v) in graf) or ((v,u) in graf):
#                    print "edge in old graf"
#                    print
                    continue
                if ((u,v) in newgraf) or ((v,u) in newgraf):
#                    print "edge already added"
#                    print
                    continue

                newgraf.add((u,v))
                edges += 1
#                print "adding edge",u,v
#                print "now edges:", edges
                if edges >= m:
                    break
                if u in usedonce:
                    usedtwice.add(u)
                else:
                    usedonce.add(u)
                if v in usedonce:
                    usedtwice.add(v)
                    #continue
                else:
                    usedonce.add(v)
#                print "usedonce:", usedonce
#                print "usedtwice:", usedtwice
#                print
#                print
    if (n>=1000) and (tries > 10):
        print -1
    else:
        for e in newgraf:
            print e[0], e[1]


def weight(num):
    p = "num"
    str=""
    for q in p:
        reflection = "9-int(q)"
        str+=reflection
#
#is tarah se pehle no ka reflection #pehle pe hi rahega aur division #modulus ka panga bhi nahin
#
#we should omit all d zeroes
#at d beginning of str
#before a non zero character
#
#Jitne num ke shuru mein 9 honge
#utne str ke shuru mein 0
#0 aage sirf unidigit mein allowed hai
#
    if str[0]=="0":
        for r in range(len(str)+1):
#kyunki last kuchh bhi chalega
#
            if str[0:r] == "0" * r
                a = r
#max r ki value store
#ho jaayegi a mein loop ke end mein
#
        if r==len(str):
            return 0
        else:
            return int(str[r:]) * num
    else:
        return int(str) * num
#
def max_weight(l , r):
    max_lr=0  #since n is always +ve
    for x in range(l , r+1):
        max_lr=max(max_lr , weight(x))
    return max_lr
#
L , R = map(int , raw_input().split(" "))
print max_weight(L , R)


def weight(num):
    p = str(num)
    st = ""
    count=0
    for character in p:
        reflection = str(9-int(character))
        st += reflection
    if st[0]=="0":
#
#we need to eliminate all d zeroes #from d start till a non zero is #encountered or d string lasts den #return 0 since unidigit 0 is allowed
#
        for r in range(1 , len(st)+1):
            if st[0:r] == ("0") * r:
                count+=1
            else:
                break
#jaisa hi pehla non zero mila break d
#loop
#max r ki value store
#ho jaayegi a mein loop ke end mein
#
        if count == len(st):
            return 0
        else:
            return ((int(st[count:])) * num)
    else:
        return ((int(st)) * num)
#
def max_weight(l , r):
    m = len(str(l))
    n=len(str(r))  #since r > l so m>=n
    p=int("9" * n) / 2
#
    if m==n :
        x=abs(p- l)
        y=abs(p-r)
        max_lr = weight(min(x , y))
    else:
        if r < p:
            max_lr = weight(r)
    else:
            max_lr = weight(p)
    return max_lr
#
L , R = map(int , raw_input().split(" "))
print max_weight(L , R)


Reflection Codeforces..More efficient program...
...........................................def weight(num):
    p = str(num)
    st = ""
    count=0
    for character in p:
        reflection = str(9-int(character))
        st += reflection
    if st[0]=="0":
#
#we need to eliminate all d zeroesu #from d start till a non zejro is #encountered or d string lasts den #return 0 since unidigit 0 is allowedj
#
        for r in range(1 , len(st)+1):
            if st[0:r] == ("0") * r:
                count+=1
            else:
                break
#jaisa hi pehla non zero mila break d
#loop
#max r ki value store
#ho jaayegi a mein loop ke end mein
#
        if count == len(st):
            return 0
        else:
            return ((int(st[count:])) * num)
    else:
        return ((int(st)) * num)
#
def max_weight(l , r):
    m = len(str(l))
    n=len(str(r))  #since r > l so m>=n
    p=int((int("9" * n)) / 2)
    q=p+1
    ml=weight(l)
    mr=weight(r)
    mp=weight(p)
#
    if m==n :
        if l==p or r==p or l==q or r==q:
            return mp
        elif r<p:
            return mr
        elif l>q:
            return ml
        else:
            return weight(min((p-l) , (r-q)))
    else:
        if r < p :
            return mr
        else:
            return mp
#
L , R = map(int , raw_input().split(" "))
print max_weight(L , R)


def weight(num):
    p = str(num)
    st = ""
    count=0
    for character in p:
        reflection = str(9-int(character))
        st += reflection
    if st[0]=="0":
#
#we need to eliminate all d zeroesu #from d start till a non zejro is #encountered or d string lasts den #return 0 since unidigit 0 is allowedj
#
        for r in range(1 , len(st)+1):
            if st[0:r] == ("0") * r:
                count+=1
            else:
                break
#jaisa hi pehla non zero mila break d
#loop
#max r ki value store
#ho jaayegi a mein loop ke end mein
#
        if count == len(st):
            return 0
        else:
            return ((int(st[count:])) * num)
    else:
        return ((int(st)) * num)
#
def max_weight(l , r):
    m = len(str(l))
    n=len(str(r))  #since r > l so m>=n
    p=int((int("9" * n)) / 2)
    mp=weight(p)
    ml=weight(l)
    mr=weight(r)
#
    if m==n :
        if r<p:
            return mr
        elif l>q:
            return ml
        else:
            return mp
#bich mein p aayega hi
    else:
        if r < p :
            return mr
        else:
            return mp
#
L , R = map(int , raw_input().split(" "))
print max_weight(L , R)


def weight(num):
    p = str(num)
    st = ""
    count=0
    for character in p:
        reflection = str(9-int(character))
        st += reflection
    if st[0]=="0":
#
#we need to eliminate all d zeroes #from d start till a non zero is #encountered or d string lasts den #return 0 since unidigit 0 is allowed
#
        for r in range(1 , len(st)+1):
            if st[0:r] == ("0") * r:
                count+=1
            else:
                break
#jaisa hi pehla non zero mila break d
#loop
#max r ki value store
#ho jaayegi a mein loop ke end mein
#
        if count == len(st):
            return 0
        else:
            return ((int(st[count:])) * num)
    else:
        return ((int(st)) * num)
#
def max_weight(l , r):
    max_lr=0  #since n is always +ve
    for x in range(l , r+1):
        max_lr=max(max_lr , weight(x))
    return max_lr
#
L , R = map(int , raw_input().split(" "))
print max_weight(L , R)


MAX = 10**5 + 1;
grundy = [0 for i in xrange(MAX)];
choice = [-1 for i in xrange(MAX)];
for i in xrange(1,MAX):
    k = 2;
    U = set();
    while k*(k+1)/2 <= i:
        diff = i - k*(k+1)/2;
        if diff % k == 0:
            offset = diff/k;
            x = grundy[offset + k ] ^ grundy[offset];
            if not x and choice[i] == -1: choice[i] = k;
            U.add(x);
        k += 1;
    while grundy[i] in U:
        grundy[i] += 1;
    grundy[i] ^= grundy[i - 1];

n = int(raw_input());
print choice[n];


n = input()

spg = [0] * (n + 1)
xor = [0] * (n + 1)

for i in range(3, n + 1):
    k = 2
    movs = set()
    while k * (k + 1) <= 2 * i:
        s = 2 * i - k * (k - 1)

        if s % (2 * k) == 0:
            a = s / 2 / k
            movs.add(xor[a + k - 1] ^ xor[a - 1])
        k += 1

    mex = 0
    while mex in movs:
        mex += 1
    spg[i] = mex
    xor[i] = xor[i - 1] ^ mex

if spg[n]:
    k = 2
    while k * (k + 1) <= 2 * i:
        s = 2 * i - k * (k - 1)

        if s % (2 * k) == 0:
            a = s / 2 / k
            if (xor[a + k - 1] ^ xor[a - 1]) == 0:
                break
        k += 1
    print(k)
else:
    print(-1)


from operator import __xor__

known = {1:0, 2:0}
win = {1:-1, 2:-1}

def split(stone, k):
    n = int( ( stone - (k*(k-1)/2)) / k)
    if n <= 0 or k*n + k*(k-1)/2 != stone:
        return []
    return range(n, n+k)

def mex(iterable):
    i = 0
    while i in iterable:
        i += 1
    return i

def g(stone):
    if stone in known:
        return known[stone]
    loc = set()
    win_k = -1
    for k in range(2, int((2*stone) ** .5) + 1):
        sp =  split(stone, k)
        if sp:
            xor = reduce(__xor__, map(g, sp), 0)
            loc.add(xor)
            if xor == 0 and win_k == -1:
                win_k = k
    xor = mex(loc)
    known[stone] = xor
    win[stone] = win_k
    return xor

if __name__ == "__main__":
    n = int(raw_input().strip())
    for i in range(10**5): g(n)
    print win[n]


import math
from collections import Counter

n = int(input())
g = [0 for i in range(n + 1)]
prefix_xor = g.copy()

def in_range(d, k):
    if (2 * k - d * d + d) % (2 * d) != 0:
        return -1
    x = (2 * k - d * d + d) / (2 * d)
    return int(x) if x > 0 else -1

def mex(arr):
    counter = Counter()
    for i in arr:
        counter[i] += 1
    for i in range(0, len(arr) + 1):
        if counter[i] == 0:
            return i

def find_move(arr):
    for i in range(0, len(arr)):
        if arr[i] == 0:
            return i
    return -1

if n < 3:
    print(-1)
    exit(0)
for i in range(3, n + 1):
    for_range = range(2, int(math.sqrt(2 * i)) + 1)
    filter_range = [l for l in for_range if in_range(l, i) > 0]
    branches = [prefix_xor[in_range(d, i) + d - 1] ^ prefix_xor[in_range(d, i) - 1] for d in filter_range]
    g[i] = mex(branches)
    prefix_xor[i] = prefix_xor[i - 1] ^ g[i]
    if i == n:
        print(-1 if g[i] == 0 else filter_range[find_move(branches)])


n = input()
a,f = [[] for _ in xrange(n+1)],[0]*(n+1)
for k in xrange(2,n):
    for x in xrange(1,n):
        z = x*k+(k*k-k>>1)
        if z>n: break
        a[z].append((k,x))
q,s = [n],set([n])
for j in q:
    l = set([])
    for k,x in a[j]: l.update(range(x,x+k))
    q.extend(l-s)
    s |= l
q = lambda(k,x): reduce(int.__xor__,f[x:x+k],0)
for i in sorted(s): f[i]=next(j for j in xrange(n) if j not in set(map(q,a[i])))
print min(p[0] for p in a[n] if q(p)==0) if f[n] else -1


import sys
sys.stderr = sys.stdout

def egcd(a, b):
    r0 = a
    r1 = b
    s0 = 1
    s1 = 0
    t0 = 0
    t1 = 1
    while r1:
        q = r0 // r1
        r0, r1 = r1, r0 - q*r1
        s0, s1 = s1, s0 - q*s1
        t0, t1 = t1, t0 - q*t1
    return r0, s0

def app(n, M):
    K = [[[1]]]
    for i in range(n-1):
        Ki = K[i]
        ni = len(Ki)
        Ki_ = [[0] * (i+2) for _ in range(ni + i + 1)]
        K.append(Ki_)
        for j, Kij in enumerate(Ki):
            for k, v in enumerate(Kij):
                for h in range(i+1):
                    Ki_[j+h][k] += v
                    Ki_[j+h][k] %= M
                Ki_[j + i + 1][i+1] += v
                Ki_[j + i + 1][i+1] %= M

    c = n
    s = 0
    for i in range(1, n):
        Ki = K[i]
        ni = len(Ki)
        mi = len(Ki[0])
        Si = [[None] * mi for _ in range(ni)]
        for j in range(ni):
            Si[j][mi-1] = Ki[j][mi-1]
            for k in reversed(range(mi-1)):
                Si[j][k] = (Ki[j][k] + Si[j][k+1]) % M
        for j in range(1, ni):
            for k in range(mi):
                Si[j][k] += Si[j-1][k]
                Si[j][k] %= M
        # log("i", i, "Ki", Ki, "Si", Si)

        si = 0
        for j in range(1, ni):
            for k in range(mi-1):
                si += (Ki[j][k] * Si[j-1][k+1]) % M
                si %= M
        # log("  si", si)

        # log("  n", n, "i+1", i+1, "c", c)
        x, y = egcd(i+1, M)
        c = (c * y) % M
        # log("  x", x, "y", y)
        # assert c % x == 0
        c = (c // x) % M
        c = (c * (n - i)) % M
        # log("  c", c)

        si *= c
        si %= M
        s += si
        s %= M

    return s

def main():
    n, m = readinti()
    print(app(n, m))

##########

def readint():
    return int(input())

def readinti():
   return map(int, input().split())

def readintt():
   return tuple(readinti())

def readintl():
   return list(readinti())

def readinttl(k):
    return [readintt() for _ in range(k)]

def readintll(k):
    return [readintl() for _ in range(k)]

def log(*args, **kwargs):
    print(*args, **kwargs, file=sys.__stderr__)

if __name__ == '__main__':
    main()


import numpy as np
def solve(n, mod):
    if n<=3:
        return 0
    else:
        last_ans = 17
        ans = 17
        size = (n-1)*(n-2)//2 + 1
        inv = 1
        record = np.zeros((2,size),dtype=np.uint64)
        record[0,0:4]=[1,2,2,1]
        for m in range(4,n):
            tp_size = m*(m-1)//2
            ans = (m+1) * last_ans
            tp = 0
            for i in range(m):
                tp += record[inv^1,i]
                record[inv,i] = tp%mod
            for i in range(m,tp_size//2+1):
                tp += record[inv^1,i]
                tp -= record[inv^1,i-m]
                record[inv,i] = tp%mod
            for i in range(tp_size//2+1):
                record[inv,tp_size-i] = record[inv,i]
            # print("ans:",ans)
            total = 0
            for i in range(tp_size-1):
                tp = 0
                for j in range(max(1,-tp_size+i+m+2),m+1):
                    # print("(",j,m+2-j+i,")",end=" ")
                    tp += j * int(record[inv,m+2-j+i])
                # print()
                total += int(record[inv,i])
                total %= mod
                tp *= total
                tp %= mod
                ans += tp
                ans %= mod
            last_ans = ans
            # print(record)
            inv ^= 1
        return int(ans)%mod

def main():
    n, mod = map(int, input().split())
    print(solve(n, mod))

if __name__ == "__main__":
    main()


import numpy as np
def solve(n, mod):
    if n<=3:
        return 0
    else:
        last_ans = 17
        ans = 17
        size = (n-1)*(n-2)//2 + 1
        inv = 1
        record = np.zeros((2,size),dtype=np.uint64)
        record[0,0:4]=[1,2,2,1]
        for m in range(4,n):
            tp_size = m*(m-1)//2
            ans = (m+1) * last_ans
            tp = 0
            for i in range(m):
                tp += record[inv^1,i]
                record[inv,i] = tp%mod
            for i in range(m,tp_size//2+1):
                tp += record[inv^1,i]
                tp -= record[inv^1,i-m]
                record[inv,i] = tp%mod
            for i in range(tp_size//2+1):
                record[inv,tp_size-i] = record[inv,i]
            # print("ans:",ans)
            total = 0
            for i in range(tp_size-1):
                tp = 0
                for j in range(max(1,-tp_size+i+m+2),m+1):
                    # print("(",j,m+2-j+i,")",end=" ")
                    tp += j * record[inv,m+2-j+i]
                # print()
                total += record[inv,i]
                total %= mod
                tp *= total
                tp %= mod
                ans += tp
                ans %= mod
            last_ans = ans
            # print(record)
            inv ^= 1
        return int(ans)

def main():
    n, mod = map(int, input().split())
    print(solve(n, mod))

if __name__ == "__main__":
    main()


def solve(n, mod):
    if n<=3:
        return 0
    else:
        last_ans = 17
        ans = 17
        size = (n-1)*(n-2)//2 + 1
        inv = 1
        record = [[0 for i in range(size+1)] for i in range(2)]
        record[0][0:4]=[1,2,2,1]
        for m in range(4,n):
            tp_size = m*(m-1)//2
            ans = (m+1) * last_ans
            tp = 0
            for i in range(m):
                tp += record[inv^1][i]
                record[inv][i] = tp%mod
            for i in range(m,tp_size//2+1):
                tp += record[inv^1,i]
                tp -= record[inv^1,i-m]
                record[inv][i] = tp%mod
            for i in range(tp_size//2+1):
                record[inv][tp_size-i] = record[inv][i]
            # print("ans:",ans)
            total = 0
            for i in range(tp_size-1):
                tp = 0
                for j in range(max(1,-tp_size+i+m+2),m+1):
                    # print("(",j,m+2-j+i,")",end=" ")
                    tp += j * int(record[inv][m+2-j+i])
                # print()
                total += int(record[inv][i])
                total %= mod
                tp *= total
                tp %= mod
                ans += tp
                ans %= mod
            last_ans = ans
            # print(record)
            inv ^= 1
        return int(ans)%mod

def main():
    n, mod = map(int, input().split())
    print(solve(n, mod))

if __name__ == "__main__":
    main()


import sys

def I(): return int(sys.stdin.readline().rstrip())
def MI(): return map(int,sys.stdin.readline().rstrip().split())
def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def LI2(): return list(map(int,sys.stdin.readline().rstrip()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())
def LS2(): return list(sys.stdin.readline().rstrip())

n,mod = MI()

m = n*(n-1)//2
dp = [[[0]*(n+1) for _ in range(m+1)] for _ in range(n+1)]
# dp[i][j][k] = kから始まる1~iの順列で、転倒数がjとなるものの個数
dp[1][0][1] = 1
for i in range(1,n):
    for j in range(m+1):
        for k in range(n+1):
            a = dp[i][j][k]
            if not a:
                continue
            dp[i+1][j+i][i+1] += a
            dp[i+1][j+i][i+1] %= mod
            for l in range(i):
                dp[i+1][j+i-1-l][k] += a
                dp[i+1][j+i-1-l][k] %= mod

S_dp = [[[0]*(n+1) for _ in range(m+1)] for _ in range(n+1)]
# S_dp[i][j][k] = dp[i][0][k]+…+dp[i][j][k]
for i in range(n+1):
    for k in range(n+1):
        a = 0
        for j in range(m+1):
            a += dp[i][j][k]
            a %= mod
            S_dp[i][j][k] = a

SS_dp = [[[0]*(n+1) for j in range(m+1)] for i in range(n+1)]
# SS_dp[i][j][k] = S_dp[i][j][0]+…+S_dp[i][j][k]
for i in range(n+1):
    for j in range(m+1):
        a = 0
        for k in range(n+1):
            a += S_dp[i][j][k]
            a %= mod
            SS_dp[i][j][k] = a

ANS = [0]*(n+1)
for i in range(1,n+1):
    ans = i*ANS[i-1] % mod  # 1文字目が同じ場合
    for k in range(n+1):
        for j in range(1,m+1):
            if not dp[i][j][k]:
                continue
            ans += dp[i][j][k]*(SS_dp[i][j-1][-1]-SS_dp[i][j-1][k])
            ans %= mod
    ANS[i] = ans

ans = ANS[-1]
print(ans)


n, m, k, r, c = map(int, input().split())
ax, ay, bx, by = map(int, input().split())
p = n * m
if ax != bx or ay != by:
	p -= r * c
print(pow(k, p, 1000000007))


mod=10**9+7
N,M,K,R,C=map(int,input().split())
AX,AY,BX,BY=map(int,input().split())
if AX>BX:
  AX,BX=BX,AX
if AY>BY:
  AY,BY=BY,AY
Z=0
if AX+R>BX and AY+C>BY:
  Z=(AX+R-BX)*(AY+C-BY)
V=N*M-R*C*2+Z
if (AX,AY)==(BX,BY):
  Z=0
print(pow(K,V+R*C-Z,mod))


n, m, k, r, c = map(int, input().split())
ax, ay, bx, by = map(int, input().split())
print(pow(k, n*m - (r*c if (ax,ay) != (bx,by) else 0), 10**9+7))


p = 10**9+7
n, m, k, r, c = [int(x) for x in input().split()]
ax, ay, bx, by = [int(x) for x in input().split()]
if [ax, ay] != [bx, by]:
    answer = pow(k, n*m-r*c, p)
else:
    answer = pow(k, n*m, p)
print(answer)


p = 10**9+7
n, m, k, r, c = [int(x) for x in input().split()]
ax, ay, bx, by = [int(x) for x in input().split()]
answer = pow(k, n*m-r*c, p)
print(answer)


n = int(input())
a = list(map(int, input().strip().split()))
print(max(a) - a[len(a) - 1])


s = raw_input()
sm = sum([int(x) for x in s])

fib = [0] * 20
fib[0] = 0
fib[1] = 1
fib[2] = 1

for i in range(3, 20):
	fib[i] = fib[i-1] + fib[i-2]

sf = set(fib)

if sm in sf:
	print "Yes"
else:
	print "No"


print(min(*[(x for x in range(103) if a.count(x) == 0) for a in [[list(map(int, input().split())) for _ in range(2)][1]]]))


import sys
from array import array  # noqa: F401

def input():
    return sys.stdin.buffer.readline().decode('utf-8')

lines = [
    [0, 1, 2],
    [3, 4, 5, 6],
    [7, 8, 9, 10, 11],
    [12, 13, 14, 15],
    [16, 17, 18],
    [0, 3, 7],
    [1, 4, 8, 12],
    [2, 5, 9, 13, 16],
    [6, 10, 14, 17],
    [11, 15, 18],
    [2, 6, 11],
    [1, 5, 10, 15],
    [0, 4, 9, 14, 18],
    [3, 8, 13, 17],
    [7, 12, 16]
]

dp = [0] + [-1] * (1 << 19)

def dfs(state: int):
    if dp[state] != -1:
        return dp[state]

    for line in lines:
        for i in range(len(line)):
            line_bit = 0
            for j in range(i, len(line)):
                line_bit |= 1 << line[j]
                if state & line_bit == line_bit and dfs(state & ~line_bit) == 0:
                    dp[state] = 1
                    return 1
    dp[state] = 0
    return 0

start_bit = 0
for s in (0, 3, 7, 12, 16):
    for i, c in enumerate(input().split(), start=s):
        if c == 'O':
            start_bit |= 1 << i

print('Karlsson' if dfs(start_bit) else 'Lillebror')