# coding: utf-8

# In[36]:

import math

def UnusualSeq(a,b):
    if b%a!=0:
        print(0)
    else:
        b//=a
        d=set()
        for i in range(1,int(math.sqrt(b)+1)):
            if b%i==0:
                d.add(i)
                d.add(b//i)
        d=sorted(list(d))
        f=d[::]
        for i in range(len(f)):
            f[i]=pow(2,d[i]-1,(10**9+7))
            for j in range(i):
                if d[i]%d[j]==0:
                    f[i]-=f[j]
        print(f[-1]%(10**9+7))

a,b=map(int,input().split())
UnusualSeq(a,b)


import __pypy__
modmul = __pypy__.intop.int_mulmod

MOD = 998244353
def inv(x):
    return pow(x, MOD - 2, MOD)

n, m = map(int, input().split())

mult = n * inv(m + 1) + 1
mult %= MOD

currN = 1
out = m + 1
while currN < n:
    currN += 1

    out += modmul(m, inv(currN), MOD)
    out %= MOD

out *= mult
print(out % MOD)


def modInverse(a, m) :
    m0 = m; y = 0; x = 1
    if (m == 1): return 0
    while (a > 1):
        q = a // m; t = m; m = a % m; a = t; t = y; y = x - q * y; x = t
    if (x < 0): x = x + m0
    return x

prime = 998244353
n, m = map(int, input().split())
z = 0

for i in range(1, n+1): z += modInverse(i, prime)
ans = (1+m*z)*(1+n*modInverse(m+1, prime))
print(ans % prime)


n,m,a,b = map(int,raw_input().split())
if m == 1:
    print 1
    exit(0)
if b == n:
    b = (b+m-1)/m*m
l = (a+m-1)/m*m
r = (b+m-1)/m*m
if r == l:
    print 1
    exit(0)
if r == l+m:
    if a % m == 1 and b % m == 0:
        print 1
    else:
        print 2
    exit(0)
d1 = (l-a+1) % m
d2 = (b-r) % m
if a % m == 1 and b % m == 0:
    print 1
    exit(0)
if a % m == 1 or b % m == 0:
    print 2
    exit(0)
if d1 + d2 == m:
    print 2
    exit(0)
print 3


from itertools import permutations
import sys
from math import *
ics, per, first, last = map(int, raw_input().split())
per = float(per)
x1 = int(ceil(first / per))
y1 = int(first % per)
x2 = int(ceil(last / per))
y2 = int(last % per)

if x1 == x2:
    print 1
    exit()

if y1 == 1 and y2 == 0:
    print 1
    exit()

if y1 == 1 and last == ics:
    print 1
    exit()

if per == 1:
    print 1
    exit()

if abs(x1-x2) == 1:
    print 2
    exit()

if y1 == 1:
    print 2
    exit()

if y2 == 0:
    print 2
    exit()

if last == ics:
    print 2
    exit()

if y1-y2 == 1 or y2-y1 == per - 1:
    print 2
    exit()

print 3


def DFS(x):
    for i in range(x):
        if(Seen[i][x]):
            continue
        if(Rem[i]>=C[x]):
            if(Rem[i]==C[x] and len(Children[i])==0):
                continue
            Rem[i]-=C[x]
            Parent[x]=i
            Children[i].append(x)
            return True
    for i in range(x):
        if(Seen[i][x]):
            continue
        Y=[]
        for j in range(len(Children[i])):
            child=Children[i][j]
            Parent[child]=-1
            Rem[i]+=C[child]
            Seen[i][child]=True
            Seen[child][i]=True
            if(DFS(child)):
                Seen[i][child]=False
                Seen[child][i]=False
                continue
            Seen[i][child]=False
            Seen[child][i]=False
            Parent[child]=i
            Rem[i]-=C[child]
            Y.append(child)
        Children[i]=list(Y)
        if(Rem[i]>=C[x]):
            if(Rem[i]==C[x] and len(Children[i])==0):
                continue
            Rem[i]-=C[x]
            Children[i].append(x)
            Parent[x]=i
            return True
    return False

n=int(input())

C=list(map(int,input().split()))
Rem=[-1]*n
Parent=[-1]*n
Children=[]
Seen=[]
for i in range(n):
    Seen.append([False]*n)
C.sort(reverse=True)

if(C[0]!=n or C.count(2)>0):
    print("NO")

else:
    for i in range(n):
        Rem[i]=C[i]-1
        Children.append([])
    Parent[0]=0
    Ans="YES"
    for i in range(1,n):
        if(DFS(i)==False):
            Ans="NO"
            break
    for i in range(n):
        if(Rem[i]!=0 and C[i]!=1):
            Ans="NO"
            break
    print(Ans)


def DFS(x):
    for i in range(x):
        if(Seen[i][x]):
            continue
        if(Rem[i]>=C[x]):
            if(Rem[i]==C[x] and len(Children[i])==0):
                continue
            Rem[i]-=C[x]
            Parent[x]=i
            Children[i].append(x)
            return True
    for i in range(x):
        if(Seen[i][x]):
            continue
        Y=[]
        for j in range(len(Children[i])):

            child=Children[i][j]
            if(Seen[i][child]):
                continue
            Parent[child]=-1
            Rem[i]+=C[child]
            Seen[i][child]=True
            Seen[child][i]=True
            if(DFS(child)):
                Seen[i][child]=False
                Seen[child][i]=False
                continue
            Seen[i][child]=False
            Seen[child][i]=False
            Parent[child]=i
            Rem[i]-=C[child]
            Y.append(child)
        Children[i]=list(Y)
        if(Rem[i]>=C[x]):
            if(Rem[i]==C[x] and len(Children[i])==0):
                continue
            Rem[i]-=C[x]
            Children[i].append(x)
            Parent[x]=i
            return True
    return False

n=int(input())

C=list(map(int,input().split()))
Rem=[-1]*n
Parent=[-1]*n
Children=[]
Seen=[]
for i in range(n):
    Seen.append([False]*n)
C.sort(reverse=True)

if(C[0]!=n or C.count(2)>0):
    print("NO")

else:
    for i in range(n):
        Rem[i]=C[i]-1
        Children.append([])
    Parent[0]=0
    Ans="YES"
    for i in range(1,n):
        if(DFS(i)==False):
            Ans="NO"
            break
    for i in range(n):
        if(Rem[i]!=0 and C[i]!=1):
            Ans="NO"
            break
    print(Ans)


#!/usr/bin/env python

import sys

line = sys.stdin.readline().strip()
groups = map(lambda x: int(x), line.split(" "))
n = groups[0]
m = groups[1]

#n, m = 2, 4

if (min(n, m) == 1):
    print max(n, m)

elif (n > 2) and (m > 2):
    print (n * m + 1) / 2

else:
    c = n + m - 2
    x = c / 2
    y = c - x
    print (x + 1) / 2 * 2 + (y + 1) / 2 * 2


def solve(l,r):
    if(l>r): return 0
    if(l == r): return 1
    if(dp[l][r] != -1): return dp[l][r]
    ans = solve(l+1,r)+1
    for i in range(l+1,r+1):
        if(s[i]==s[l]): ans = min(ans , solve(l+1,i-1)+solve(i,r))
    dp[l][r] = ans
    return ans

def F():
    n = int(input())
    global s;
    s = input()

    global dp;
    dp = [[-1]*n for _ in range(n)]
    ans = solve(0,n-1)

    print(ans)
F()


#!/usr/bin/env python
# coding=utf-8

h, n = map(int, raw_input().split())
t = bin(n - 1)[2:]
t = '0' * (h - len(t)) + t
res = 0
flag = True
for i in range(h):
    if (t[i] == ('1' if flag else '0')):
        res += 2 ** (h - i)
    else:
        flag = not flag
        res += 1
print res


#------------------------template--------------------------#
import os
import sys
from math import *
from collections import *
from fractions import *
from bisect import *
from heapq import*
from io import BytesIO, IOBase
def vsInput():
    sys.stdin = open('input.txt', 'r')
    sys.stdout = open('output.txt', 'w')
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")
sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")
def value():return tuple(map(int,input().split()))
def array():return [int(i) for i in input().split()]
def Int():return int(input())
def Str():return input()
def arrayS():return [i for i in input().split()]

#-------------------------code---------------------------#
#vsInput()

h,n=value()

low=1
high=2**(h)

ans=0
move=0

while(low<high):
    mid=low+(high-low)//2
    #print(low,mid,high,ans,move)

    if(n<=mid):
        if(move==0):
            ans+=1
            move^=1
        else:
            ans+=2**h
        high=mid
    else:
        if(move==1):
            ans+=1
            move^=1
        else:
            ans+=2**h
        low=mid+1

    h-=1
    #move^=1

print(ans)


import math
def cnt_res(n):
    d = [1]
    s = 0
    for i in range(n):
        s += d[-1]
        d.append(d[-1]*2)
    return s
h,n = map(int, input().split())
answ = 0
l = 1
r = 2**h
b = h
dir = 'L'
for i in range(h):
    if dir == 'L':
        if n>(l+r)/2:
            answ+=cnt_res(b)+1
            l = (l+r)//2+1
        elif n<(l+r)/2:
            r = (l+r)//2+int(l+r%2!=0)-1
            answ += 1
            dir = 'R'
        b-=1
    else:
        if n<(l+r)/2:
            answ+=cnt_res(b)+1
            r = (l+r)//2+int(l+r%2!=0)-1
        elif n>(l+r)/2:
            answ += 1
            l=(l+r)//2+1
            dir = 'L'
        b-=1
print(answ)


sl = [0]*51
sl[0] = 1
for i in range(1,51):
    sl[i] = sl[i-1] + (2**i)

h,n = map(int,input().split())

nl = []
n += sl[h-1]
tn = n
nl.append(tn)
while tn != 1:
    tn = tn//2
    nl.append(tn)

ans = 0
cn = 1
cp = False

while cn != n:
    tnl = []
    for i in range(h):
        tnl.append(cn);
        if cp == False:
            cn *= 2
        else:
            cn = cn*2+1
        cp = not cp
    if cn == n:
        ans += h
        break

    tnl.append(cn)
    tnl = tnl[::-1]
    for i in range(1,h+1):
        if nl[i] == tnl[i]:
            ans += sl[i-1]+h-i+1
            h=i-1
            cn=tnl[i-1]
            if cn == tnl[i]*2:
                cn = tnl[i]*2+1
                cp = False
            else:
                cn = tnl[i]*2
                cp = True
            break
print(ans)


"""
Codeforces Contest 287 Div 2 Problem C

Author  : chaotic_iak
Language: Python 3.4.2
"""

################################################### SOLUTION

def main():
    h,n = read()
    n -= 1
    n = bin(n)[2:]
    n = "0" * (h-len(n)) + n

    s = ""
    for i in range(h):
        if i and n[i-1] == "0":
            s += "1" if n[i] == "0" else "0"
        else:
            s += n[i]

    ct = 0
    for i in range(h):
        ct += 1
        if s[i] == "1": ct += 2**(h-i)-1
    print(ct)

#################################################### HELPERS

def read(mode=2):
    # 0: String
    # 1: List of strings
    # 2: List of integers
    inputs = input().strip()
    if mode == 0: return inputs
    if mode == 1: return inputs.split()
    if mode == 2: return list(map(int, inputs.split()))

def write(s="\n"):
    if s is None: s = ""
    if isinstance(s, list): s = " ".join(map(str, s))
    s = str(s)
    print(s, end="")

write(main())


### TEMPLATE BEGIN

from collections import defaultdict
from math import sqrt

def read_int():
    return int(raw_input())

def read_ints():
    return (int(x) for x in raw_input().split())

def read_int_list():
    return [int(x) for x in raw_input().split()]

def read_float():
    return float(raw_input())

def read_floats():
    return (float(x) for x in raw_input().split())

def read_float_list():
    return [float(x) for x in raw_input().split()]

def read_list():
    return [x for x in raw_input().split()]

def read_line():
    return raw_input()

### TEMPLATE END

def solve():
    height, node = read_ints()
    node -= 1
    left = True
    leftLeaf = 0
    intervalSize = 2 ** height
    ret = 0
    while intervalSize > 1:
        if left:
            ll = leftLeaf
            rr = ll + intervalSize/2
        else:
            ll = leftLeaf + intervalSize/2
            rr = ll + intervalSize/2
        if node >= ll and node < rr:
            ret += 1
            left = not left
        else:
            ret += intervalSize
        if node >= leftLeaf + intervalSize/2:
            leftLeaf += intervalSize/2
        intervalSize /= 2
    print ret

qq = 1
# qq = 2**30
# qq = read_int()
for _________ in xrange(qq):
    solve()


h, n = map(int, input().split())
N = bin(n - 1)[2:]
N = '0' * (h - len(N)) + N
ans = 0
f = False
for i in range(h):
    if N[i] != ('1' if not f else '0'):
        f = not f
        ans += 1
    else:
        ans += 2 ** (h - i)
print(ans)


h, n = map(int, input().split())
h -= 1
n -= 1
l = 0
r = 2 << h
ll = True
ans = 0
i = 0
while r - l > 1:
    m = (l + r) // 2
    if ll == (n < m):
        ans += 1
    else:
        ans += 1 << (h - i + 1)
    if n < m:
        r = m
        ll = False
    else:
        l = m;
        ll = True
    i += 1
print(ans)


def L(h, n):
    if h == 0:
        return 0
    half = 2**(h-1)
    if n <= half:
        return 1 + R(h-1, n)
    else:
        return 2*half + L(h-1, n-half)

def R(h, n):
    if h == 0:
        return 0
    half = 2**(h-1)
    if n <= half:
        return 2*half + R(h-1, n)
    else:
        return 1 + L(h-1, n-half)

[h, n] = map(int, raw_input().split(" "))
print L(h, n)


h,n=input().split(' ')
h=int(h)
n=int(n)
s='l'
ans=0
for i in range(h,0,-1):
 if n>pow(2,i-1):
     if s=='l':
       ans+=pow(2,i)
     else:
       ans+=1
     s='l'
     n-=pow(2,i-1)
 else:
     if s=='r':
         ans+=pow(2,i)
     else:
         ans+=1;
     s='r'
print (ans)


import sys
import re
[n, k] = map(int, sys.stdin.readline().split())
seq = sys.stdin.readline().split()[0]

#print n, k, seq

def max_N(s):
    r = 0
    max_r = 0
    for i in range(len(s)):
        if s[i] == 'N':
            r += 1
        else:
            r = 0
        if r > max_r:
            max_r = r
    return max_r

def is_possible(s, k):
    s1 = "Y" + s + "Y"
    seq_N = s1.replace("?", "N")
    for i in range(len(seq_N)):
        if seq_N[i:i + k] == 'N' * k:
            if (s1[i - 1] in ["Y", "?"]) and (s1[i + k] in ["Y", "?"]):
                return 1
    return 0

seq_Y = seq.replace("?", "Y")
max_N_Y = max_N(seq_Y)

if max_N_Y > k:
    print("NO")
elif max_N_Y == k:
    print("YES")
else:
    if is_possible(seq, k):
        print("YES")
    else:
        print("NO")


import sys

(n, k) = raw_input().split(' ')
series = str(raw_input())
n = int(n)
k = int(k)

streak = False
max_streak = 0
curr_count = 0

for i in xrange(n):
    if series[i] == 'N':
        if not streak:
            curr_count = 1
            streak = True
        else:
            curr_count += 1
    else:
        streak = False
        if max_streak < curr_count:
            max_streak = curr_count

if max_streak < curr_count:
    max_streak = curr_count

if int(k) < max_streak:
    print 'NO'
    sys.exit()
else:
    for i in xrange(n - k + 1):
        check_bounds = True

        # print series[i:i+k]
        check = True
        for j in range(i, i+k):
            if not (series[j] == 'N' or series[j] == '?'):
                check = False
                break
        if check:
            if i != 0:
                if series[i - 1] == 'N':
                    check_bounds = False
                    # print 'left'
            if i != n - k:
                if series[i + k] == 'N':
                    check_bounds = False
                    # print 'right'

        if check and check_bounds:
            print 'YES'
            sys.exit()
    print 'NO'
    sys.exit()


# ------------------- fast io --------------------
import os
import sys
from io import BytesIO, IOBase

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")

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

# ------------------- fast io --------------------
from math import gcd, ceil

def prod(a, mod=10**9+7):
    ans = 1
    for each in a:
        ans = (ans * each) % mod
    return ans

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

def binary(x, length=16):
    y = bin(x)[2:]
    return y if len(y) >= length else "0" * (length - len(y)) + y

for _ in range(int(input()) if not True else 1):
    #n = int(input())
    #n, k = map(int, input().split())
    n,m,x1,y1,x2,y2 = map(int, input().split())
    #c, d = map(int, input().split())
    #a = list(map(int, input().split()))
    #b = list(map(int, input().split()))
    #s = input()
    x, y = abs(x2-x1), abs(y2-y1)
    x, y = min(x,y), max(x,y)
    if [x,y] in [[0,0], [0,1], [0,2], [0,3], [0,4],
                 [1,1], [1,2], [1,3], [1,4],
                 [2,2], [2,3], [2,4],
                 [3,3]]:
        print("First")
    else:
        print("Second")


n,m,X,Y,x,y=map(int,input().split())
a=[abs(X-x),abs(Y-y)]
a.sort()
print("First" if a[1]<5 and a[0]+a[1]<7 else "Second")


import sys
import math
input = sys.stdin.readline

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

m,a,b=map(int,input().split())

GCD=gcd(a,b)

#when a>b,

MODLIST=[-1]*a

NOWMAX=a
NOW=a
MODLIST[0]=a
while True:

    while NOW-b>0 and MODLIST[(NOW-b)%a]==-1:
        NOW-=b
        MODLIST[NOW]=NOWMAX

    NOW+=a
    NOWMAX=max(NOW,NOWMAX)

    if MODLIST[(NOW-b)%a]!=-1:
        break

ANS=m+1#0
MAX=max(MODLIST)
for i in range(1,min(m+1,MAX)):
    if MODLIST[i%a]==-1:
        continue
    ANS+=max((m+1-max(MODLIST[i%a],i)),0)

    #print(ANS)

if MAX<=m:
    ANS+=(m-MAX+1+(m-m//GCD*GCD)+1)*((m//GCD*GCD-MAX)//GCD+1)//2

print(ANS)


#! /usr/bin/python

from collections import deque

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

m, a, b = [int(inp) for inp in raw_input().split()]

m0 = min(a + b - 1, m)

canGet = [1 if i == 0 else 0 for i in xrange(m0 + 1)]
count = 1
total = 1
q = deque()
for x in xrange(1, m0 + 1):
	if x - a >= 0 and canGet[x - a] == 1:
		canGet[x] = 1
		count += 1
		q.append(x)
		while len(q) > 0:
			j = q.pop()
			if j + a <= x and canGet[j + a] == 0:
				canGet[j + a] = 1
				count += 1
				q.append(j + a)
			if j - b >= 0 and canGet[j - b] == 0:
				canGet[j - b] = 1
				count += 1
				q.append(j - b)
	total += count

g = gcd(a, b)

m1 = min(m, ((m0 + g)/g)*g - 1)
total += (m1 - m0)*count

m2 = (m/g)*g - 1
if m2 >= m1:
	total += ((m2 - m1)/g)*g*((m1 + 1)/g + (m2 + 1)/g + 1)/2
	total += (m - m2)*(m/g + 1)

print total


import sys
range = xrange
input = raw_input
import __pypy__
mulmod = __pypy__.intop.int_mulmod

MOD = 10**9+7
n, k = [int(x) for x in input().split()]

def f(n):
    s = 0
    for i in range(n):
        s += pow(i,k,MOD)
        s %= MOD
    return s

precalc = [0]
for i in range(k + 1):
    precalc.append((precalc[-1] + pow(i,k,MOD)) % MOD)

def interpolate(samples, x):
    x %= MOD
    m = len(samples)
    if x < m:
        return samples[x]

    modinv = [1]*m
    for i in range(2, m):
        modinv[i] = mulmod(-(MOD//i), modinv[MOD%i], MOD)

    invfac = [1]
    for i in range(1, m):
        invfac.append(mulmod(invfac[-1], modinv[i], MOD))
    invneg_fac = [invfac[i] * (1 - 2 * (i & 1)) for i in range(m)]

    base = 1
    for j in range(-x, m - x):
        base = mulmod(base, j, MOD)

    s = 0
    for i in range(m):
        pr = precalc[i]
        pr = mulmod(pr, pow(i - x, MOD - 2, MOD), MOD)
        pr = mulmod(pr, mulmod(invneg_fac[i], invfac[m - i - 1], MOD), MOD)
        s = (s + pr) % MOD
    return mulmod(s, base, MOD)
print (interpolate(precalc, n + 1) - (k == 0)) % MOD


import sys
range = xrange
input = raw_input
import __pypy__
mulmod = __pypy__.intop.int_mulmod

MOD = 10**9+7
n, k = [int(x) for x in input().split()]
k += 2

def f(n):
    s = 0
    for i in range(n):
        s += pow(i,k-2,MOD)
        s %= MOD
    return s

precalc = [0]
for i in range(k - 1):
    precalc.append((precalc[-1] + pow(i,k-2,MOD)) % MOD)

big = 10**6 + 10
modinv = [1]*big
for i in range(2,big):
    modinv[i] = mulmod(-(MOD//i), modinv[MOD%i], MOD)

invfac = [1]
for i in range(1,big):
    invfac.append(invfac[-1]*modinv[i]%MOD)
invneg_fac = [invfac[i] * (1 - 2 * (i & 1)) for i in range(len(invfac))]

def g(x):
    if x < k:
        return precalc[x]
    base = 1
    for j in range(-x, k - x):
        base = mulmod(base, j, MOD)
    s = 0
    for i in range(k):
        pr = precalc[i]
        pr = mulmod(pr, pow(i - x, MOD - 2, MOD), MOD)
        pr = mulmod(pr, mulmod(invneg_fac[i], invfac[k - i - 1], MOD), MOD)
        s = (s + pr) % MOD
    return mulmod(s, base, MOD)

print (g(n + 1) - (k == 2)) % MOD


BASE = 998244353
import heapq

N = 2 * 10**5

fac = [1]
inv_fac = [1]

for i in range(1, N + 1):
    fac.append((fac[-1] * i) % BASE)
    inv_fac.append((inv_fac[-1] * pow(i, BASE-2, BASE)) % BASE)
    assert (fac[i] * inv_fac[i] - 1) % BASE == 0

def fft(A,w):
    N=len(A)
    # assert (N & -N) == N
    if N<=1: return A
    even=fft(A[0::2],(w*w)%BASE)
    odd=fft(A[1::2],(w*w)%BASE)
    F=[0]*N
    x=1
    for j in range(0,N//2):
        F[j]=(even[j]+x*odd[j])%BASE
        F[j+N//2]=(even[j]-x*odd[j])%BASE
        x=(x*w)%BASE
    return F

def ifft(A,w):
    q = pow(len(A), BASE-2, BASE)
    return [(i*q)%BASE for i in fft(A, pow(w, BASE-2, BASE))]

root_order, root = 524288, 363395222

def convolve(A,B):
    # assert len(A) & -len(A) == len(A)
    w = pow(root, root_order // len(A), BASE)
    # assert pow(w, len(A), BASE) == 1
    u=fft(A,w)
    v=fft(B,w)
    return [u%BASE for u in ifft([(u[i]*v[i])%BASE for i in range(len(u))],w)]

def stirling_row(n, K):
    k = min(n, K)
    # https://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind#Explicit_formula
    # stirling(n, k) == inv_fac[k] * sum((-1)**(k - j) * binom(k, j) * (j**n) for j in range(k + 1))
    # = sum(((-1)**(k - j) * inv_fac[k - j]) * (inv_fac[j] * (j**n)) for j in range(k + 1))

    pad = (2 << (k.bit_length())) - (k + 1)
    A = [(pow(-1, j) * inv_fac[j]) % BASE for j in range(k + 1)] + [0] * pad
    B = [(pow(j, n, BASE) * inv_fac[j]) % BASE for j in range(k + 1)] + [0] * pad
    assert len(A) == len(B) == (len(A) & -len(A))
    R = convolve(A, B)
    return sum(R[1:k+1])

def solve(N, K):
    if K == 1: return 1

    muls = [0] * (N + 1)
    Q = [1]
    QV = {1: 1}

    while len(Q):
        n_div = Q[0]; heapq.heappop(Q)
        mul = QV[n_div]

        n = (N - 1) // n_div + 1
        muls[n] += mul

        for i in range(2, n + 1):
            n2 = (N - 1) // (n_div * i) + 1
            if n2 <= 0: break

            child = n_div * i
            if child not in QV:
                QV[child] = 0
                heapq.heappush(Q, child)

            QV[child] = QV.get(child, 0) - mul

    ans = 0
    for n in range(1, N + 1):
        c = muls[n]
        if c == 0: continue
        term = stirling_row(n, K)
        ans += c * term
        # print(n, c, term, ans)

    return ans % BASE

while True:
    try:
        line = input().strip()
        if len(line) == 0: continue
        N, K = list(map(int, line.split(" ")))
    except EOFError:
        break

    print(solve(N, K))


from math import inf as inf
from math import *
from collections import *
import sys
from itertools import permutations
input=sys.stdin.readline
t=1
while(t):
    t-=1
    n=int(input())
    f=n-45*20*(10**19)%n
    print(f,f+(10**20-1))


# test code from internet
n = int( input() )
x,t=10**100-1,n-100*45*10**99%n
print(t,t+x)


__author__ = 'sergio'

def sg(p):
    if p == 0:
        return -1
    else:
        return 1

def minim(w,h):
    if w < h:
        return (w,0)
    else:
        return (h,1)

def find_path(x, y, down, right):
    global size_n
    global size_m
    if down == 1:
        h = size_n - x
    else:
        h = x - 1
    if right == 1:
        w = size_m - y
    else:
        w = y - 1
    minimum = minim(w,h)
    p = minimum[0]
    ansX = x + p * sg(down)
    ansY = y + p * sg(right)
    if ansX == 1:
        down = 1
    if ansY == 1:
        right = 1
    if ansX == size_n:
        down = 0
    if ansY == size_m:
        right = 0
    return (ansX, ansY, down, right)

def total_black_bound_cells(n, m):
    return n + m - 2

def moves_count(x, y, xn, yn):
    return abs(x - xn)

def get_direction(direction):
    if direction == 'UL':
        return 0, 0
    elif direction == 'UR':
        return 0, 1
    elif direction == 'DL':
        return 1, 0
    elif direction == 'DR':
        return 1, 1

def turn_inside(n, m, xs, ys, down, right):
    if xs == 1:
        down = 1
    if ys == 1:
        right = 1
    if xs == n:
        down = 0
    if ys == m:
        right = 0
    return (down, right)

size_n = 0
size_m = 0

if __name__ == '__main__':

    n, m = [int(x) for x in raw_input().strip().split(' ')]
    xs, ys, direction = raw_input().strip().split(' ')
    xs = int(xs)
    ys = int(ys)

    size_n = n
    size_m = m
    down, right = get_direction(direction)
    down, right = turn_inside(n, m, xs, ys, down, right)

    # print n, m, xs, ys, down, right

    # make visited_points with bound cells
    visited_points = {}
    total_to_check = total_black_bound_cells(n, m) # calculate
    # print 'total_to_check', total_to_check
    visited_points[(xs, ys)] = 1
    total_to_check -= 1
    x = xs
    y = ys
    dye = 1
    while (total_to_check > 0):
        xn, yn, down, right = find_path(x, y, down, right)
        dye += moves_count(x, y, xn, yn)
        # print 'moves_count', moves_count(x, y, xn, yn)
        x = xn
        y = yn
        if (x, y) not in visited_points:
            visited_points[(x, y)] = 1
            total_to_check -= 1
        elif visited_points[(x,y)] == 1:
            visited_points[(x,y)] += 1
        else:
            print -1
            exit()
    print dye


from bisect import bisect_right as br

d_a = []
d_b = []

def solve(a, b):
    global d_a, d_b

    n = a + b
    ans = (1 + n) << 1

    for i in xrange(1, int(n ** 0.5) + 1):
        if n % i == 0:
            idx_a = br(d_a, i)
            idx_b = br(d_b, i)
            x_a = d_a[idx_a - 1]
            x_b = d_b[idx_b - 1]
            if ((a // x_a <= n // i) or (b // x_b <= n // i)): ans = min(ans, (i + n // i) << 1)

    return ans

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

for i in xrange(1, int(a ** 0.5) + 1):
    if a % i == 0: d_a.append(i)
for i in xrange(1, int(b ** 0.5) + 1):
    if b % i == 0: d_b.append(i)

print solve(a, b)


a,b = map(int,raw_input().split())
d1,d2 = 1,1
n = a+b
ans = pow(10,16)
for i in range(1,int(pow(n,0.5))+1):
    if a%i==0:
        d1 = i
    if b%i==0:
        d2 = i
    if n%i==0:
        if a/d1<=n/i or b/d2<=n/i:
            ans = min(ans,2*(i+(n/i)))
print ans


def LessInTable(n, m, x, k):
    t = x-1
    summ = int(t/m)*m
    summ1 = int(t/m)*(m-n)
    #print (t/m+1, n+1)
    #return sum([t/i for i in xrange(t/m+1,n+1)]) + summ
    v = min(int(t**0.5), n)
        #for i in xrange(t/m+1,t/n+1):
        #summ1 += t/i - n
    tn = (t-1)/n;
    tm = t/m;
    vv = [t/i for i in xrange(tm+1,v+1)]
    add = - v**2 + max(min((tn - tm),len(vv))*n,0);
    summ = summ + sum(vv)
    summ1 = summ1 + sum(vv[0:max(min(tn-tm, len(vv)),0)])
        #for i in xrange(t/m+1,v+1):
        #minimum = t/i
    #if i < tn:
    #summ1 += minimum
        #summ += minimum
        #if minimum == 0 or 2 * summ + add - summ1 > k:
            #return k+1
            #print (summ, add, summ1, x, summ * 2 + add - summ1)
    return summ * 2 + add - summ1

[n, m, k] = raw_input("").split(" ")
[n, m, k] = [int(n), int(m), int(k)]
[n,m] = [min(n,m), max(n,m)]
a = 1
b = k+1
while (b-a>1):
    cur = (a+b)/2
    summ = LessInTable(n,m,cur,k)
    #print (summ, cur)
    if summ < k:
        a = cur
    else:
        b = cur
#if LessInTable(n,m,b,k) < k:
#    print b
#else:
print a


def main():
    from math import sqrt
    m, n, k = map(int, input().split())
    if n < m:
        n, m = m, n
    lo, hi = 1, k + 1
    while lo + 1 < hi:
        mid = (lo + hi) // 2
        t = mid - 1
        v = min(int(sqrt(t)), m)
        tn, tm = (t - 1) // m, t // n
        vv = [t // i for i in range(tm + 1, v + 1)]
        if t // n * (n + m) + sum(vv) * 2 + max(min((tn - tm), len(vv)) * m, 0) - v * v - sum(
                vv[:max(min(tn - tm, len(vv)), 0)]) < k:
            lo = mid
        else:
            hi = mid
    print(lo)

if __name__ == '__main__':
    main()


import sys
import math

MOD = 998244853

def prepare_c(n):
    result = [1]
    last = [1, 1]
    for i in range(2, n + 1):
        new = [1]
        for j in range(1, i):
            new.append((last[j - 1] + last[j]) % MOD)
        new.append(1)
        last = new
    return new

def main():
    (a, b) = tuple([int(x) for x in input().split()])
    if a + b == 0:
        print(0)
        return

    c = prepare_c(a + b)

    min_lv = max(0, a - b)
    max_lv = a

    res = 0
    res += (min_lv * c[a]) % MOD
    for lv in range(min_lv + 1, max_lv + 1):
        t = 2 * lv - a + b
        res += c[(a + b + t) // 2]
        res = res % MOD

    print(res)

if __name__ == '__main__':
    main()


import sys

"""def modinv(x, y):
    z = y - 2
    ans = 1
    while z > 0:
        if z % 2 == 0:
            z = z // 2
            x = (x * x) % y
        else:
            ans = (ans * x) % y
            z = z - 1
    return ans"""

n, m = list(map(int, sys.stdin.readline().strip().split()))
p = 998244853

G = [[0 for i in range (0, m+1)] for j in range (0, n+1)]
H = [[0 for i in range (0, m+1)] for j in range (0, n+1)]
B = [[0 for i in range (0, m+1)] for j in range (0, n+1)]
"""I = [0] * 2001
for i in range (1, 2001):
    I[i] = modinv(i, p)"""
for i in range (0, n+1):
    for j in range (0, m+1):
        if i == 0 or j == 0:
            B[i][j] = 1
        else:
            B[i][j] = (B[i-1][j] + B[i][j-1]) % p
for i in range (0, n+1):
    for j in range (0, m+1):
        if i == 0:
            H[i][j] = 1
        elif j >= i:
            H[i][j] = (H[i-1][j]+H[i][j-1]) % p
for i in range (0, n+1):
    for j in range (0, m+1):
        if j == 0:
            G[i][0] = i
        elif i == 0:
            G[0][j] = 0
        else:
            G[i][j] = (G[i-1][j] + G[i][j-1] + H[i][j-1] + B[i-1][j] - B[i][j-1]) % p

print(G[n][m])


R = raw_input().split()
n = int(R[0])
p = float(R[1])
t = int(R[2])
f, g = [0.0] * 3000, [0.0] * 3000
f[0] = 1.0
for i in range (1, t+1, 1):
    for j in range (i):
        g[j] += f[j] * (1-p) if j < n else f[j]
        g[j+1] += f[j] * p if j < n else 0.0
    for j in range (i+1):
        f[j] = g[j]
        g[j] = 0.0

ans = 0.0
for i in range (1, t+1, 1):
    ans += i * f[i]
print ans


import sys
from functools import reduce
raw_input = sys.stdin.readlines

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

def lcm(x, y):
    return x//gcd(x, y)*y

def inv(n):
    return pow(n, MOD-2, MOD)

def solution():
    n, a0, x, y, k, M = list(map(int, input().strip().split()))
    a = [a0]*n
    for i in range(1, n):
        a[i] = (a[i-1]*x+y)%M
    inv_n = inv(n)
    base = reduce(lambda x, y: lcm(x, y), range(1, max(k, 2)))
    pr = [0]*base
    for x in a:
        pr[x%base] = (pr[x%base]+inv_n)%MOD
    result = ((reduce(lambda total, x: (total+(x-x%base))%MOD, a, 0)*inv_n)*k)%MOD
    for i in range(1, k+1):
        result = (result+reduce(lambda total, x: (total+x*pr[x])%MOD, range(base), 0))%MOD
        for x in range(base):
            change = pr[x]*inv_n%MOD
            pr[x] = (pr[x]-change)%MOD
            pr[x-x%i] = (pr[x-x%i]+change)%MOD
    result = (result*pow(n, k, MOD))%MOD
    return result

MOD = 998244353
print('%s' % solution())


import sys
from functools import reduce
raw_input = sys.stdin.readlines

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

def lcm(x, y):
    return x//gcd(x, y)*y

def inv(n):
    return pow(n, MOD-2, MOD)

def solution():
    n, a, x, y, k, M = list(map(int, input().strip().split()))
    inv_n = inv(n)
    base = reduce(lambda x, y: lcm(x, y), range(1, max(k, 2)))
    pr = [0]*base
    result = 0
    for i in range(n):
        pr[a%base] = (pr[a%base]+inv_n)%MOD
        result = (result + (a-a%base)*inv_n*k)%MOD
        a = (a*x+y)%M
    for i in range(1, k+1):
        result = (result+reduce(lambda total, x: (total+x*pr[x])%MOD, range(base), 0))%MOD
        for x in range(base):
            change = pr[x]*inv_n%MOD
            pr[x] = (pr[x]-change)%MOD
            pr[x-x%i] = (pr[x-x%i]+change)%MOD
    result = (result*pow(n, k, MOD))%MOD
    return result

MOD = 998244353
print('%s' % solution())


import sys
input = sys.stdin.readline

def make_tree(n):
    i = 2
    while True:
        if i >= n * 2:
            tree = [0] * i
            break
        else:
            i *= 2
    return tree

def update(i, x):
    i += len(tree) // 2
    tree[i] = x
    i //= 2
    while True:
        if i == 0:
            break
        tree[i] = tree[2 * i] + tree[2 * i + 1]
        i //= 2
    return

def get_sum(s, t):
    s += len(tree) // 2
    t += len(tree) // 2
    ans = 0
    while True:
        if s > t:
            break
        if s % 2 == 0:
            s //= 2
        else:
            ans += tree[s]
            s = (s + 1) // 2
        if t % 2 == 1:
            t //= 2
        else:
            ans += tree[t]
            t = (t - 1) // 2
    return ans

def prime_factorize(n):
    ans = []
    for i in range(2, int(n ** (1 / 2)) + 1):
        while True:
            if n % i:
                break
            ans.append(i)
            n //= i
        if n == 1:
            break
    if not n == 1:
        ans.append(n)
    return ans

def euler_func(n):
    p = set(prime_factorize(n))
    x = n
    for i in p:
        x *= (i - 1)
        x //= i
    return x

def f(a, b):
    ans = 1
    for i in range(a + 1, b + 1):
        ans *= i
        ans %= mod
    return ans

n, mod = map(int, input().split())
x = euler_func(mod)
l = n + 5
fact = [1] * (l + 1)
for i in range(1, l + 1):
    fact[i] = i * fact[i - 1] % mod
if n <= 3:
    ans = 0
else:
    dp = [0] * 2000
    dp[0], dp[1], dp[2], dp[3] = 1, 2, 2, 1
    tree = make_tree(2005)
    for i in range(4):
        update(i, dp[i])
    m = 3
    ans = 0
    for i in range(n - 3):
        dp0 = list(dp)
        ans0 = 0
        for j in range(i + 3):
            for k in range(1, m + 2):
                ans0 += get_sum(j + k + 1, 2004) * dp0[k - 1] % mod
                ans0 %= mod
                dp[j + k] += dp0[k - 1]
                dp[j + k] %= mod
                update(j + k, dp[j + k])
        m += i + 3
        ans += f(i + 4, n) * ans0 % mod
        ans %= mod
print(ans)


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[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]*(m+1) for k in range(n+1)] for i in range(n+1)]
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][k][j] = a

SS_dp = [[[0]*(n+1) for j in range(m+1)] for i in range(n+1)]
for i in range(n+1):
    for j in range(m+1):
        a = 0
        for k in range(n+1):
            a += S_dp[i][k][j]
            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
    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

print(ANS[-1])


import sys
from math import factorial

input = sys.stdin.readline

def A(n, k):
	return factorial(n)//factorial(n-k)

def solve():
	n, mod = map(int, input().split())
	if n == 1:
		print(0)
		return
	z = [1]
	aaa = 0
	for i in range(2,n+1):
		nz = [0]*(i*i//2)
		for j in range(len(z)):
			for k in range(i):
				if z[j] > 0:
					#print(i-k+j, j, i-k-1)
					nz[i-k-1+j] += z[j]
		bbb = 0
		d = [0]*(len(z)+1)
		for w in range(len(z)-1, -1, -1):
			d[w] = (d[w+1] + z[w]) % mod
		e = [0]*(len(d)+1)
		f = [0]*(len(d)+1)
		for w in range(0, len(e)-1):
			e[w+1] = (e[w] + d[w]) % mod
			f[w+1] = (f[w] - w * d[w]) % mod
		for jj in range(len(z)):
			ccc = 0
			#for w in range(min(len(z)-1, i+jj), jj + 1, -1):
			#	ccc = (ccc + d[w] * (i+1+jj)) % mod
			L = jj + 2
			R = min(len(z)-1, i+jj)
			#for w in range(min(len(z)-1, i+jj), jj + 1, -1):
			#	ccc = (ccc - w * d[w]) % mod
			if R >= L:
				ccc = (ccc + (e[R+1] - e[L]) * (i+1+jj) \
					+ (f[R+1] - f[L])) % mod
			bbb = (bbb + ccc * z[jj]) % mod
		#print(bbb)
		aaa += (bbb * A(n,n-i)) % mod
		#print(nz)
		z = nz
	#print(z)
	print(aaa % mod)

solve()


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 comb(n0, M):
#     C = [[None] * (i+1) for i in range(n0+1)]
#     C[0][0] = 1
#     C[1][0] = C[1][1] = 1
#     for n in range(2, n0+1):
#         Cp = C[n-1]
#         Cn = C[n]
#         Cn[0] = Cn[n] = 1
#         for i in range(1, n):
#             Cn[i] = (Cp[i] + Cp[i-1]) % M
#     return C

def tf(n, M):
    C = [0] * (n+1)
    C[n] = 1
    for k in reversed(range(n)):
        C[k] = (C[k+1] * (k+1)) % M
        if not C[k]:
            break
    return C

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 = comb(n, M)[n]
    C = tf(n, M)
    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)

        c = C[i+1]
        # log("  n", n, "k", i+1, "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 sys
from math import factorial

input = sys.stdin.readline

def A(n, k):
	return factorial(n)//factorial(n-k)

def solve():
	n, mod = map(int, input().split())
	if n == 1:
		print(0)
		return
	z = [1]
	aaa = 0
	for i in range(2,n+1):
		nz = [0]*((i-1)*i//2+1)
		d = [0]*(len(z)+1)
		for w in range(len(z)-1, -1, -1):
			d[w] = (d[w+1] + z[w]) % mod
		for w in range(len(nz)):
			#d = 0
			#for j in range(max(0,w+1-i), min(len(z),w+1)):
			#	d = (d + z[j]) % mod
			#nz[w] = d
			L = max(0,w+1-i)
			R = min(len(z)-1,w)
			nz[w] = d[L]-d[R+1]
		e = [0]*(len(d)+1)
		f = [0]*(len(d)+1)
		for w in range(0, len(e)-1):
			e[w+1] = (e[w] + d[w]) % mod
			f[w+1] = (f[w] - w * d[w]) % mod
		R = len(z)
		bbb = 0
		for jj in range(max(0,len(z)-i), len(z)-2):
			L = jj + 2
			bbb = (bbb + ((e[R] - e[L]) * (i+1+jj) \
				+ (f[R] - f[L])) * z[jj]) % mod
		for jj in range(len(z)-i):
			L = jj + 2
			R = i + jj
			bbb = (bbb + ((e[R+1] - e[L]) * (i+1+jj) \
				+ (f[R+1] - f[L])) * z[jj]) % mod
		#print(bbb)
		aaa += (bbb * A(n,n-i)) % mod
		#print(nz)
		z = nz
	#print(z)
	print(aaa % mod)

solve()


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()


def toSys(n, k):
    res = ''
    t = k
    while (n != 0):
        res += str(n % t)
        n //= t
        t *= k
    return res[::-1]

n = int(input())
for i in range(1, n):
    for j in range(1, n):
        print(toSys(i * j, n), end=" ")
    print()


k=int(input())
for i in range(1,k):
    z,a=i,[]
    for j in range(k-1):
        p,s=z,""
        while p:
            s=str(p%k)+s
            p//=k
        z+=i
        a.append(s)
    print(*a)


def f(a, b):
    return min(abs(a - b) * 5, abs(a - b) + 10)

def main():
    n, m, k = map(int, input().split())
    a, b = map(int, input().split())
    pa, pb = (a - 1) // (m * k), (b - 1) // (m * k)
    ans = min((pa - pb + n) % n, (-pa + pb + n) % n) * 15
    ea, eb = (a - 1) // k % m, (b - 1) // k % m
    if ans == 0:
        ans = f(ea, eb)
    else:
        ans += f(ea, 0) + f(eb, 0)
    print(ans)

main()


import sys,math
def numb(ch):
    pod=ch//(m*k)
    if ch%(m*k)!=0:
        pod+=1
    et=((ch-1)%(m*k)+1)//k
    if ((ch-1)%(m*k)+1)%k!=0:
        et+=1
    return(pod,et)

ans=0
n,m,k=map(int,input().split())
a,b=map(int,input().split())
ans=0
f_x,f_y=numb(a)
a_x,a_y=numb(b)
if f_x!=a_x:
    z=min(math.fabs(f_x-a_x),math.fabs(n-max(f_x,a_x)+min(f_x,a_x)))
    ans+=15*z
    ans+=min(10+f_y-1,(f_y-1)*5)
    ans+=min(10+a_y-1,(a_y-1)*5)
    print(int(ans))
else:
    ans+=min(10+math.fabs(a_y-f_y),math.fabs(a_y-f_y)*5)
    print(int(ans))


ll = [0]
for i in xrange(1,101):
    d = i
    while d >= i:
        tmp = 0
        while d > 0:
            tmp += d%10
            d /= 10
        d = tmp
        if d < 10: break
    if d < 10:
        ll.append(d)
    else:
        ll.append(ll[d])

n = int(raw_input())
num = [0]
for i in xrange(1,10):
    num.append(0)
    if n%9 >= i:
        tmp = 1
    else:
        tmp = 0
    num[i] = n/9 + tmp

ret = 0
for i in xrange(1,10):
    for j in xrange(1,10):
        for k in xrange(1,10):
            if ll[i*j] == ll[k]:
                ret += num[i]*num[j]*num[k]

for i in xrange(1,n+1):
    ret -= n/i
print ret


n , ans , a = int(input()) , 0 , [0] * 10
for i in range(1,n+1):
    ans -= (int)(n/i)
    a[i % 9] += 1
for i in range(9):
    for j in range(9):
        ans += a[i] * a[j] * a[(i * j) % 9]
print (ans)


import sys
# a simple parser for python. use get_number() and get_word() to read
def parser():
    while 1:
        data = list(input().split(' '))
        for number in data:
            if len(number) > 0:
                yield(number)

input_parser = parser()

def get_word():
    global input_parser
    return next(input_parser)

def get_number():
    data = get_word()
    try:
        return int(data)
    except ValueError:
        return float(data)

def done(x,y):
    print("%d %d"%(x,y))
    sys.exit(0)

def die():
    print(-1)
    sys.exit(0)

def ext_gcd(a,b):
    if b != 0:
        tmp = ext_gcd(b,a%b)
        return [tmp[1], tmp[0] - (a//b)*tmp[1]]
    return [1,0]

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

n = get_number()
m = get_number()
x = get_number()
y = get_number()
vx = get_number()
vy = get_number()

if vx == 0 :
    if x != 0 and x != n :
        die()
    if x == 0:
        if vy > 0:
            done(0,m)
        else:
            done(0,0)
    if x == n:
        if vy > 0:
            done(n,m)
        else:
            done(n,0)

if vy == 0 :
    if y != 0 and y != m:
        die()
    if y == 0:
        if vx > 0:
            done(n,0)
        else:
            done(0,0)
    if y == m:
        if vx > 0:
            done(n,m)
        else:
            done(0,m)

g = gcd(vy*n,vx*m)

if (vy*x-vx*y)%g != 0:
    die()

a = vy*n//g
b = vx*m//g
t = (vy*x-vx*y)//g
res = ext_gcd(a,-b)
if res[0]*a + res[1]*(-b) == -1:
    res[0] = -res[0]
    res[1] = -res[1]

alpha = res[0]*t
beta = res[1]*t
k = b//gcd(a,b)
T = (n*alpha-x)//vx

val = 0
if vx*k > 0 :
    val = 1
else :
    val = -1
high = 98765432198765432198765432199
low = 0
ans = 0

while high >= low:
    mid = (high+low)//2
    nalpha = alpha + mid*val*k
    nT = (n*nalpha-x)//vx
    if nT > 0:
        ans = mid
        high = mid-1
    else:
        low = mid+1

alpha = alpha + ans*val*k
T = (n*alpha-x)//vx

val = 0
if vx*k > 0 :
    val = -1
else :
    val = 1

high = 98765432198765432198765432199
low = 0
ans = 0
while high >= low:
    mid = (high+low)//2
    nalpha = alpha + mid*val*k
    nT = (n*nalpha-x)//vx
    if nT >= 0:
        ans = mid
        low = mid+1
    else:
        high = mid-1

alpha = alpha + ans*val*k
T = (n*alpha-x)//vx

X = x + vx*T
Y = y + vy*T
T = t + vy*T
if (X//n)%2 == 0 and (Y//m)%2 == 0 :
    done(0,0)
elif (X//n)%2 == 0:
    done(0,m)
elif (Y//m)%2 == 0:
    done(n,0)
else:
    done(n,m)


def getIntList():
    return list(map(int, input().split()));
def getTransIntList(n):
    first=getIntList();
    m=len(first);
    result=[[0]*n for _ in range(m)];
    for i in range(m):
        result[i][0]=first[i];
    for j in range(1, n):
        curr=getIntList();
        for i in range(m):
            result[i][j]=curr[i];
    return result;
n, m, x, y, vx, vy=getIntList();
#Возвращает НОД d и коэффициенты k1, k2: k1*n1+k2*n2=d
def GCDKoef(n1, n2):
    k11=1;
    k12=0;
    k21=0;
    k22=1;
    while n2>0:
        k, r=divmod(n1, n2);
        n1, n2= n2, r;
        #r=n1-n2*k
        k11, k12, k21, k22 = k21, k22, k11 - k21 * k, k12 - k22*k;
    return n1, k11, k12;
def solveSystemCongruence(a1, n1, a2, n2):
    d, k1, k2=GCDKoef(n1, n2);
    if (a1-a2)%d!=0:
        return None;
    #t===a1(n1), t===a2(n2), d=GCD(n1, n2), d=n1*k1+n2*k2
    #r=a1%d=a2%d; a1=r+d*x1 a2=r+d*x2
    #t=r+x1*n2*k2+x2*n1*k1===r+d*x1=a1(n1) ===r+d*x2=a2(n2)
    r=a1%d;
    x1=(a1-r)//d;
    x2=(a2-r)//d;
    t=r+x1*n2*k2+x2*n1*k1;
    mod=n1*n2//d;
    t%=mod;
    if t<0:
        t+=mod;
    return t;
if vx==0:
    if x!=0 and x!=n:
        print(-1);
    elif vy==1:
        print(x, m)
    else:
        print(x, 0);
elif vy==0:
    if y!=0 and y!=m:
        print(-1);
    elif vx==1:
        print(n, y);
    else:
        print(0, y);
else:
    t=solveSystemCongruence(-x*vx, n, -y*vy, m);
    if t==None:
        print(-1);
    else:
        x=x+t*vx;
        y=y+t*vy;
        x//=n;
        y//=m;
        x%=2;
        y%=2;
        x=abs(x);
        y=abs(y);
        print(x*n, y*m);


# -*- coding: utf-8 -*-
import sys,copy,math,heapq,itertools as it,fractions,re,bisect,collections as coll

MX = 1180000
prime = [1] * MX
prime[0] = prime[1] = 0
for i in xrange(2, int(MX ** 0.5 + 1e-8)):
    if prime[i]:
        prime[2 * i::i] = [0] * len(prime[2 * i::i])

p, q = map(int, raw_input().split())
pi = rub = ans = 0
for i in xrange(1, MX):
    pi += prime[i]
    if i == int(str(i)[::-1]): rub += 1
    if q * pi <= p * rub:
        ans = max(ans, i)

print ans


"""
NTC here
"""
import sys
inp = sys.stdin.readline
def input(): return inp().strip()
# flush= sys.stdout.flush
# import threading
# sys.setrecursionlimit(10**6)
# threading.stack_size(2**26)

def iin(): return int(input())

def lin(): return list(map(int, input().split()))

# range = xrange
# input = raw_input

def primetilln(n):
    prime = [True for i in range(n+1)]
    p = 2
    while (p * p <= n):

        if (prime[p] == True):
            for i in range(p * 2, n+1, p):
                prime[i] = False
        p += 1
    primes = set()
    for i in range(2, n):
        if prime[i]:
            primes.add(i)
    return primes

def main():
    def check_palindrom(x):
        s = list(str(x))
        return s==s[::-1]

    T = 1
    while T:
        T-=1
        p, q = lin()
        mx = 10**7+10
        a = primetilln(mx-1)
        a1 = [0]*mx
        a2 = [0]*mx
        for i in a:a1[i]+=1
        for i in range(1, mx):
            if check_palindrom(i):
                a2[i]+=1
        for i in range(1, mx):
            a1[i]+=a1[i-1]
            a2[i]+=a2[i-1]
        # print(a2[:20])
        ans = 0
        for i in range(1, mx):
            if a1[i]*q<=p*a2[i]:
                ans=max(ans, i)
        print(ans if ans else "Palindromic tree is better than splay tree")

main()

# threading.Thread(target=main).start()


x, y, z, k = [int(x) for x in input().split()]

dim = sorted([x - 1, y - 1, z - 1])

answer = [0, 0, 0]

for i in range(len(dim)):
    dimi = dim[i]
    if dimi * (3 - i) <= k:
        k = k - (dimi * (3 - i))
        for j in range(i, 3):
            answer[j] += dimi
        for j in range(3):
            dim[j] -=  dimi
    else:
        for j in range(i, 3):
            answer[j] += k // (3 - i)
        for j in range(i, (k % (3 - i)) + i):
            answer[j] += 1
        break

true_ans = 1

for i in answer:
    true_ans = true_ans * (i + 1)

print(true_ans)


def main():
    M=998244353
    n,k,*h=map(int,open(0).read().split())
    m=sum(i!=j for i,j in zip(h,h[1:]+h[:1]))
    f=[0]*(m+1)
    f[0]=b=1
    for i in range(1,m+1):f[i]=b=b*i%M
    inv=[0]*(m+1)
    inv[m]=b=pow(f[m],M-2,M)
    for i in range(m,0,-1):inv[i-1]=b=b*i%M
    comb=lambda n,k:f[n]*inv[n-k]*inv[k]%M
    print((pow(k,m,M)-sum(comb(m,i)*comb(m-i,i)*pow(k-2,m-i-i,M)for i in range(m//2+1)))*pow(k,n-m,M)*pow(2,M-2,M)%M)
main()


import sys

# read int
n = int(sys.stdin.readline().strip())
sum = 0
f1 = 1
f2 = 1
mod = 1000000007
for i in range(n):
    sum = (sum + f2) % mod
    f1, f2 = f2, (f1+f2) % mod
print sum


# Legends Always Come Up with Solution
# Author: Manvir Singh

import os
from io import BytesIO, IOBase
import sys
from collections import defaultdict,deque,Counter
from bisect import *
from math import sqrt,pi
import math
from itertools import permutations
from copy import deepcopy

def main():
    n = int(input())
    mod = 10 ** 9 + 7
    if n >= 2:
        dp = [0 for i in range(n)]
        dp[0], dp[1] = 1, 2
        ans = 3
        for i in range(2, n):
            dp[i] = (dp[i - 1] + dp[i - 2]) % mod
            ans = (ans + dp[i]) % mod
        print(ans)
    else:
        print(1)
# region fastio
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")

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

if __name__ == "__main__":
    main()


#Simple non-optimized class of matrices. Used with small dense matrices.
import functools
import itertools
import math

class NotAMatrixError(Exception):
    pass

class MatrixSizeError(Exception):
    def __init__(self, s1, s2):
        print('sizes do not match : ', s1, ', ', s2)

class NotSquareError(Exception):
    pass

class Matrix(list):
    def __init__(self, L):
        if type(L) == type(self):
            self = L
            return
        n = len(L)
        m = len(L[0])
        for i in range(n):
            if len(L[i]) != m:
                raise NotAMatrixError()
        list.__init__(self, L)
        self.n = n
        self.m = m
        self.degrees = []
    def check_size(self, M, mode):
        n, m = len(M), len(M[0])
        for i in range(n):
            if len(M[i]) != m:
                raise NotAMatrixError()

        if mode == 'add' and (self.n != n or self.m != m):
            raise MatrixSizeError((self.n, self.m), (n,m))
        if mode == 'lul' and self.m != n:
            print(self.m, n, self.m != n)
            raise MatrixSizeError((self.n, self.m), (n,m))
    def __add__(self, M):
        self.check_size(M, mode = 'add')
        return Matrix([[self[i][j]+M[i][j] for j in range(self.m)]for i in range(self.n)])
    def __iadd__(self, M):
        self.check_size(M, mode = 'add')
        for i in range(self.n):
            for j in range(self,m):
                self[i][j] += M[i][j]
    def __mul__(self, M):
        self.check_size(M, mode = 'mul')
        l = len(M[0])
        return Matrix([[sum(self[i][k]*M[k][j] for k in range(self.m))
                 for j in range(l)] for i in range(self.n)])
    def issquare(self):
        return self.n == self.m
    def primary(self):
        if self.n != self.m:
            raise NotSquareError()
        return Matrix([[int(i==j) for j in range(self.m)] for i in range(self.n)])
    def __pow__(self, n):
        if self.n != self.m:
            raise NotSquareError()
        if n == 0:
            return self.primary()
        elif n == 1:
            return self
        if len(self.degrees) == 0:
            self.degrees.append(self*self)
        for i in range(n.bit_length() - len(self.degrees) - 1):
            self.degrees.append(self.degrees[-1] * self.degrees[-1])
        s = [(n>>i)&1 for i in range(1,n.bit_length())]
        res = functools.reduce(lambda x,y:x*y, itertools.compress(self.degrees, s))
        return res*self if n%2 else res
    def drop_degrees(self):
        self.degrees.clear()

class Remainder(int):
    def __new__(self, n, p):
        obj = int.__new__(self, n%p)
        obj.p = p
        return obj
    def __mul__(self, m): return Remainder(int.__mul__(self, m), self.p)
    def __add__(self, m): return Remainder(int.__add__(self, m), self.p)
    def __sub__(self, m): return Remainder(int.__sub__(self, m), self.p)
    def __rmul__(self, m): return Remainder(int.__rmul__(self, m), self.p)
    def __radd__(self, m): return Remainder(int.__radd__(self, m), self.p)
    def __rsub__(self, m): return Remainder(int.__rsub__(self, m), self.p)
    def __neg__(self): return Remainder(int.__neg__(self), self.p)
    def __pow__(self, m): return Remainder(int.__pow__(self, m, self.p), self.p)

def solve(n, sx, sy, dx, dy, t):
    o, l, j = Remainder(0, n), Remainder(1, n), Remainder(2, n)
    N = [[j, l, l, o, l, o],
         [l, j, o, l, l, o],
         [l, l, l, o, l, o],
         [l, l, o, l, l, o],
         [o, o, o, o, l, l],
         [o, o, o, o, o, l]]
    M = Matrix(N)
    sx, sy, dx, dy = map(lambda x: Remainder(x, n), [sx, sy, dx, dy])
    v = Matrix([[sx], [sy], [dx], [dy], [o], [l]])
    return M ** t * v

n, sx, sy, dx, dy, t = [int(x) for x in input().split()]
ans = solve(n, sx, sy, dx, dy, t)
print(int(ans[0][0] - 1) + 1, int(ans[1][0] - 1) + 1)


mod, sx, sy, dx, dy, t = map(int, input().split())
class Matrix():
    def __init__(self, n):
        self.n = n
        self.a = [[0] * n for _ in range(n)]

    def __mul__(self, b):
        res = Matrix(self.n)
        for i in range(self.n):
            for j in range(self.n):
                for k in range(self.n):
                    res.a[i][j] += self.a[i][k] * b.a[k][j] % mod
                    res.a[i][j] %= mod
        return res

    def __pow__(self, e):
        res = Matrix(self.n)
        for i in range(self.n):
            res.a[i][i] = 1
        tmp = self
        while e:
            if e & 1:
                res = res * tmp
            e >>= 1
            tmp = tmp * tmp
        return res
M = Matrix(6)
M.a = [[2, 1, 1, 0, 1, 2],
       [1, 2, 0, 1, 1, 2],
       [1, 1, 1, 0, 1, 2],
       [1, 1, 0, 1, 1, 2],
       [0, 0, 0, 0, 1, 1],
       [0, 0, 0, 0, 0, 1]]
sx -= 1
sy -= 1
r = M ** t
f = lambda i: (r.a[i][0] * sx + r.a[i][1] * sy + r.a[i][2] * dx + r.a[i][3] * dy + r.a[i][5]) % mod + 1
print(f(0), f(1))


n, C = map(int, raw_input().split())
fac = [1]
z = 1000003
for i in range(1, 700000):
    fac.append((fac[-1] * i) % z)
ans = 0
for i in range(1, n+1):
    x = (fac[i+C-1] * pow(fac[i], z-2, z) * pow(fac[C-1], z-2, z)) % z
    ans = (ans + x) % z
print(ans)


from collections import defaultdict
import sys
from itertools import *
sys.setrecursionlimit(999999999)

n,c = map(int,raw_input().split())

P = 10**6+3
fak= [1]*P

for i in xrange(P-1):
    fak[i+1]= (fak[i]*(i+1))%P

def pow(q,w):
    if w==0:
        return 1
    pom = pow(q,w/2)
    h = 1
    if w%2:
        h = q
    return (((pom*pom)%P)*h)%P

def inv(q):
    return pow(q,P-2)

ans = -1
i=n
ans+= (fak[n+c]* inv(fak[n])*inv(fak[c]))%P

print ans


from math import *

class sqrt_decomp:
    def _init_(self,val):
        self.values=val
        self.blockl=int(sqrt(len(val)))
        self.noblocks=int(ceil(len(val)/self.blockl))
        self.plusv=[0]*self.noblocks
        self.sumbl=[0]*self.noblocks
        for i in range(self.noblocks):
            self.sumbl=sum(val[i*self.blockl:max(len(val),(i+1)*self.blockl)])

def maximize(n,X,l):
    if l==0:
        return 0
    cur=ans[l-1]
    X-=cur**3
    while X+(cur+1)**3<=n:
        cur+=1
        #print("again",cur,X,X+cur**3,n)
    Xy=cur**3
    Xy+=maximize(min(n-Xy,(cur+1)**3-Xy-1),X,l-1)
    ans[l-1]=cur
    return Xy

n=int(input())
c=1
ans=[]
X=0
while X+c**3<=n:
    while X<(c+1)**3-c**3 and X+c**3<=n:
        ans+=[c]
        X+=c**3
        #print(c,X,ans)
    c+=1
    #print(c,c**3,X,n,"rofl")
X=maximize(n,X,len(ans))
print(len(ans),X)
#print(ans)


def solve(m, cubes, volume):
  if m == 0:
    return [cubes, volume]

  x = 1
  while (x ** 3) <= m:
    x += 1
  x -= 1

  best = solve(m - (x ** 3), cubes + 1, volume + x ** 3)
  if x > 1:
    best = max(best, solve((x ** 3) - 1 - ((x - 1) ** 3), cubes + 1, volume + (x - 1) ** 3))

  return best

m = int(raw_input())
print " ".join(map(str, solve(m, 0, 0)))
#cubes = list(reversed([i * i * i for i in xrange(1, 20)]))


import sys
input = sys.stdin.readline

from functools import lru_cache

k, M = map(int, input().split())

MOD = M

def modmul(x, y, c = 0):
    return (x * y + c) % MOD

mod_mul = modmul

def inv(x):
    return pow(x, MOD - 2, MOD)

MAX = 10 ** 5

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

invfact = [1] * (MAX)
invfact[MAX - 1] = inv(fact[MAX - 1])
for i in range(MAX - 2, -1, -1):
    invfact[i] = modmul(i + 1, invfact[i+1])

def comb(x, y):
    assert 0 <= y <= x

    return modmul(fact[x], modmul(invfact[y], invfact[x - y]))

def invcomb(x, y):
    return modmul(invfact[x], modmul(fact[y], fact[x - y]))

def invs(x):
    return modmul(fact[x - 1], invfact[x])

def count(a, b):
    if a + b == 0:
        return 1
    return modmul(a, fact[a + b - 1])

n = k

pn1 = [1]
for i in range(5000):
    pn1.append(modmul(pn1[-1], n - 1))

out = 0
for i in range(1, n):

    pni = [1]
    for _ in range(5000):
        pni.append(modmul(pni[-1], n - i))

    for j in range(i + 1):
        if n - i - j < 0:
            continue

        stab = comb(n, i)
        app = modmul(comb(i, j), comb(n - i, n - i - j))
        order = count(j, n - i - j)
        sao = modmul(modmul(stab, app), order)
        #sao = 1

        #u1 = pow(n - i, i - j, M)
        #u2 = pow(n - 1, j, M)
        u1 = pni[i - j]
        u2 = pn1[j]
        u = modmul(u1, u2)
        #u = 1

        #print(i, j, stab, app, order, u1, u2)

        out += modmul(sao, u)

print(out % M)


from math import sqrt

class vector:
	def __init__(self, _x = 0, _y = 0):
		self.x = _x
		self.y = _y
	def len(self):
		return sqrt(self.x ** 2 + self.y ** 2)
	def len_sq(self):
		return self.x ** 2 + self.y ** 2
	def __mul__(self, other):
		if (type(self) == type(other)):
			return self.x * other.x + self.y * other.y
		return vector(self.x * other, self.y * other)
	def __mod__(self, other):
		return self.x * other.y - self.y * other.x
	def normed(self):
		length = self.len()
		return vector(self.x / length, self.y / length)
	def normate(self):
		self = self.normed()
	def __str__(self):
		return "(" + str(self.x) + ", " + str(self.y) + ")"
	def __add__(self, other):
		return vector(self.x + other.x, self.y + other.y);
	def __sub__(self, other):
		return vector(self.x - other.x, self.y - other.y);
	def __eq__(self, other):
		return self.x == other.x and self.y == other.y
	def rot(self):
		return vector(self.y, -self.x)

class line:
	def __init__(self, a = 0, b = 0, c = 0):
		self.a = a
		self.b = b
		self.c = c
	def intersect(self, other):
		d = self.a * other.b - self.b * other.a
		dx = self.c * other.b - self.b * other.c
		dy = self.a * other.c - self.c * other.a
		return vector(dx / d, dy / d)
	def fake(self, other):
		d = self.a * other.b - self.b * other.a
		return d
	def __str__(self):
		return str(self.a) + "*x + " + str(self.b) + "*y = " + str(self.c)

def line_pt(A, B):
		d = (A - B).rot()
		return line(d.x, d.y, d * A)

class circle:
	def __init__(self, O = vector(0, 0), r = 0):
		self.O = O
		self.r = r
	def intersect(self, other):
		O1 = self.O
		O2 = other.O
		r1 = self.r
		r2 = other.r
		if (O1 == O2):
			return []
		if ((O1 - O2).len_sq() > r1 ** 2 + r2 ** 2 + 2 * r1 * r2):
			return []
		rad_line = line(2 * (O2.x - O1.x), 2 * (O2.y - O1.y), r1 ** 2 - O1.len_sq() - r2 ** 2 + O2.len_sq())
		central = line_pt(O1, O2)
		M = rad_line.intersect(central)
		# print(M)
		if ((O1 - O2).len_sq() == r1 ** 2 + r2 ** 2 + 2 * r1 * r2):
			return [M]
		d = (O2 - O1).normed().rot()
		if (r1 ** 2 - (O1 - M).len_sq() < 0):
			return []
		d = d * (sqrt(r1 ** 2 - (O1 - M).len_sq()))
		return [M + d, M - d]
	def fake(self, other):
		O1 = self.O
		O2 = other.O
		r1 = self.r
		r2 = other.r
		if (O1 == O2):
			return 1
		if ((O1 - O2).len_sq() > r1 ** 2 + r2 ** 2 + 2 * r1 * r2):
			return 1
		rad_line = line(2 * (O2.x - O1.x), 2 * (O2.y - O1.y), r1 ** 2 - O1.len_sq() - r2 ** 2 + O2.len_sq())
		central = line_pt(O1, O2)
		return rad_line.fake(central)

# a = vector(3, 4)
# b = vector(4, 4)
# print(circle(vector(1, 2), 3).intersect(circle(vector(2, 1), 6)))
n = int(input())
arr = []
m = 1
for i in range(n):
	x, y, r = map(int, input().split())
	arr.append(circle(vector(x, y), r))
for i in range(n):
	for j in range(i + 1, n):
		m *= arr[i].fake(arr[j])
for i in range(n):
	arr[i].O = arr[i].O * m
	arr[i].r = arr[i].r * m
# print(m)
s = set()
V = 0
for i in range(n):
	for j in range(i + 1, n):
		tmp = arr[i].intersect(arr[j])
		for e in tmp:
			s.add((round(e.x, 6), round(e.y, 6)))
V += len(s)
E = 0

par = [i for i in range(n)]

def get_par(v):
	if (par[v] != v):
		par[v] = get_par(par[v])
	return par[v]
def unite(v, u):
	par[get_par(v)] = get_par(u)
for i in range(n):
	s = set()
	for j in range(n):
		tmp = arr[i].intersect(arr[j])
		if (len(tmp)):
			unite(i, j)
		for e in tmp:
			s.add((round(e.x, 	), round(e.y, 	)))
	E += len(s)
# print(V, E)
# print(len({get_par(i) for i in range(n)}))
print(E - V + 1 + len({get_par(i) for i in range(n)}))


import bisect
def LIS(As):
    L = [As[0]]
    for a in As[1:]:
        if a >= L[-1]:
            L.append(a)
        else:
            pos = bisect.bisect_right(L, a)
            L[pos] = a
    return L

def solve():
    n,T = map(int,input().split())
    array = list(map(int,input().split()))
    if (T<=n+1):
        print (len(LIS(array*T)))
    else:
        newarray = array*n
        lis = LIS(newarray)
        newlis = LIS(newarray+array)
        print (len(newlis)+(len(newlis)-len(lis))*(T-n-1))

solve()


N=400
R=lambda:map(int,raw_input().split())
n,t=R()
a=R()
def mk(s):
  v=[0]*N
  t=[0]*N
  for x in s:
    c=0
    i=x
    while i>0:
      c=max(c,v[i])
      i-=i&-i
    t[x]=max(t[x],c+1)
    i=x
    while i<N:
      v[i]=max(v[i],c+1)
      i+=i&-i
  return t
if t>n*2:
  f=mk(a*n)
  b=mk([321-x for x in (a*n)[::-1]])
  z=0
  for x in a:
    z=max(z,f[x]+b[321-x]+a.count(x)*(t-2*n))
  print z
else:
  print max(mk(a*t))


import math
x, y, z = map(int, input().split())
a, b, c = map(int, input().split())
s, rs, ls = map(int, input().split())
def rec(ss):
    for i in range(0, 205, 1):
        for j in range(0, 105, 1):
            if(i * rs + j * ls <= ss):
                q = y + i;p = z + j; pq = x + ((int)((ss - i * rs - j *ls) / s))
                an1 = 1000000000000.0;an2 = 1000000000000.0
                if(b - p > 0):
                    an1 = math.ceil(((float) (pq)) / ((float)(b - p)))
                if(q - c > 0):
                    an2 = math.ceil(((float) (a)) / ((float)(q - c)))
                if(q > c and p >= b or an1 > an2):
                    return True
    return False
st = 0; en = 100000; mid = 0
while(st <= en):
    mid = (int)((st + en) / 2)
    if(rec(mid) == True):
        en = mid - 1
    else:
        st = mid + 1
print(en + 1)


I=lambda:map(int,input().split())
R=list(range(999))
q,w,e=I()
r,t,y=I()
a,b,c=I()
print(min(i*b+j*c+max(0,(r//(w+i-y)+bool(r%(w+i-y)))*(t-e-j)-q+1)*a for i in R for j in R if w+i>y))


import sys
range = xrange
input = raw_input

MOD = 10**9 + 7
def fac(x):
    i = 1
    for j in range(2 , x + 1):
        i = i * j % MOD
    return i

fac = [1]
for i in range(1, 10**6 + 10):
    fac.append(int(fac[-1] * i % MOD))

n = int(input())
def ways(prevg, g):
    cur = n//g - n//prevg if prevg else n//g
    left = n - n//g

    a = cur
    for i in range(left + 1, left + cur):
        a = a * i % MOD
    #a = fac[cur] * pow(left+1, cur - 1, MOD)
    b = +(g == 1)
    for x in 2,3:
        if g % x == 0:
            b += ways(g, g // x)
    return a * b

a = 1
while a * 2 <= n:
    a *= 2

ans = ways(0, a)
if a //2 * 3 <= n:
    ans += ways(0, a //2 * 3)

print ans % MOD


import os, sys
from math import trunc

MOD = 998244353
MODF = float(MOD)
SHRT = float(1 << 16)
G = 3.0
MAXSIZ = 1 << 20

# Using pajenegod's crazy method for multiplication using floating point
fmod = lambda x: x - MODF * trunc(x / MODF)
mod_prod = lambda a, b: fmod(trunc(a / SHRT) * fmod(b * SHRT) + (a - SHRT * trunc(a / SHRT)) * b)
def fpow(a, b):
    r = 1.0
    while b:
        if b & 1: r = mod_prod(r, a)
        if b > 1: a = mod_prod(a, a)
        b >>= 1
    return r

inp = os.read(sys.stdin.fileno(), 10 ** 8).split()
n, k = int(inp[0]), int(inp[1])
f = [0.0] * MAXSIZ
for i in xrange(2, k + 2):
    f[int(inp[i])] = 1.0

m = MAXSIZ
m2 = m / 2
w = [1.0] * m2
w[1] = fpow(G, (MOD - 1) / m)
for i in xrange(2, m2):
    w[i] = mod_prod(w[i - 1], w[1])

rev = [0] * m
for i in xrange(m):
    rev[i] = rev[i >> 1] >> 1
    if i & 1: rev[i] |= m2

def ntt_transform(a):
    for i in xrange(m):
        if i < rev[i]: a[i], a[rev[i]] = a[rev[i]], a[i]
    l = 2
    while l <= m:
        half, diff = l >> 1, m / l
        for i in xrange(0, m, l):
            pw = 0
            for j in xrange(i, i + half):
                v = mod_prod(a[j + half], w[pw])
                a[j + half] = a[j] - v
                a[j] = a[j] + v
                pw += diff
        l <<= 1

ntt_transform(f)
f = [fpow(x, n >> 1) for x in f]
ntt_transform(f)

inv_m = fpow(m, MOD - 2)
ans = mod_prod(sum(mod_prod(x, x) for x in f) % MODF, mod_prod(inv_m, inv_m))
os.write(sys.stdout.fileno(), str(int(ans)))


#!/usr/bin/env python
"""
This file is part of https://github.com/Cheran-Senthil/PyRival.

Copyright 2018 Cheran Senthilkumar all rights reserved,
Cheran Senthilkumar <hello@cheran.io>
Permission to use, modify, and distribute this software is given under the
terms of the MIT License.

"""
from __future__ import division, print_function

import cmath
import itertools
import math
import operator as op
# import random
import sys
from atexit import register
from bisect import bisect_left, bisect_right
# from collections import Counter, MutableSequence, defaultdict, deque
# from copy import deepcopy
# from decimal import Decimal
# from difflib import SequenceMatcher
# from fractions import Fraction
# from heapq import heappop, heappush

if sys.version_info[0] < 3:
    # from cPickle import dumps
    from io import BytesIO as stream
    # from Queue import PriorityQueue, Queue
else:
    # from functools import reduce
    from io import StringIO as stream
    # from pickle import dumps
    # from queue import PriorityQueue, Queue

if sys.version_info[0] < 3:
    class dict(dict):
        """dict() -> new empty dictionary"""
        def items(self):
            """D.items() -> a set-like object providing a view on D's items"""
            return dict.iteritems(self)

        def keys(self):
            """D.keys() -> a set-like object providing a view on D's keys"""
            return dict.iterkeys(self)

        def values(self):
            """D.values() -> an object providing a view on D's values"""
            return dict.itervalues(self)

    input = raw_input
    range = xrange

    filter = itertools.ifilter
    map = itertools.imap
    zip = itertools.izip

def sync_with_stdio(sync=True):
    """Set whether the standard Python streams are allowed to buffer their I/O.

    Args:
        sync (bool, optional): The new synchronization setting.

    """
    global input, flush

    if sync:
        flush = sys.stdout.flush
    else:
        sys.stdin = stream(sys.stdin.read())
        input = lambda: sys.stdin.readline().rstrip('\r\n')

        sys.stdout = stream()
        register(lambda: sys.__stdout__.write(sys.stdout.getvalue()))

def gcd(x, y):
    """greatest common divisor of x and y"""
    while y:
        x, y = y, x % y
    return x

def main():
    n, k = map(int, input().split(' '))
    n //= 2

    inv = [1] * (9*n + 2)
    for i in range(2, 9*n + 2):
        inv[i] = -inv[998244353 % i] * (998244353 // i) % 998244353

    a = list(map(int, input().split(' ')))
    mi = min(a)

    a = list(map(lambda x: x - mi, a))
    a.remove(0)

    b = [0] * 16
    b[0] = 1

    ans = 0
    for i in range(9*n + 1):
        ans += b[i & 15] * b[i & 15]
        if ans >= 7971934306371108872:
            ans -= 7971934306371108872

        s = 0
        for x in a:
            s += b[(i - x + 17) & 15] * (n * x - (i - x + 1))
        b[(i + 1) & 15] = s % 998244353 * inv[i + 1] % 998244353

    print(ans % 998244353)

if __name__ == '__main__':
    sync_with_stdio(False)
    main()


mod , maxn , cur , ans , r = 998244353, 1000005, 10, 0 , 0
dp, x , a = [0] * maxn, [0] * maxn , [0] * 12 ,
x[1] = 1
dp[0] = 1
for i in range(2 , maxn):
    x[i] = mod - (mod// i) *x[mod % i] % mod;
n , k = map(int,input().split())
n = n // 2
p = [0] * k
for u in map(int,input().split()):
    cur = min(cur , u)
    p[r] = u
    r += 1
for i in range(k):
    a[p[i] - cur] = 1
for i in range (n * 10 + 1):
    sm,  j = 0, 0
    while j < min(10 , i + 1):
        sm += dp[i-j] * (j+1) * a[j+1] * n % mod
        j+= 1
    j = 1
    while j < min(10 , i + 1):
        sm -= dp[i-j+1] * (i-j+1) * a[j]
        j+= 1
    ans = (ans + dp[i] * dp[i]) %mod
    dp[i+1] = sm * x[i+1] % mod
print(ans % mod)


from math import trunc

MOD = 998244353
MODF = float(MOD)
SHRT = float(1 << 16)

# Using pajenegod's crazy method for multiplication using floating point
fmod = lambda x: x - MODF * trunc(x / MODF)
mod_prod = lambda a, b: fmod(trunc(a / SHRT) * fmod(b * SHRT) + (a - SHRT * trunc(a / SHRT)) * b)
def fpow(a, b):
    r = 1.0
    while b:
        if b & 1: r = mod_prod(r, a)
        a = mod_prod(a, a)
        b >>= 1
    return r

n, k = map(int, input().split())
f = [0] * (5 * n + 5)
for d in map(int, input().split()):
    f[d] = 1

def ntt_transform(a, G, inv=False):
    n, k = 1, 0
    while n < len(a):
        k += 1
        n *= 2
    a += [0] * (n - len(a))

    n2 = n // 2
    w = [1] * n2
    w[1] = fpow(G, (MOD - 1) // n)
    if inv: w[1] = fpow(w[1], MOD - 2)
    for i in range(2, n2):
        w[i] = mod_prod(w[i - 1], w[1])

    rev = [0] * n
    for i in range(n):
        rev[i] = rev[i >> 1] >> 1
        if i & 1: rev[i] |= n2
        if i < rev[i]: a[i], a[rev[i]] = a[rev[i]], a[i]

    l = 2
    while l <= n:
        half, diff = l // 2, n // l
        for i in range(0, n, l):
            pw = 0
            for j in range(i, i + half):
                v = mod_prod(a[j + half], w[pw]);
                a[j + half] = a[j] - v if a[j] - v >= 0 else a[j] - v + MOD
                a[j] = a[j] + v if a[j] + v < MOD else a[j] + v - MOD
                pw += diff
        l *= 2

    if inv:
        inv_n = fpow(n, MOD - 2)
        for i in range(n): a[i] = mod_prod(a[i], inv_n);

ntt_transform(f, 3)
f = [fpow(x, n // 2) for x in f]
ntt_transform(f, 3, inv=True)

ans = sum(mod_prod(x, x) for x in f) % MODF
print(int(ans))


from math import trunc

MOD = 998244353
MODF = float(MOD)
SHRT = float(1 << 16)
G = 3.0
MAXSIZ = 1 << 20

# Using pajenegod's crazy method for multiplication using floating point
fmod = lambda x: x - MODF * trunc(x / MODF)
mod_prod = lambda a, b: fmod(trunc(a / SHRT) * fmod(b * SHRT) + (a - SHRT * trunc(a / SHRT)) * b)
def fpow(a, b):
    r = 1.0
    while b:
        if b & 1: r = mod_prod(r, a)
        a = mod_prod(a, a)
        b >>= 1
    return r

n, k = map(int, raw_input().split())
f = [0.0] * MAXSIZ
for d in map(int, raw_input().split()):
    f[d] = 1.0

m = MAXSIZ
m2 = m / 2
w = [1] * m2
w[1] = fpow(G, (MOD - 1) / m)
for i in range(2, m2):
    w[i] = mod_prod(w[i - 1], w[1])

rev = [0] * m
for i in range(m):
    rev[i] = rev[i >> 1] >> 1
    if i & 1: rev[i] |= m2

def ntt_transform(a):
    for i in range(m):
        if i < rev[i]: a[i], a[rev[i]] = a[rev[i]], a[i]
    l = 2
    while l <= m:
        half, diff = l >> 1, m / l
        for i in range(0, m, l):
            pw = 0
            for j in range(i, i + half):
                v = mod_prod(a[j + half], w[pw])
                a[j + half] = a[j] - v
                a[j] = a[j] + v
                pw += diff
        l <<= 1

ntt_transform(f)
f = [fpow(x, n >> 1) for x in f]
ntt_transform(f)

inv_m = fpow(m, MOD - 2)
ans = mod_prod(sum(mod_prod(x, x) for x in f) % MODF, mod_prod(inv_m, inv_m))
print(int(ans))


class State:
  __slots__ = ['candidate', 'votes', 'last_vote']

  def __init__(self, cand, votes, last):
    self.candidate = cand
    self.votes = votes
    self.last_vote = last

  def beats(self, other, extra):
    return self.votes + extra > other.votes

def main():
  candidates, seats, people, voted = map(int, input().split())
  votes = [0 for i in range(candidates)]
  last_vote = [0 for i in range(candidates)]

  if candidates == 1:
    print(1)
    return

  v = list(map(int, input().split()))
  for t in range(voted):
    cand = v[t] - 1
    votes[cand] += 1
    last_vote[cand] = t

  states = [State(i, votes[i], last_vote[i]) for i in range(candidates)]
  states = sorted(states, key = lambda x : (x.votes, -x.last_vote))
  res = [0 for i in range(candidates)]

  for i in range(candidates):
    if i < candidates - seats:
      low = candidates - seats
      if states[i].beats(states[low], people - voted):
        res[states[i].candidate] = 2
      else:
        res[states[i].candidate] = 3
    else:
      extra = people - voted
      other = i - 1
      place = i

      if extra == 0 and states[i].votes == 0:
        res[states[i].candidate] = 3
        continue

      while other >= 0 and extra > 0:
        needed = states[i].votes - states[other].votes + 1
        if needed <= extra:
          extra -= needed;
          place -= 1
          other -= 1
        else:
          break

      res[states[i].candidate] = (1 if place + seats >= candidates and states[i].votes > 0 else 2)

  for i in res:
    print(i, end = ' ')

main()


from copy import deepcopy
n, k, m, a = [int(i) for i in input().split()]
cn = [0] * (n + 1)
last = [-1] * (n + 1)
v = [int(i) for i in input().split()]

for i in range(len(v)):
    last[v[i]] = i
    cn[v[i]] += 1

cn1 = deepcopy(cn)
last1 = deepcopy(last)

for i in range(1, n + 1):
    cn = deepcopy(cn1)
    last = deepcopy(last1)
    res = [i1 for i1 in range(1, n + 1)]
    res.sort(key=lambda x: (cn[x], -last[x]), reverse = True)
    #print(res)

    for j in range(len(res)):
        if res[j] != i:
            continue
        j1 = j + 1
        lft = m - a
        while j1 < n and lft:
            pls = min(lft, cn[i] - cn[res[j1]] + 1)
            cn[res[j1]] += min(lft, cn[i] - cn[res[j1]] + 1)
            last[res[j1]] = m
            lft -= pls
            j1 += 1

    res.sort(key=lambda x: (cn[x], -last[x]), reverse = True)
    sans = 0
    for j in range(len(res)):
        if res[j] != i:
            continue
        if cn[i] == 0 or j >= k:
            sans = 0
        else:
            sans = 1
        break

    if sans == 1:
        print(1, end= ' ')
        continue

    cn = deepcopy(cn1)
    last = deepcopy(last1)

    if m - a:
        cn[i] += m - a
        last[i] = m - 1

    res.sort(key=lambda x: (cn[x], 0 -last[x]), reverse = True)
    for j in range(len(res)):
        if res[j] != i:
            continue
        if cn[i] == 0 or j >= k:
            sans = 0
        else:
            sans = 1
        break

    if sans:
        print(2, end=' ')
    else:
        print(3, end=' ')


n, m = map(int, input().split())
prev_points = [[] for _ in range(n)]
for _ in range(m):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    prev_points[v].append(u)
k = int(input())
p = [int(pi) - 1 for pi in input().split()]
best_ways_d = [-1] * n
best_ways_nm1 = [0] * n
q = [(p[-1], 0)]
for u, d in q:
    if best_ways_d[u] < 0:
        best_ways_d[u] = d
        d += 1
        for v in prev_points[u]:
            q.append((v, d))
    elif best_ways_d[u] == d:
        best_ways_nm1[u] += 1
ans1 = ans2 = 0
for i in range(1, k):
    u, v = p[i - 1], p[i]
    if best_ways_d[u] <= best_ways_d[v]:
        ans1 += 1
        ans2 += 1
    elif best_ways_nm1[u]:
        ans2 += 1
print(ans1, ans2)


import sys
from collections import deque
input = lambda : sys.stdin.readline().strip()
# for i in range(int(input())):
n,m = map(int,input().split())
g = {}
for i in range(m):
    a,b = map(int,input().split())
    if b-1 in g:
        g[b-1].append(a-1)
    else:
        g[b-1]=[a-1]
k = int(input())
way = list(map(lambda x: int(x)-1,input().split()))
bfs = deque()
bfs.append(way[-1])
lvl = [-1]*n
ans = [0]*n
a = [set() for j in range(n)]
lvl[way[-1]]=0
while bfs:
    v = bfs.popleft()
    for u in g[v]:
        if lvl[u]==-1:
            lvl[u]=lvl[v]+1
            a[u].add(v)
            bfs.append(u)
        elif lvl[u]==lvl[v]+1:
            ans[u]=1
            a[u].add(v)
ansv = 0
ans1 = 0
for v in range(k-1):
    if k-v-1!=lvl[way[v]] and way[v+1] not in a[way[v]]:
        ans1+=1
    elif k-v-1 == lvl[way[v]]:
        break
for v in range(k-1):
    if ans[way[v]] or  a[way[v]].pop()!=way[v+1]:#
        ansv +=1

print(ans1,ansv)


def nextc(m):
    m2 = {}
    for n, c in m.iteritems():
        h = n-1 >> 1
        m2[h] = m2.get(h, 0) + c
        m2[n-1 - h] = m2.get(n-1 - h, 0) + c
    return m2

def countseg(l, s, cache={}):
    if s > l: return 0
    if s == l: return 1
    if (l, s) in cache:
        return cache[l, s]
    h = l-1 >> 1
    out = countseg(h, s) + countseg(l-1 - h, s)
    cache[l, s] = out
    return out

def findx(l, q, ss):
    if l <= max(ss):
        return (l-1 >> 1) + q
    h = l-1 >> 1
    ns = sum(countseg(h, s) for s in ss)
    if q >= ns:
        return h + 1 + findx(l-1 - h, q - ns, ss)
    else:
        return findx(h, q, ss)

def f(l, r):
    m = {l: 1, l-1: 0}
    q = 1
    while r >= q and min(m) > 2:
        r -= q
        q <<= 1
        m = nextc(m)
    mn, mx = min(m), max(m)
    if mx & 1:
        if r >= m[mx]:
            if mx == 3:
                return findx(l, r - m[mx], [1,2])
            return findx(l, r - m[mx], [mn])
        else:
            return findx(l, r, [mx])
    else:
        return findx(l, r, [mn, mx])

def ans(n, k):
    if k == 1: return 1
    if k == 2: return n
    return 2 + f(n - 2, k - 3)

def brute_ans(n, k):
    if k == 1: return 1
    if k == 2: return n
    return 2 + brute_f(n - 2, k - 2)

def brute_f(l, r):
    s = [(0, l)]
    for _ in xrange(r):
        i = max(xrange(len(s)), key=lambda j: s[j][1]-1 >> 1)
        x, d = s[i]
        h = d-1 >> 1
        s = s[:i] + [(x, h), (x+h+1, d-1-h)] + s[i+1:]
    return x+h

def test_n(n):
    for i in xrange(1, n + 1):
        assert brute_ans(n, i) == ans(n, i)

if __name__ == '__main__':
    n, k = map(int, raw_input().split())
    print ans(n, k)


dp = {}
def count(n, low):
	k = (n, low)
	if k in dp: return dp[k]
	l1 = (n-1)/2
	if l1 < low: return 0
	l2 = n - 1 - l1
	dp[k] = 1 + count(l1, low) + count(l2, low)
	return dp[k]

def getPos(l, r, low, want):
	m = (l+r)/2

	want -= 1
	if want == 0: return m

	c1 = count(m-l, low)
	c2 = count(r-m, low+1)

	if c1+c2 >= want:
		return getPos(l, m-1, low, want-c2)
	else:
		return getPos(m+1, r, low, want-c1)

n,k = map(int, raw_input().split())
if k == 1: print 1
elif k == 2: print n
else:
	lo, hi = 0, n+1
	while lo < hi:
		mid = (lo + hi + 1) / 2
		if count(n-2, mid) >= k-2:
			lo = mid
		else:
			hi = mid-1
	print getPos(2,n-1,lo,k-2)


import sys

def solve():
    n = int(input())
    if n == 1: return 0
    res = 1000000
    for other in range(n - 1, 0, -1):
        pair = [n, other]
        temp = 0
        while (pair[0] > 1 or pair[1] > 1) and (pair[0] > 0 and pair[1] > 0):
            if pair[0] > pair[1]: pair[0], pair[1] = pair[1], pair[0]
            pair[1] -= pair[0]
            temp+=1
            if temp > res: break
        if pair[0] == 1 and pair[1] == 1: res = min(res, temp)
    return res

if sys.hexversion == 50594544 : sys.stdin = open("test.txt")
print(solve())


def solve(N, M):
    ans = 0
    while M > 1:
        ans += N // M
        N, M = M, N % M
    if M == 0: return 1000000
    return N - 1 + ans

N = int(input())
ans = 1000000
for M in range(1, N + 1):
    ans = min([ans, solve(N, M)])
print(ans)


MOD = 1000000007
def isSubset(a, b):
    return (a & b) == a
def isIntersect(a, b):
    return (a & b) != 0
def cntOrder(s, t):
    p = len(s)
    m = len(t)
    inMask = [0 for i in range(m)]
    for x in range(p):
        for i in range(m):
            if t[i] % s[x] == 0:
                inMask[i] |= 1 << x
    cnt = [0 for mask in range(1 << p)]
    for mask in range(1 << p):
        for i in range(m):
            if isSubset(inMask[i], mask):
                cnt[mask] += 1
    dp = [[0 for mask in range(1 << p)] for k in range(m + 1)]
    for i in range(m):
        dp[1][inMask[i]] += 1
    for k in range(m):
        for mask in range(1 << p):
            for i in range(m):
                if not isSubset(inMask[i], mask) and isIntersect(inMask[i], mask):
                    dp[k + 1][mask | inMask[i]] = (dp[k + 1][mask | inMask[i]] + dp[k][mask]) % MOD
            dp[k + 1][mask] = (dp[k + 1][mask] + dp[k][mask] * (cnt[mask] - k)) % MOD
    return dp[m][(1 << p) - 1]
def dfs(u):
    global a, graph, degIn, visited, s, t

    visited[u] = True
    if degIn[u] == 0:
        s.append(a[u])
    else:
        t.append(a[u])

    for v in graph[u]:
        if not visited[v]:
            dfs(v)
def main():
    global a, graph, degIn, visited, s, t
    n = int(input())
    a = list(map(int, input().split()))
    c = [[0 for j in range(n)] for i in range(n)]
    for i in range(n):
        c[i][0] = 1
        for j in range(1, i + 1):
            c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD
    degIn = [0 for u in range(n)]
    graph = [[] for u in range(n)]
    for u in range(n):
        for v in range(n):
            if u != v and a[v] % a[u] == 0:
                graph[u].append(v)
                graph[v].append(u)
                degIn[v] += 1
    ans = 1
    curLen = 0
    visited = [False for u in range(n)]
    for u in range(n):
        if not visited[u]:
            s = []
            t = []
            dfs(u)
            if len(t) > 0:
                sz = len(t) - 1
                cnt = cntOrder(s, t)
                ans = (ans * cnt) % MOD
                ans = (ans * c[curLen + sz][sz]) % MOD
                curLen += sz
    print(ans)
if __name__ == "__main__":
    main()


def inv(a):
	return pow(a, MOD-2, MOD) %MOD

def fat(a):
	ans = 1
	for i in range(1, a+1):
		ans = (ans*i)%MOD
	return ans

MOD = 998244353
n, m, k = map(int, input().split())
p = inv(m)

# O(Burro) O(n2)-> Fórmula da experança = sum(x^k * C(n, x) * p^x * q^(n-x))
'''
resp = 0
q = (1 - p + MOD) % MOD
for x in range(1, n+1):
	resp += pow(x, k, MOD) %MOD * fat(n) %MOD * invfat(n-x) %MOD * invfat(x) %MOD *pow(p, x, MOD) %MOD * pow(q, n-x, MOD) %MOD
'''
# O(menos burro) O(nlog(k)) -> atualiza somatório usando valores ja calculados
if n<=k:
	q = (1 - p + MOD) % MOD
	inv_q = inv(q)
	p_aux = p
	q_aux = pow(q, n-1, MOD)
	fn = n
	resp = n * p%MOD * q_aux%MOD
	resp = resp%MOD

	for i in range(2, n+1):
		x = pow(i, k, MOD)
		p_aux = p_aux * p %MOD
		q_aux = q_aux * inv_q
		fn = fn*(n-i+1)%MOD*inv(i)%MOD

		resp = resp + x * fn %MOD * p_aux %MOD * q_aux %MOD
		resp = resp%MOD
	print(resp)

# O(inteligente) O(k2) -> A partir da FGM M(X), identifica padrão das derivadas
# k-ésima derivada de M(X) = E(x^k)
# E(x^k) = n!/(n-k)! * p^k + k*(deriv[k-1] - sum(ind[i]*deriv[i])) + sum(ind[i]*deriv[i+1])
else:
	deriv = [(n*p)%MOD] #E(x) = np
	resp = n*n%MOD*p%MOD*p%MOD - n*p%MOD*p%MOD + n*p%MOD #E(x^2) = n^2p^2 - np^2 + np
	deriv.append(resp%MOD)
	fn = (n*(n-1))%MOD
	v=[1];

	for i in range(3, k+1):
		fn = (fn * (n-i+1) %MOD)%MOD
		w = [(-(i-1)*v[0])%MOD]
		for j in range(len(v)-1):
			w.append((v[j] - (i-1)*v[j+1]%MOD)%MOD)
		w.append((v[-1] + i-1)%MOD)
		v = tuple(w)

		resp = (fn * pow(p, i, MOD))%MOD
		for j in range(len(v)):
			resp = (resp + v[j]*deriv[j]%MOD)%MOD
			resp = resp%MOD
		resp %= MOD
		deriv.append(resp)

	print(deriv[k-1])


dp=[0]*5010
dp[0]=1
n,m,k=map(int,input().split())
t=998244353
for i in range(k):
    for j in range(len(dp)-1, -1, -1):
        if j==0:dp[j]=0
        else:dp[j]=(dp[j-1]*(n-j+1)+dp[j]*j)%t
c=0
for i in range(k+1):
    c+=pow(m,max(n-i,0),t)*dp[i]
    c%=t
den=pow(m,n,t)
den=pow(den,t-2,t)
print((den*c)%t)


from sys import stdin, stdout
import math
from collections import defaultdict

def Comb(nn,rr):
    f = math.factorial
    return f(nn) / f(rr) / f(nn-rr)

n,k,S = [int(x) for x in stdin.readline().split()]
a = [int(x) for x in stdin.readline().split()]

aset = set(a)
alist = list(aset)
alist.sort()

plist = []
for i in alist:
	plist.append((i,a.count(i)))

oplist = []
for x,c in plist:
	tlist = []
	if x > 18:
		for i in xrange(c+1):
			tlist.append((i*x,0,Comb(c,i)))  # (amount added, stickers used, multiplier)
	else:
		xfact = math.factorial(x)
		for nf in xrange(c+1):
			for i in xrange(nf,c+1):
				tlist.append((nf*xfact+(i-nf)*x, nf, Comb(c,i)*Comb(i,nf)))
	oplist.append(tlist)

'''
print plist
for tlist in oplist:
	print tlist

b = list(a)
c = [False for x in a]
for i in xrange(len(b)):
	if b[i] < 19:
		b[i] = math.factorial(b[i])
		c[i] = True
'''

def rec(mult,d,l,i,f,nn,s=0):
	if i < nn:
		for add, nf, mm in oplist[i]:
			x = s + add
			ff = f + nf
			if x <= S and ff <= k:
				if add > 0:
					l.add(x)
					d[ff][x] += mult*mm
				rec(mult*mm, d, l, i+1, ff, nn, x)

'''
def rec(d,l,i,f,nn,s=0):
	if i < nn:
		rec(d,l,i+1,f,nn,s)
		x = s+a[i]
		if x <= S:
			rec(d,l,i+1,f,nn,x)
			l.add(x)
			d[f][x] += 1
		if c[i] and f < k:
			x = s+b[i]
			if x <= S:
				rec(d,l,i+1,f+1,nn,x)
				l.add(x)
				d[f+1][x] += 1
'''

n = len(alist)

dl1 = [defaultdict(int) for i in xrange(k+1)]
dl1[0][0] = 1
nn = n/2
s = set()
rec(1,dl1,s,0,0,nn)
l1 = list(s)
l1.append(0)
dl2 = [defaultdict(int) for i in xrange(k+1)]
dl2[0][0] = 1
s = s = set()
rec(1,dl2,s,nn,0,n)
l2 = list(s)
l2.append(0)

count = 0
l1.sort()
l2.sort(reverse=True)
i = 0
j = 0

while i < len(l1):
	while l2[j] > S - l1[i]:
		j += 1
	if l1[i] + l2[j] == S:
		for m in xrange(k+1):
			for r in xrange(m+1):
				count += dl1[r][l1[i]] * dl2[m-r][l2[j]]
	i += 1

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) 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 and factorial(x) + y <= s:
                        nr[j-1][factorial(x) + y] += t
                    if x + y <= s:
                        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 and y - factorial(x) >= 0:
                        nr[j-1][y - factorial(x)] += t
                    if y - x >= 0:
                        nr[j][y - x] += t
                    nr[j][y] += t
            res = nr
        return res
    dl = f(a[:n/2])
    dr = g(a[n/2:])
    ans = 0
    for i, d in enumerate(dl):
        for x, t in d.viewitems():
            for j in xrange(k - i, k + 1):
                ans += t * dr[j][x]
    print ans
main()


from math import factorial
fac = factorial

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

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

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

count = 0
for i in xrange(k+1):
    for sum1 in first[i]:
        for kk in xrange(k-i+1):
            if s-sum1 in second[kk]:
                count += first[i][sum1]*second[kk][s-sum1]
print count


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

from collections import defaultdict

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

ldp = [ [ defaultdict( int ) for i in range( K + 1 ) ] for j in range( 2 ) ]
ldp[ 0 ][ 0 ][ 0 ] = 1
for i in range( N // 2 ):
  for j in range( K + 1 ):
    ldp[ ~ i & 1 ][ j ].clear()
  for j in range( K + 1 ):
    for key in ldp[ i & 1 ][ j ]:
      ldp[ ~ i & 1 ][ j ][ key ] += ldp[ i & 1 ][ j ][ key ] # toranai
      ldp[ ~ i & 1 ][ j ][ key + A[ i ] ] += ldp[ i & 1 ][ j ][ key ] # toru
      if j + 1 <= K and A[ i ] <= 18:
        ldp[ ~ i & 1 ][ j + 1 ][ key + fact[ A[ i ] ] ] += ldp[ i & 1 ][ j ][ key ] # kaijyou totte toru

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

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

print( ans )


from sys import stdin, stdout
import math
from collections import defaultdict

def Comb(nn,rr):
    f = math.factorial
    return f(nn) / f(rr) / f(nn-rr)

n,k,S = [int(x) for x in stdin.readline().split()]
a = [int(x) for x in stdin.readline().split()]

aset = set(a)
alist = list(aset)
alist.sort()

plist = []
for i in alist:
	plist.append((i,a.count(i)))

oplist = []
for x,c in plist:
	tlist = []
	if x > 18:
		for i in xrange(c+1):
			tlist.append((i*x,0,Comb(c,i)))  # (amount added, stickers used, multiplier)
	else:
		xfact = math.factorial(x)
		for nf in xrange(c+1):
			for i in xrange(nf,c+1):
				tlist.append((nf*xfact+(i-nf)*x, nf, Comb(c,i)*Comb(i,nf)))
	oplist.append(tlist)

def rec(mult,d,l,i,f,nn,s=0):
	if i < nn:
		for add, nf, mm in oplist[i]:
			x = s + add
			ff = f + nf
			if x <= S and ff <= k:
				if add > 0:
					l.add(x)
					d[ff][x] += mult*mm
				rec(mult*mm, d, l, i+1, ff, nn, x)

n = len(alist)

halflist1 = []
halflist2 = []
oplist.reverse()
hl1 = 1
hl2 = 1
for i in xrange(n):
	if hl1 <= hl2:
		hl1 *= len(oplist[i])
		halflist1.append(oplist[i])
	else:
		hl2 *= len(oplist[i])
		halflist2.append(oplist[i])

oplist = halflist1 + halflist2

dl1 = [defaultdict(int) for i in xrange(k+1)]
dl1[0][0] = 1
nn = n/2
s = set()
rec(1,dl1,s,0,0,nn)
l1 = list(s)
l1.append(0)
dl2 = [defaultdict(int) for i in xrange(k+1)]
dl2[0][0] = 1
s = s = set()
rec(1,dl2,s,nn,0,n)
l2 = list(s)
l2.append(0)

count = 0
l1.sort()
l2.sort(reverse=True)
i = 0
j = 0

while i < len(l1):
	while l2[j] > S - l1[i]:
		j += 1
	if l1[i] + l2[j] == S:
		for m in xrange(k+1):
			for r in xrange(m+1):
				count += dl1[r][l1[i]] * dl2[m-r][l2[j]]
	i += 1

print count


import sys

import itertools

from collections import defaultdict

factorials = [1] * 19

for i in range(1, 19):
    factorials[i] = i * factorials[i - 1]

def cumsum(l):
    n = len(l)
    for i in range(1, n):
        l[i] += l[i-1]

def enum(l):

    global K, S

    options = itertools.product(*([(0, 1, 2)] * len(l)))

    d = defaultdict(lambda: [0] * (25 + 1))

    for opts in options:

        s = 0
        marks = 0
        for i, opt in enumerate(opts):

            if s > S:
                break

            if opt == 1:
                s += l[i]
            elif opt == 2:
                if l[i] <= 18:
                    s += factorials[l[i]]
                    marks += 1
                else:
                    s = S + 1

        if s <= S:
            d[s][marks] += 1

    return d

[n, K, S] = map(int, sys.stdin.next().split(' '))
l = sorted(map(int, sys.stdin.next().split(' ')))

p1 = enum(l[:(len(l) / 2)][::-1])
p2 = enum(l[(len(l) / 2):][::-1])

variants = 0
for s in p1:
    if S - s in p2:
        m1 = p1[s]
        m2 = p2[S - s]
        cumsum(m2)
        for (k1, c1) in enumerate(m1[:(K + 1)]):
            c2 = m2[(K - k1)]
            variants += c1 * c2

print(variants)