import math

def good(x):
    while x > 0:
        if x % 10 != 4 and x % 10 != 7:
            return False
        x //=10
    return True

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

l = 1
r = n
if n >= 11:
    l = n-10
if n <= 10 and math.factorial(n) < k:
    print(-1)
else:
    L = r - l + 1
    a = []
    for i in range(L):
        a.append(i)
    b = []
    k -= 1
    for i in range(L):
        x = k//math.factorial(L-i-1)
        y = a[x]
        b.append(y+l)
        a.remove(y)
        k -= x * math.factorial(L-i-1)
    c = []
    if 4 < l:
        c.append(4)
    if 7 < l:
        c.append(7)
    ans = 0
    while len(c) > 0:
        ans += len(c)
        cc = []
        for x in c:
            if x * 10 + 4 < l:
                cc.append(x * 10 + 4)
            if x * 10 + 7 < l:
                cc.append(x * 10 + 7)
        c = cc
    for i in range(L):
        if good(i+l) and good(b[i]):
            ans += 1
    print(ans)


def lucky(x):
    s=str(x)
    return s.count('4')+s.count('7')==len(s)

def Gen_lucky(n):
    s=str(n)
    if(len(s)==1):
        if(s[0]=='4' or s[0]=='7'):
            return 1
        return 0
    x=0
    for i in range(1,len(s)):
        x+=2**i
    if(s[0]<'4'):
        return x
    if(s[0]>'7'):
        return x+2**len(s)
    if(s[0]=='5' or s[0]=='6'):
        return x+(2**(len(s)-1))
    if(s[0]=='7'):
        x+=2**(len(s)-1)
    x+=Getlucky(s[1:])
    return x

def Form(X,k):
    if(k==0):
        return X
    for i in range(len(X)):
        if(k>=F[len(X)-i-1]):
            h=k//F[len(X)-i-1]
            r=k%F[len(X)-i-1]
            G=list(X[i+1:])
            G.remove(X[i+h])
            G=[X[i]]+G
            return Form(X[:i]+[X[i+h]]+G,r)

p=1

F=[1]
i=1
while(p<=10**10):
    p*=i
    F.append(p)
    i+=1

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

if(n<=15):
    L=Form(list(range(1,n+1)),k-1)
    x=0
    for i in range(n):
        if(lucky(i+1) and lucky(L[i])):
            x+=1
    print(x)
else:
    L=Form(list(range(n-13,n+1)),k-1)
    x=Gen_lucky(n-14)
    for i in range(n-13,n+1):
        if(lucky(L[i-n+13]) and lucky(i)):
            x+=1
    print(x)


import math
def isLucky(num):
	s = str(num)
	for i in s:
		if i != '4' and i != '7':
			return False
	return True

def getLucky(d):
	if d == 1:
		for i in [4, 7]:
			yield str(i)
	else:
		l = [i for i in getLucky(d-1)]
		for j in l:
			yield '4'+j
		for j in l:
			yield '7'+j

luckies = []
for d in range(1,11):
	for i in getLucky(d):
		luckies.append(int(i))

def canto(l, k):
	# find the k(th) permutation of list l, k counts from 1
	n = len(l)
	p = k - 1
	a = []
	i = n - 1
	mark = [False]*(n+1)
	while len(a) < n:
		fac = math.factorial(i)

		a.append(p/fac)
		p %= fac
		i -= 1
		j = 1
		cnt = 0
		while cnt < a[-1]+1:
			if not mark[j]:
				cnt += 1
			j += 1
		a[-1] = j-1
		mark[a[-1]] = True
	return [l[i-1] for i in a]

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

for tail in range(1, n+1):
	fac = math.factorial(tail)
	if fac >= k:
		break
l = [i for i in range(n+1-tail, n+1)]
p_tail = canto(l, k)
# print 'tail',tail
# print p_tail

ans = 0
for lucky in luckies:
	if lucky > n: break
	# print 'lucky is',lucky
	if lucky <= n-tail:
		ans += 1
		# print lucky
	else:
		i = p_tail.index(lucky)
		if isLucky(n-tail+1+i):
			ans += 1
			# print lucky
print ans


MOD = 998244353;import __pypy__;int_add = __pypy__.intop.int_add;int_sub = __pypy__.intop.int_sub;int_mul = __pypy__.intop.int_mul
def make_mod_mul(mod=MOD):
    fmod_inv = 1.0 / mod
    def mod_mul(a, b, c=0):
        res = int_sub(int_add(int_mul(a, b), c), int_mul(mod, int(fmod_inv * a * b + fmod_inv * c)))
        if res >= mod:            return res - mod
        elif res < 0:            return res + mod
        else:            return res
    return mod_mul
mod_mul = make_mod_mul()
def mod_pow(x, y):
    if y == 0:        return 1
    res = 1
    while y > 1:
        if y & 1 == 1:            res = mod_mul(res, x)
        x = mod_mul(x, x);        y >>= 1
    return mod_mul(res, x)
n, m = map(int, input().split());pascal = [[1]]
for _ in range(n + m + 5):
    nl = [1]
    for i in range(_):        nl.append((pascal[-1][i] + pascal[-1][i+1]) % MOD)
    nl.append(1);    pascal.append(nl)
def s1(n,m):
    out = 0
    for row in range(1, n):
        above = row
        below = n - row

        bottom = []
        for i in range(m):
            a = below - 1
            b = i
            a2 = below
            b2 = m-i-1
            bottom.append(mod_mul(pascal[a+b][a] , pascal[a2+b2][a2]))

        top = []
        for i in range(m):
            a = above - 1
            b = i
            a2 = above
            b2 = m-i-1
            top.append(mod_mul(pascal[a+b][a] , pascal[a2+b2][a2]))
        top.reverse()

        curr = 0
        for i in range(m):
            out += mod_mul(curr,bottom[i])
            curr += top[i]
            curr %= MOD
            out %= MOD
    return out * 2

def s2(n,m):
    o = 0
    for i in range(1,n):
        for j in range(1,m):
            a = pascal[i+j-1][i-1]
            b = pascal[n-i+j-1][n-i]
            c = pascal[n-i-1+m-j][m-j]
            d = pascal[i+m-j-1][i]
            #print(a,b,c,d)
            o += mod_mul(mod_mul(a,b),mod_mul(c,d))
    return o

c1 = s1(n,m)
c2 = s1(m,n)
c3 = s2(n,m)

out = (c1 + c2 - 2*c3) % MOD
print(out)


MOD = 998244353;import __pypy__;int_add = __pypy__.intop.int_add;int_sub = __pypy__.intop.int_sub;int_mul = __pypy__.intop.int_mul
def make_mod_mul(mod=MOD):
    fmod_inv = 1.0 / mod
    def mod_mul(a, b, c=0):
        res = int_sub(int_add(int_mul(a, b), c), int_mul(mod, int(fmod_inv * a * b + fmod_inv * c)))
        if res >= mod:            return res - mod
        elif res < 0:            return res + mod
        else:            return res
    return mod_mul
mod_mul = make_mod_mul()
def mod_pow(x, y):
    if y == 0:        return 1
    res = 1
    while y > 1:
        if y & 1 == 1:            res = mod_mul(res, x)
        x = mod_mul(x, x);        y >>= 1
    return mod_mul(res, x)
n, m = map(int, input().split());pascal = [[1]]
for _ in range(n + m + 5):
    nl = [1]
    for i in range(_):        nl.append((pascal[-1][i] + pascal[-1][i+1]) % MOD)
    nl.append(1);    pascal.append(nl)
def s1(n,m):
    out = 0
    for row in range(1, n):
        above = row;    below = n - row;     bottom = [];top = []
        for i in range(m):  a = below - 1;     b = i;    a2 = below;    b2 = m-i-1;  bottom.append(mod_mul(pascal[a+b][a] , pascal[a2+b2][a2]))
        for i in range(m):  a = above - 1;  b = i;   a2 = above;    b2 = m-i-1;   top.append(mod_mul(pascal[a+b][a] , pascal[a2+b2][a2]))
        top.reverse();        curr = 0
        for i in range(m):  out += mod_mul(curr,bottom[i]);  curr += top[i];  curr %= MOD;   out %= MOD
    return out * 2
def s2(n,m):
    o = 0
    for i in range(1,n):
        for j in range(1,m):  a = pascal[i+j-1][i-1];       b = pascal[n-i+j-1][n-i]; c = pascal[n-i-1+m-j][m-j];  d = pascal[i+m-j-1][i];   o += mod_mul(mod_mul(a,b),mod_mul(c,d))
    return o
c1 = s1(n,m);c2 = s1(m,n);c3 = s2(n,m);out = (c1 + c2 - 2*c3) % MOD;print(out)


M=998244353;N=4042
try:
    import __pypy__
    int_add=__pypy__.intop.int_add
    int_sub=__pypy__.intop.int_sub
    int_mul=__pypy__.intop.int_mul
    def make_mod_mul(mod=M):
        fmod_inv=1.0/mod
        def mod_mul(a,b,c=0):
            res=int_sub(
                int_add(int_mul(a,b),c),
                int_mul(mod,int(fmod_inv*a*b+fmod_inv*c)),
            )
            if res>=mod:return res-mod
            elif res<0:return res+mod
            else:return res
        return mod_mul
    mod_mul=make_mod_mul()
except:
    def mod_mul(a,b):return(a*b)%M
def mod_add(a,b):
    v=a+b
    if v>=M:v-=M
    if v<0:v+=M
    return v
def mod_sum(a):
    v=0
    for i in a:v=mod_add(v,i)
    return v
f1=[1]
for i in range(N):f1.append(mod_mul(f1[-1],i+1))
f2=[pow(f1[-1],M-2,M)]
for i in range(N):f2.append(mod_mul(f2[-1],N-i))
f2=f2[::-1]
C=lambda a,b:mod_mul(mod_mul(f1[a],f2[b]),f2[a-b])
A=lambda a,b,w:mod_mul(C(a+b,a),C(w+b-a-2,b-1))
def V(h,W,H):
    s=p=0
    for i in range(W-1):
        p=mod_add(p,A(i,H-h,W));s=mod_add(s,mod_mul(p,A(W-2-i,h,W)))
    return s
H,W=map(int,input().split())
Y=mod_sum(mod_mul(A(s,h,W),A(W-2-s,H-h,W))for s in range(W-1)for h in range(1,H))
X=mod_add(mod_sum(V(h,W,H)for h in range(1,H)),mod_sum(V(w,H,W)for w in range(1,W)))
print((X+X-Y-Y)%M)


MOD = 998244353;import __pypy__;int_add = __pypy__.intop.int_add;int_sub = __pypy__.intop.int_sub;int_mul = __pypy__.intop.int_mul
def make_mod_mul(mod=MOD):
    fmod_inv = 1.0 / mod

    def mod_mul(a, b, c=0):
        res = int_sub(int_add(int_mul(a, b), c), int_mul(mod, int(fmod_inv * a * b + fmod_inv * c)))
        if res >= mod:
            return res - mod
        elif res < 0:
            return res + mod
        else:
            return res

    return mod_mul

mod_mul = make_mod_mul()

def mod_pow(x, y):
    if y == 0:
        return 1
    res = 1
    while y > 1:
        if y & 1 == 1:
            res = mod_mul(res, x)
        x = mod_mul(x, x)
        y >>= 1
    return mod_mul(res, x)

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

pascal = [[1]]
for _ in range(n + m + 5):
    nl = [1]
    for i in range(_):
        nl.append((pascal[-1][i] + pascal[-1][i+1]) % MOD)
    nl.append(1)
    pascal.append(nl)

def s1(n,m):
    out = 0
    for row in range(1, n):
        above = row
        below = n - row

        bottom = []
        for i in range(m):
            a = below - 1
            b = i
            a2 = below
            b2 = m-i-1
            bottom.append(mod_mul(pascal[a+b][a] , pascal[a2+b2][a2]))

        top = []
        for i in range(m):
            a = above - 1
            b = i
            a2 = above
            b2 = m-i-1
            top.append(mod_mul(pascal[a+b][a] , pascal[a2+b2][a2]))
        top.reverse()

        curr = 0
        for i in range(m):
            out += mod_mul(curr,bottom[i])
            curr += top[i]
            curr %= MOD
            out %= MOD
    return out * 2

def s2(n,m):
    o = 0
    for i in range(1,n):
        for j in range(1,m):
            a = pascal[i+j-1][i-1]
            b = pascal[n-i+j-1][n-i]
            c = pascal[n-i-1+m-j][m-j]
            d = pascal[i+m-j-1][i]
            #print(a,b,c,d)
            o += mod_mul(mod_mul(a,b),mod_mul(c,d))
    return o

c1 = s1(n,m)
c2 = s1(m,n)
c3 = s2(n,m)

out = (c1 + c2 - 2*c3) % MOD
print(out)


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


mod, sx, sy, dx, dy, t = map(int, raw_input().split())
v = (sx - 1, sy - 1, dx + sx + sy, dy + sx + sy, 1, 1)
A = [
[1, 0, 1, 0, 0, 0],
[0, 1, 0, 1, 0, 0],
[1, 1, 2, 1, 1, 2],
[1, 1, 1, 2, 1, 2],
[0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1]
]
I = lambda: [[1 if i == j else 0 for j in xrange(6)] for i in xrange(6)]
def mul(M, N):
    global mod
    res = [[0] * 6 for i in xrange(6)]
    for i in xrange(6):
        for j in xrange(6):
            for k in xrange(6):
                res[i][j] += M[i][k] * N[k][j]
                res[i][j] %= mod
    return res
def power(M, k):
    if k > 1:
        res = power(M, k/2)
        res = mul(res, res)
        if k % 2:
            res = mul(res, M)
        return res
    elif k == 1:
        return M
    else:
        return I()
B = power(A, t)
V = [0] * 6
for i in xrange(6):
    for j in xrange(6):
        V[i] += B[i][j] * v[j]
        V[i] %= mod
print V[0] + 1, V[1] + 1


od, sx, sy, dx, dy, t = map(int, raw_input().split())
v = (sx - 1, sy - 1, dx + sx + sy, dy + sx + sy, 1, 1)
A = [
[1, 0, 1, 0, 0, 0],
[0, 1, 0, 1, 0, 0],
[1, 1, 2, 1, 1, 2],
[1, 1, 1, 2, 1, 2],
[0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1]
]
I = lambda: [[1 if i == j else 0 for j in xrange(6)] for i in xrange(6)]
def mul(M, N):
    global mod
    res = [[0] * 6 for i in xrange(6)]
    for i in xrange(6):
        for j in xrange(6):
            for k in xrange(6):
                res[i][j] += M[i][k] * N[k][j]
                res[i][j] %= mod
    return res
def power(M, k):
    if k > 1:
        res = power(M, k/2)
        res = mul(res, res)
        if k % 2:
            res = mul(res, M)
        return res
    elif k == 1:
        return M
    else:
        return I()
B = power(A, t)
V = [0] * 6
for i in xrange(6):
    for j in xrange(6):
        V[i] += B[i][j] * v[j]
        V[i] %= mod
print (V[0] + 1, V[1] + 1)


od, sx, sy, dx, dy, t = map(int, raw_input().split())
v = (sx - 1, sy - 1, dx + sx + sy, dy + sx + sy, 1, 1)
A = [
[1, 0, 1, 0, 0, 0],
[0, 1, 0, 1, 0, 0],
[1, 1, 2, 1, 1, 2],
[1, 1, 1, 2, 1, 2],
[0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 0, 1]
]
I = lambda: [[1 if i == j else 0 for j in xrange(6)] for i in xrange(6)]
def mul(M, N):
    global mod
    res = [[0] * 6 for i in xrange(6)]
    for i in xrange(6):
        for j in xrange(6):
            for k in xrange(6):
                res[i][j] += M[i][k] * N[k][j]
                res[i][j] %= mod
    return res
def power(M, k):
    if k > 1:
        res = power(M, k/2)
        res = mul(res, res)
        if k % 2:
            res = mul(res, M)
        return res
    elif k == 1:
        return M
    else:
        return I()
B = power(A, t)
V = [0] * 6
for i in xrange(6):
    for j in xrange(6):
        V[i] += B[i][j] * v[j]
        V[i] %= mod
print V[0] + 1,V[1] + 1


mod, sx, sy, dx, dy, t = map(int,raw_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))


import math
a,b= map(int,input().split())
n=a+b
ans,l=0,1
while l<=n:
    g= n//l
    if a<g or b<g:
        l= (n//g) +1
        continue
    r= n//g
    a_low = (a+g)//(g+1)
    a_high = a//g
    b_low=(b+g)//(g+1)
    b_high = b//g
    if (a_low <= a_high and b_low <= b_high):
        ans += max(0,min(r,a_high+b_high)- max(l,a_low +b_low)+1)

    l=r+1
print(ans)


a,b= map(int,input().split())
ans,l,n=0,1,a+b
while l<=n:
    g= n//l
    if a<g or b<g:
        l= (n//g) +1
        continue
    r= n//g
    al = (a+g)//(g+1)
    ah = a//g
    bl=(b+g)//(g+1)
    bh = b//g
    if (al <= ah and bl <= bh):
        ans += max(0,min(r,ah+bh)- max(l,al +bl)+1)
    l=r+1
print(ans)


import math

a, b = [int(x) for x in input().split()]
cnt = 0
ab = a + b
k = 2
while k <= ab:
    t = ab // k
    aPeriod = a // t
    bPeriod = b // t
    aLeft = (a + t) // (t + 1)
    bLeft = (b + t) // (t + 1)
    arem = a - t * aPeriod
    brem = b - t * bPeriod
    if aPeriod >= arem and bPeriod >= brem:
    	validK = aPeriod + bPeriod - aLeft - bLeft + 1
    	if (t + 1) * (aLeft + bLeft) == ab:
    		validK -= 1
    	if validK > 0:
    		cnt += validK
    k = ab // t + 1
print(cnt)


import math

a, b = [int(x) for x in input().split()]
cnt = 0
ab = a + b
k = 2
while k <= ab:
    t = ab // k
    aPeriod = a // t
    bPeriod = b // t
    aLeft = (a + t) // (t + 1)
    bLeft = (b + t) // (t + 1)
    arem = a - t * aPeriod
    brem = b - t * bPeriod
    if aPeriod >= arem and bPeriod >= brem:
    	validK = aPeriod + bPeriod - aLeft - bLeft + 1
    	if validK > 0:
    		cnt += validK
    k = ab // t + 1
print(cnt)


import fileinput

def calc(a, b):
    ans = 0
    l = a + b
    i = 1
    while i < l:
        P = l // i
        r = l // P
        if P <= a and P <= b:
            an = (a + P) // (P + 1)
            ax = a // P
            bn = (b + P) // (P + 1)
            bx = b // P
            if an <= ax and bn <= bx:
                ans += min(ax + bx, r) - max(an + bn, i) + 1
        i = r + 1
    return ans

if __name__ == '__main__':
    it = fileinput.input()
    a, b = [int(x) for x in next(it).split()]
    print(calc(a, b))


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

planet = []

for i in xrange(n):
    nome = raw_input()
    op = []
    for j in xrange(m):

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

        op.append([a, b, c])

    planet.append(op)

maximo = 0

for i in xrange(n):
    for j in xrange(n):
        if i != j:
            pft = []
            for k in xrange(m):
                luc = planet[j][k][1] - planet[i][k][0]
                pft.append([luc, planet[i][k][2]])

            pft.sort(reverse=True, key=lambda tup:tup[0])

            qtd = 0
            ganho = 0
            for r in xrange(len(pft)):
                if qtd + pft[r][1] <= l and pft[r][0] > 0:
                    ganho += pft[r][0]*pft[r][1]
                    qtd += pft[r][1]
                elif pft[r][0] > 0:
                    ganho += pft[r][0]*(l-qtd)
                    break

            if ganho > maximo:
                maximo = ganho

print maximo


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

planet = []

for i in xrange(n):
    nome = raw_input()
    op = []
    for j in xrange(m):

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

        op.append([a, b, c])

    planet.append(op)

maximo = 0

for i in xrange(n):
    for j in xrange(n):
        if i != j:
            pft = []
            for k in xrange(m):
                luc = (planet[j][k][1] - planet[i][k][0])*planet[i][k][2]
                pft.append([luc, planet[i][k][2]])

            pft.sort(reverse=True, key=lambda tup:tup[0])

            qtd = 0
            ganho = 0
            for r in xrange(len(pft)):
                if qtd + pft[r][1] < l and pft[r][0] > 0:
                    ganho += pft[r][0]
                    qtd += pft[r][1]
                elif pft[r][0] > 0:
                    ganho += (pft[r][0]/pft[r][1])*(l-qtd)
                    break
                else:
                    break

            if ganho > maximo:
                maximo = ganho

print maximo


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

planet = []

for i in xrange(n):
    nome = raw_input()
    op = []
    for j in xrange(m):

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

        op.append([a, b, c])

    planet.append(op)

maximo = 0

for i in xrange(n):
    for j in xrange(n):
        if i != j:
            pft = []
            for k in xrange(m):
                luc = planet[j][k][1] - planet[i][k][0]
                pft.append([luc, planet[i][k][2]])

            pft.sort(reverse=True, key=lambda tup:tup[0])

            qtd = 0
            ganho = 0
            for r in xrange(len(pft)):
                if qtd + pft[r][1] < l:
                    ganho += pft[r][0]*pft[r][1]
                    qtd += pft[r][1]
                else:
                    ganho += pft[r][0]*(l-qtd)
                    break

            if ganho > maximo:
                maximo = ganho

print maximo


n,m,capacity = [int(x) for x in raw_input().split()]

class Planet:
    def __init__(self):
        self.a = []
        self.b = []
        self.c = []
        self.n = ""
    def __repr__(self):
        return "%s: a:%r, b:%r, c:%r" % (self.n, self.a, self.b,self.c)

def calc_profit(p1, p2):
    #print "%s -> %s" % (p1.n, p2.n)
    profits = []
    for j in range(m):
        if p1.c[j] == 0:
            continue
        profit = p2.b[j] - p1.a[j]
        if profit > 0:
            profits.append((profit, p1.c[j]))
    profits.sort(reverse=True)
    load = 0
    total_profit = 0
    for p in profits:
        if load + p[1] > capacity:
            c = capacity - load
        else:
            c = p[1]
        total_profit += p[0]*c
        load += c
        if c != p[1]:
            break
    #print "profit: %d" % total_profit
    return total_profit

ps = []

for i in range(n):
    p = Planet()
    p.n = raw_input()
    for j in range(n):
        a,b,c = [int(x) for x in raw_input().split()]
        p.a.append(a)
        p.b.append(b)
        p.c.append(c)
    ps.append(p)

max_profit = -1

for n1 in range(n):
    for n2 in range(n):
        if n1 != n2:
            profit = calc_profit(ps[n1], ps[n2])
            max_profit = max(max_profit, profit)

print max_profit


a = list(map(int,input().split()))
def calc(a):
 return int((((a[1]-a[0])+(a[1]+a[0]))/2))
a.sort()
if a[1] % 2 == 0 and a[0] % 2 == 0:
 print(calc(a))
elif a[1] % 2 == 0 or a[0] % 2 == 0:
 print(a[2])
else:
 print(calc(a))


a, b, c = map(int, raw_input().split(' '))
l = [a, b, c]
l.sort()
[a, b, c] = l
if a % 2 == b % 2 == c % 2:
	print b
else:
	if a % 2 == b % 2:
		print b
	elif a % 2 == c % 2:
		print c
	else:
		print c


def pixel(input):
    red, green, blue = input.split()
    red = int(red)
    green = int(green)
    blue = int(blue)

    plist = [red,green,blue]
    plist.sort()

    lowestChet = is_chet(plist[0])
    midChet = is_chet(plist[1])

    if ((midChet + lowestChet) == 2) or ((midChet + lowestChet) == 0):
        return plist[1]
    else:
        return plist[2]

def is_chet(n):
    return 1 if n % 2 == 0 else 0

print(pixel(input()))


def cal(ar,cnt):
  if ar[0]==ar[1]:
   return cnt+ar[0]
  elif ar[0]==ar[2]:
   return cnt+ar[0]
  elif ar[1]==ar[2]:
   return cnt+ar[1]
  else:
   ar.sort()
   ar[2]-=1
   ar[1]-=1
   ar[0]+=1
   cnt+=1
   return cal(ar,cnt)

a = list(map(int,input().split()))
print(cal(a,0))


def pixel(input):
    red, green, blue = input.split()
    pixels = [int(red), int(green), int(blue)]

    red = 0
    green = 1
    blue = 2

    battles = 0

    f1 = None
    f2 = None
    w = None

    while True:
        if pixels[red] == pixels[green]:
            break
        if pixels[red] == pixels[blue]:
            break
        if pixels[green] == pixels[red]:
            break
        if pixels[green] == pixels[blue]:
            break
        if pixels[blue] == pixels[red]:
            break
        if pixels[blue] == pixels[green]:
            break

        lowest = get_min_key(pixels)
        if lowest == red:
            f1 = green
            f2 = blue
            w = red
        elif lowest == green:
            f1 = red
            f2 = blue
            w = green
        elif lowest == blue:
            f1 = red
            f2 = green
            w = blue

        pixels[f1] -= 1
        pixels[f2] -= 1
        pixels[w] += 1
        battles += 1

    minBattles = 0
    maxBattles = 0
    minPixels = pixels.copy()
    maxPixels = pixels.copy()

    lowest = get_min_key(pixels)

    if lowest == red:
        f1 = green
        f2 = blue
        w = red
    elif lowest == green:
        f1 = red
        f2 = blue
        w = green
    elif lowest == blue:
        f1 = red
        f2 = green
        w = blue

    while True:
        is_mir = len([x for x in maxPixels if x <= 0]) > 1
        if is_mir:
            break

        if maxPixels[f1] == 0:
            tmp = w
            w = f1
            f1 = tmp

        if maxPixels[f2] == 0:
            tmp = w
            w = f2
            f2 = tmp

        maxPixels[f1] -= 1
        maxPixels[f2] -= 1
        maxPixels[w] += 1

        minBattles += 1

    highest = get_max_key(pixels)
    if highest == red:
        f1 = green
        f2 = blue
        w = red
    elif highest == green:
        f1 = red
        f2 = blue
        w = green
    elif highest == blue:
        f1 = red
        f2 = green
        w = blue

    while True:
        is_mir = len([x for x in minPixels if x <= 0]) > 1
        if is_mir:
            break

        if minPixels[f1] == 0:
            tmp = w
            w = f1
            f1 = tmp

        if minPixels[f2] == 0:
            tmp = w
            w = f2
            f2 = tmp

        minPixels[f1] -= 1
        minPixels[f2] -= 1
        minPixels[w] += 1

        maxBattles += 1

    return battles + minBattles if battles + minBattles < battles + maxBattles else battles + maxBattles

def get_max_key(pixels):
    maxKey = 0
    max = pixels[maxKey]
    for key, pixel in enumerate(pixels):
        if pixel > max:
            max = pixel
            maxKey = key

    return maxKey

def get_min_key(pixels):
    minKey = 0
    min = pixels[minKey]
    for key, pixel in enumerate(pixels):
        if pixel < min:
            min = pixel
            minKey = key

    return minKey

print(pixel(input()))


# Read input
n,m,k = map(int,raw_input().split())
a     = [map(int,raw_input().split())+[i+1] for i in range(m)]

def reduce (e,x,y,d,cst):
    return [cst-((cst-max(e[0],x))/(k**d))*k**d,
            cst+((min(e[1],y)-cst)/(k**d))*k**d]

# Recursive approach
def next (s1,s2,cst,d,mi,ma,l,r):
    ll = [reduce(e,mi,ma,d,cst)+[e[2],e[3]] for e in l if ma>=e[0] and mi<=e[1]]
    if len(ll)<r-1 or len(ll)==0: return False
    if r==1:
        return max ([[s1+s2*((x[1]-cst)/(k**d)),(x[1]-cst)/(k**d)],[[x[3],1]]]
                    for x in ll)

    # Case times k
    res = [[next (s1+k*cst,s2+k**(d+1),k*cst,d+1,k*x[0],k*x[1],
                  [e for e in l if e[2]>x[2]], r-1),
            [x[3],1]] for x in ll if x[1]>=x[0]]

    # Case adds k
    res += [[next (s1+cst+k,s2+k**d,cst+k,d,x[0]+k,x[1]+k,
                   [e for e in l if e[2]>x[2]], r-1),
             [x[3],0]] for x in ll if x[1]>=x[0]]

    ll = [e for e in res if e[0]!=False]
    if len(ll)==0: return False
    M = max (ll)
    return [M[0][0], [M[1]]+M[0][1]]

l = next (0,1,0,0,0,10**16,a,n)
if l==False:
    print "NO"
else:
    print "YES"
    c = l[0][1]
    for e in l[1]:
        print e[0], c
        if e[1]: c*=k
        else:    c+=k


class Subject:
    def __init__(self, id, low, high, complexity):
        self.id = id
        self.low = low
        self.high = high
        self.complexity = complexity
        self.day_links = [ {} for i in range(high - low + 1) ]

    def add_link(self, link):
        days = link.days
        links = self.day_links[link.weight - self.low]
        if days not in links or links[days].total < link.total:
            links[days] = link

class Link:
    def __init__(self, subject, weight, total, days, previous):
        self.subject = subject
        self.weight = weight
        self.total = total
        self.days = days
        self.previous = previous

class Group:
    def __init__(self, complexity):
        self.complexity = complexity
        self.subjects = []

need_days, num_subjects, more = map(int, input().split())
groups = {}
for i in range(num_subjects):
    subject = Subject(i + 1, *list(map(int, input().split())))
    if subject.complexity not in groups:
        groups[subject.complexity] = Group(subject.complexity)
    groups[subject.complexity].subjects.append(subject)
groups = sorted(groups.values(), key = lambda group: group.complexity)
num_groups = len(groups)

best_link = None

for pos, group in enumerate(groups):
    if num_groups - pos >= need_days:
        for subject in group.subjects:
            for weight in range(subject.low, subject.high + 1):
                subject.add_link(Link(subject, weight, weight, 1, None))
    for subject in group.subjects:
        for i, links in enumerate(subject.day_links):
            weight = subject.low + i
            for days, link in links.items():
                if days == need_days:
                    if not best_link or best_link.total < link.total:
                        best_link = link
                    continue
                for next_weight in [ weight + more, weight * more ]:
                    max_pos = num_groups + days - need_days
                    for next_pos in range(pos + 1, max_pos + 1):
                        for next_subject in groups[next_pos].subjects:
                            if next_weight < next_subject.low:
                                continue
                            if next_weight > next_subject.high:
                                continue
                            next_subject.add_link(Link(
                                next_subject, next_weight,
                                next_weight + link.total, days + 1, link))

if best_link:
    print('YES')
    schedule = need_days * [ None ]
    link = best_link
    while link:
        subject = link.subject
        subject.weight = link.weight
        schedule[link.days - 1] = subject
        link = link.previous
    for subject in schedule:
        print(subject.id, subject.weight)
    import sys
    sys.exit()
else:
    print('NO')


class Subject:
    def __init__(self, id, low, high, complexity):
        self.id = id
        self.low = low
        self.high = high
        self.complexity = complexity
        self.day_links = [ {} for i in range(high - low + 1) ]

    def add_link(self, link):
        days = link.days
        links = self.day_links[link.weight - self.low]
        if days not in links or links[days].total < link.total:
            links[days] = link

    def __str__(self):
        return '[%d [%d, %d] %d]' % (self.id,
                self.low, self.high, self.complexity)

class Link:
    def __init__(self, subject, weight, total, days, previous):
        self.subject = subject
        self.weight = weight
        self.total = total
        self.days = days
        self.previous = previous

class Group:
    def __init__(self, complexity):
        self.complexity = complexity
        self.subjects = []

need_days, num_subjects, more = map(int, input().split())
groups = {}
for i in range(num_subjects):
    subject = Subject(i + 1, *list(map(int, input().split())))
    if subject.complexity not in groups:
        groups[subject.complexity] = Group(subject.complexity)
    groups[subject.complexity].subjects.append(subject)
groups = sorted(groups.values(), key = lambda group: group.complexity)
num_groups = len(groups)

def win(link):
    print('YES')
    schedule = need_days * [ None ]
    while link:
        subject = link.subject
        subject.weight = link.weight
        schedule[link.days - 1] = subject
        link = link.previous
    for subject in schedule:
        print(subject.id, subject.weight)
    import sys
    sys.exit()

best_link = None

for pos, group in enumerate(groups):
    #print(pos, '', '  '.join(map(str, group.subjects)))
    if num_groups - pos >= need_days:
        for subject in group.subjects:
            for weight in range(subject.low, subject.high + 1):
                subject.add_link(Link(subject, weight, weight, 1, None))
    for subject in group.subjects:
        for i, links in enumerate(subject.day_links):
            weight = subject.low + i
            for days, link in links.items():
                if link.weight != weight:
                    print('expected weight %d, link has weight %d' % (
                        weight, link.weight))
                    import sys; sys.exit()
                if days == need_days:
                    if not best_link or best_link.total < link.total:
                        best_link = link
                    continue
                for next_weight in [ weight + more, weight * more ]:
                    max_pos = num_groups + days - need_days
                    for next_pos in range(pos + 1, max_pos + 1):
                        for next_subject in groups[next_pos].subjects:
                            if next_weight < next_subject.low:
                                continue
                            if next_weight > next_subject.high:
                                continue
                            next_subject.add_link(Link(
                                next_subject, next_weight,
                                next_weight + link.total, days + 1, link))
                            #print('%d -> %d (%d)' % (link.weight,
                            #    next_weight, days + 1))

if best_link:
    win(best_link)
else:
    print('NO')

# Made By Mostafa_Khaled


# Read input
n,m,k = map(int,raw_input().split())
a     = [map(int,raw_input().split())+[i+1] for i in range(m)]

# Format datastructure
a.sort(key=lambda x:x[2])
M     = a[-1][2]
P     = dict()
ind   = dict()

# Select the first valid interval after p
def valid (val,p,i):
    return [q for q in range (p+1,m-i+1) if a[q][0]<=val and val<=a[q][1]
                                        and a[p][2]<a[q][2] and a[q][2]<=M-i+1]

# Recursive function with memoization
def path (i,p,v):
    if P.has_key((i,p,v)): return P[i,p,v]
    if i==1:               return (v, None, None)

    val   = v+k
    ladd  = valid (val,p,i-1)
    madd  = path (i-1,ladd[0],val) if len(ladd)>0 else None

    val   = v*k
    lprod = valid (val,p,i-1)
    mprod = path (i-1,lprod[0],val) if len(lprod)>0 else None

    if   madd>mprod: P[i,p,v] = (madd[0] +v, ladd[0], v+k)
    elif mprod>madd: P[i,p,v] = (mprod[0]+v, lprod[0], v*k)
    else:            P[i,p,v] = None
    return P[i,p,v]

#
vals = set (sum ((range(a[i][0],a[i][1]+1) for i in range (m)), []))
for p in range(m):
    for v in range(a[p][0],a[p][1]+1):
        ind[v] = p if not ind.has_key(v) or p<ind[v] else ind[v]
seed = max ((path(n,ind[v],v),ind[v],v) for v in vals)

if seed[0]==None:
    print "NO"
else:
    print "YES"
    (s,p,v) = seed
    print a[p][3],v
    for i in range(n,1,-1):
        (s,p,v) = path(i,p,v)
        print a[p][3], v


class Subject:
    def __init__(self, id, low, high, complexity):
        self.id = id
        self.low = low
        self.high = high
        self.complexity = complexity
        self.links = (high - low + 1) * [ None ]

    def add_link(self, weight, new_link):
        link = self.links[weight - self.low]
        if link == None or link.days < new_link.days:
            self.links[weight - self.low] = new_link

    def __str__(self):
        return '[%d [%d, %d] %d]' % (self.id,
                self.low, self.high, self.complexity)

class Link:
    def __init__(self, subject, weight, days, previous):
        self.subject = subject
        self.weight = weight
        self.days = days
        self.previous = previous

class Group:
    def __init__(self, complexity):
        self.complexity = complexity
        self.subjects = []

need_days, num_subjects, more = map(int, input().split())
groups = {}
for i in range(num_subjects):
    subject = Subject(i + 1, *list(map(int, input().split())))
    if subject.complexity not in groups:
        groups[subject.complexity] = Group(subject.complexity)
    groups[subject.complexity].subjects.append(subject)
groups = sorted(groups.values(), key = lambda group: group.complexity)
num_groups = len(groups)

def win(link):
    print('YES')
    schedule = need_days * [ None ]
    while link:
        subject = link.subject
        subject.weight = link.weight
        schedule[link.days - 1] = subject
        link = link.previous
    for subject in schedule:
        print(subject.id, subject.weight)
    import sys
    sys.exit()

for pos, group in enumerate(groups):
    #print(pos, '', '  '.join(map(str, group.subjects)))
    if num_groups - pos >= need_days:
        for subject in group.subjects:
            for weight in range(subject.low, subject.high + 1):
                subject.add_link(weight, Link(subject, weight, 1, None))
                #print(pos, weight, 1)
    for subject in group.subjects:
        for i, link in enumerate(subject.links):
            if link == None:
                continue
            if link.days == need_days:
                win(link)
            weight = subject.low + i
            for next_weight in [ weight + more, weight * more ]:
                max_pos = num_groups + link.days - need_days
                for next_pos in range(pos + 1, max_pos + 1):
                    for next_subject in groups[next_pos].subjects:
                        if next_weight < next_subject.low:
                            continue
                        if next_weight > next_subject.high:
                            continue
                        next_subject.add_link(next_weight, Link(
                            next_subject, next_weight, link.days + 1, link))
                        #print(next_pos, next_weight, link.days + 1)

print('NO')


read = lambda: map(int, input().split())
n = int(input())
a = list(read())
b = [0] * n
j = 0
for i in a:
    if i:
        b[j] = i
        j += 1
cnt = sum(i != 0 for i in b)
for i in range(n):
    if b[i] == 0: break
    if b[i] == a[i]:
        cnt -= 1
print(cnt)


input()
memory = list(map(int, input().split()))

proc_data = {p: (-1, -1) for p in memory}

for i, c in enumerate(memory):
    d1, d2 = proc_data[c]
    if d1 == -1: d1 = i
    d2 = i
    proc_data[c] = (d1, d2)

try: del proc_data[0]
except KeyError:
    print("0")
    exit()

data = list(proc_data.values())
data.sort()

ans = 0

first_free = 0

for a, b in data:
    c = a - first_free
    ans += min(c, b-a+1)
    b -= c
    first_free = b + 1

print(ans)


n = int(input())
k = [[0, 0, -1]]
cnt = 0
for i in map(int, input().split()):
    if i:
        if k[-1][0] == i:
            k[-1][1] += 1
        else:
            k.append([i, 1, cnt])
    cnt += 1
cnt = 0
ans = 0
for i in k[1:]:
    ans += min(i[1], i[2] - cnt)
    cnt += i[1]
print(ans)


n = int(input())
l = list(map(int, input().split()))
ans = 0
count = 0
d = dict()
s = set()
s1 = set()
for i in l:
    if i in s:
        d[i] += 1
    else:
        d[i] = 1
        s.add(i)
for i in range(n):
    if l[i] == 0:
        count += 1
    else:
        if l[i] not in s1:
            ans += min(d[l[i]], count)
            s1.add(l[i])
print(ans)


p = 1000000007

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

d = [1] * 300001
td = [0] * 300001
L = b[0]
for i in range(1, n):
	if a[i - 1] != 1:
		t = m % a[i - 1]
		if L < t:
			print(0)
			exit(0)
		m //= a[i - 1]
		for j in range((L - t) // a[i - 1] + 1):
			d[j] = d[j * a[i - 1] + t]
		L = (L - t) // a[i - 1]
	k = 0
	for j in range(L + b[i] + 1):
		if j <= L:
			k = (k + d[j]) % p
		td[j] = k
		if j >= b[i]:
			k = (k - d[j - b[i]] + p) % p
	L += b[i]
	for j in range(L + 1):
		d[j] = td[j]
print(d[m] if m <= L else 0)


import array

p = 1000000007

n = int(input())
a = array.array('i', map(int, input().split()))
b = array.array('i', map(int, input().split()))
m = int(input())

d = array.array('i', (1 for _ in range(300001)))
td = array.array('i', (0 for _ in range(300001)))
L = b[0]
for i in range(1, n):
	if a[i - 1] != 1:
		t = m % a[i - 1]
		if L < t:
			print(0)
			exit(0)
		m //= a[i - 1]
		for j in range((L - t) // a[i - 1] + 1):
			d[j] = d[t]
			t += a[i - 1]
		L = j
	k = 0
	for j in range(L + b[i] + 1):
		if j <= L:
			k += d[j]
		k %= p
		td[j] = k
		if j >= b[i]:
			k -= d[j - b[i]]
	L += b[i]
	d, td = td, d
print(d[m] if m <= L else 0)


import array

p = 1000000007

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

d = array.array('i', (1 for _ in range(300001)))
td = array.array('i', (0 for _ in range(300001)))
L = b[0]
for i in range(1, n):
	if a[i - 1] != 1:
		t = m % a[i - 1]
		if L < t:
			print(0)
			exit(0)
		m //= a[i - 1]
		for j in range((L - t) // a[i - 1] + 1):
			d[j] = d[t]
			t += a[i - 1]
		L = j
	k = 0
	for j in range(L + b[i] + 1):
		if j <= L:
			k += d[j]
		k %= p
		td[j] = k
		if j >= b[i]:
			k -= d[j - b[i]]
	L += b[i]
	d, td = td, d
print(d[m] if m <= L else 0)


p = 1000000007

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

d = [1] * 300001
td = [0] * 300001
L = b[0]
for i in range(1, n):
	if a[i - 1] != 1:
		t = m % a[i - 1]
		if L < t:
			print(0)
			exit(0)
		m //= a[i - 1]
		for j in range((L - t) // a[i - 1] + 1):
			d[j] = d[t]
			t += a[i - 1]
		L = j
	k = 0
	for j in range(L + b[i] + 1):
		if j <= L:
			k += d[j]
		k %= p
		td[j] = k
		if j >= b[i]:
			k -= d[j - b[i]]
	L += b[i]
	for j in range(L + 1):
		d[j] = td[j]
print(d[m] if m <= L else 0)


p = 1000000007

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

d = [1 for _ in range(b[0] + 1)]
for i in range(1, n):
	if a[i - 1] != 1:
		t = m % a[i - 1]
		m //= a[i - 1]
		d = [d[j * a[i - 1] + t] for j in range((len(d) - t - 1) // a[i - 1] + 1)]
	td = [0 for _ in range(len(d) + b[i])]
	k = 0
	for j in range(len(d) + b[i]):
		if j < len(d):
			k = (k + d[j]) % p
		if j > b[i]:
			k = (k - d[j - b[i] - 1] + p) % p
		td[j] = k
	d = td
print(d[m] if m < len(d) else 0)


def powmod(a,b,m):
 a%=m
 r=1
 while b:
  if b&1:r=r*a%m
  a=a*a%m
  b>>=1
 return r

def f(n):
 r=[]
 if (n&1)==0:
  e=0
  while (n&1)==0:n>>=1;e+=1
  yield (2,e)
 p=3
 while n>1:
  if p*p>n:p=n
  if n%p:
   p+=2
   continue
  e=1;n//=p
  while n%p==0:n//=p;e+=1
  yield (p,e)
  p+=2
 return r
m,x=map(int,input().split())
p=2
r=[(1,1)]
for p,e in f(m):
 assert e>=1
 ord=p-1
 assert powmod(x,ord,p)==1
 for pi,ei in f(p-1):
  while ord % pi == 0 and powmod(x,ord//pi,p)==1: ord//=pi
 ords=[(1,1),(ord,p-1)]
 q=p
 for v in range(2,e+1):
  q*=p
  if powmod(x,ord,q)!=1:ord*=p
  assert powmod(x,ord,q)==1
  ords.append((ord,q//p*(p-1)))
 r=[(a//gcd(a,c)*c,b*d) for a,b in r for c,d in ords]
print(sum(y//x for x,y in r))


def p(a,b,m):
 a%=m
 r=1
 while b:
  if b&1:r=r*a%m
  a=a*a%m
  b>>=1
 return r

def f(n):
 r=[]
 if (n&1)==0:
  e=0
  while (n&1)==0:n>>=1;e+=1
  yield (2,e)
 p=3
 while n>1:
  if p*p>n:p=n
  if n%p:
   p+=2
   continue
  e=1;n//=p
  while n%p==0:n//=p;e+=1
  yield (p,e)
  p+=2
 return r
m,x=map(int,input().split())
p=2
r=[(1,1)]
for p,e in f(m):
 assert e>=1
 ord=p-1
 assert p(x,ord,p)==1
 for pi,ei in f(p-1):
  while ord % pi == 0 and p(x,ord//pi,p)==1: ord//=pi
 ords=[(1,1),(ord,p-1)]
 q=p
 for v in range(2,e+1):
  q*=p
  if p(x,ord,q)!=1:ord*=p
  assert p(x,ord,q)==1
  ords.append((ord,q//p*(p-1)))
 r=[(a//gcd(a,c)*c,b*d) for a,b in r for c,d in ords]
print(sum(y//x for x,y in r))


from math import gcd
def powmod(a,b,m):
 a%=m
 r=1
 while b:
  if b&1:r=r*a%m
  a=a*a%m
  b>>=1
 return r

def f(n):
 r=[]
 if (n&1)==0:
  e=0
  while (n&1)==0:n>>=1;e+=1
  yield (2,e)
 p=3
 while n>1:
  if p*p>n:p=n
  if n%p:
   p+=2
   continue
  e=1;n//=p
  while n%p==0:n//=p;e+=1
  yield (p,e)
  p+=2
 return r
m,x=map(int,input().split())
p=2
r=[(1,1)]
for p,e in f(m):
 assert e>=1
 ord=p-1
 assert powmod(x,ord,p)==1
 for pi,ei in f(p-1):
  while ord % pi == 0 and powmod(x,ord//pi,p)==1: ord//=pi
 ords=[(1,1),(ord,p-1)]
 q=p
 for v in range(2,e+1):
  q*=p
  if powmod(x,ord,q)!=1:ord*=p
  assert powmod(x,ord,q)==1
  ords.append((ord,q//p*(p-1)))
 r=[(a//gcd(a,c)*c,b*d) for a,b in r for c,d in ords]
print(sum(y//x for x,y in r))


import sys

def main():
  n, k = map(int, input().split())
  b = list(map(int, input().split()))
  bs = [[], [], []]
  s = input()
  for i in range(n):
    ind = -1
    if s[i] == 'O':
      ind = 0
    elif s[i] == 'R':
      ind = 1
    else:
      ind = 2
    bs[ind].append(b[i])
  bs[0].sort()
  bs[1].sort()
  bs[2].sort()
  if len(bs[0]) == 0 or len(bs[1]) + len(bs[2]) == 0 or len(bs[0]) + max(len(bs[1]), len(bs[2])) < k:
    print(-1)
    sys.exit(0)

  sufs = [0]
  for i in range(len(bs[0]) - 1, -1, -1):
    sufs.append(sufs[-1] + bs[0][i])

  ans = -1
  for i in (1, 2):
    x, y = bs[0], bs[i]
    if len(x) + len(y) < k:
      continue
    cursum = 0
    for cny in range(1, len(y) + 1):
      if cny > 0:
        cursum += y[-cny]
      cnx = k - cny
      if cnx > 0 and cnx <= len(x):
        ans = max(ans, cursum + sufs[cnx])

  print(ans)

if __name__ == '__main__':
  main()


n,k=map(int,raw_input().split())
v=map(int,raw_input().split())
s=raw_input()
r=[]
w=[]
o=[]

for i in range(0,len(s)):
	if s[i]=='R':
		r.append(v[i])
	if s[i]=='W':
		w.append(v[i])
	if s[i]=='O':
		o.append(v[i])

r.sort(),w.sort(),o.sort()
r.append(0),w.append(0),o.append(0)
r.reverse(),w.reverse(),o.reverse()

for i in range(1,len(r)):
	r[i]+=r[i-1]

for i in range(1,len(w)):
	w[i]+=w[i-1]

for i in range(1,len(o)):
	o[i]+=o[i-1]

ans=-1

for i in range(1,len(o)):
	if i>=k :
		break
	if k-i<len(r):
		ans=max(ans,o[i]+r[k-i])
	if k-i<len(w):
		ans=max(ans,o[i]+w[k-i])
print ans


def calca(_A, _B, k):
    A = _A.copy()
    B = _B.copy()
    n = len(A)
    m = len(B)
    ans = -int(1e9)
    for i in range(1, n):
        A[i] += A[i-1]
    for i in range(1, m):
        B[i] += B[i-1]
    for i in range(1, n):
        if k-i < m and k-i > 0:
            ans = max(ans, A[i] + B[k-i])
    return ans

def testCase():
    n, k = [int(x) for x in input().split()]
    nums = [int(x) for x in input().split()]
    ros = input()
    n = len(nums)
    A = []
    B = []
    C = []
    for i in range(n):
        if ros[i] == 'R':
            A.append(nums[i])
        elif ros[i] == 'O':
            B.append(nums[i])
        else:
            C.append(nums[i])
    A.sort()
    A.append(0)
    A.reverse()
    B.sort()
    B.append(0)
    B.reverse()
    C.sort()
    C.append(0)
    C.reverse()
    ans = max(calca(A, B, k), calca(B, C, k))
    print(-1 if ans == -int(1e9) else ans)

testCase()


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

s = input()

# print(n,k)
# print(b)
# print(s)

INF = 1000*1000*1000+123
R = [];
W = [];
O = [];

for i in range(n):
    if s[i] == 'R':
        R.append(b[i])
    elif s[i] == 'W':
        W.append(b[i])
    else:
        O.append(b[i])

R.sort()
R.reverse()

W.sort()
W.reverse()

O.sort()
O.reverse()

# print('--------')

# print("-",)

if k == 1:
    print(-1)
    exit(0)

def solve(A,B):
    # print("\nsolve");
    # print(A);
    # print(B);
    nA = len(A);
    nB = len(B);

    pA = [0 for i in range(nA)]
    pB = [0 for i in range(nB)]

    pA[0] = A[0]
    pB[0] = B[0]

    for i in range(1,nA):
        pA[i] = pA[i-1] + A[i];
    for i in range(1,nB):
        pB[i] = pB[i-1] + B[i];

    # print("pA",pA)
    # print("pB",pB)

    res = -1

    for i in range(1,min(nA+1,k)):

        costA = pA[i-1]
        bNeed = k-i
        if bNeed <= 0 or bNeed > nB: continue
        costB = pB[bNeed-1]
        res = max(res,costA+costB)
    return res

res = -1
if len(R) > 0 and len(O)> 0:
    res = max(res,solve(R,O))

if len(W) > 0 and len(O)> 0:
    res = max(res,solve(W,O))

print(res)

#
# a = [
#    6,5,37,10,22,9,2,16,3,3,11,9,5,14,11,3,1,4,6,2,7,
#     3,7,5,4,8,2,7,13,16,15,9,4,4,2,3,9,5,11,3,7,5,9,
#     3,8,9,4,10,3,2,7,6,9,3,5,4,6,4,14,3,12,6,8,12,7
# ]
#
# print(a)
#
# cnt = [0] * 1000
#
# for e in a:
#     cnt[e] += 1
#
# a = set(a)
# a = sorted(a)
#
#
# for e in a:
#     print("%d %d"%(e,cnt[e]));


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)


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


import sys
range = xrange
input = raw_input

MOD = 998244353

n, m, k = [int(x) for x in input().split()]

if m == 1:
    print pow(n, k, MOD)
    sys.exit()

p = pow(m, MOD - 2, MOD)

vec = [0]*(k + 1)
vec[0] = 1
for i in range(k):
    for m in reversed(range(i + 1)):
        vec[m + 1] = int( (vec[m + 1] + (n - m) * vec[m]) % MOD )
        vec[m] = int(vec[m] * m % MOD)

x = p * pow(1 - p, MOD - 2, MOD)

summa = 0
for m in range(k + 1):
    summa += vec[m] * pow(1 + x, n - m, MOD) * pow(x, m, MOD) % MOD

summa *= pow(1 - p, n, MOD)

print summa % MOD


__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

#         visited_points[(n, i)] = 0
# if xs % 2 == 0:
#     for i in range (2, n + 1, 2):
#         visited_points[(i,1)] = 0
#         visited_points[(i,m)] = 0
# else:
#     for i in range (1, n + 1, 2):
#         visited_points[(i,1)] = 0
#         visited_points[(i,m)] = 0
#
# if ys % 2 == 0:
#     for i in range (2, m + 1, 2):
#         visited_points[(1, i)] = 0
#         visited_points[(n, i)] = 0
# else:
#     for i in range (1, m + 1, 2):
#         visited_points[(1, i)] = 0


__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


s = raw_input()
n = len(s)
pb = -1
for i in xrange(n):
	if s[i] == 'B':
		pb = i

if pb != -1:
	s = s[pb:] + s[:pb]

s = s[-1] + s + s[0]

res = 1

dp = []

for i in xrange(n + 2):
	dp.append([[[0, 0], [0, 0]], [[0, 0], [0, 0]]])

for i in xrange(2, n + 1):
	for first in xrange(2):
		for prev in xrange(2):
			for last in xrange(2):
				for cur in xrange(2):
					if s[i - 1:i + 1] != 'BA' and cur == 1:
						continue
					if i == 2:
						if first != cur or prev != 0 or last != 0:
							continue
						dp[i][first][last][cur] = 1
					elif i > 2:
						if s[i - 2:i] == 'AB' and prev == 0 and cur == 0:
							continue
						if i == n and s[n] + s[1] == 'AB' and cur == 0 and first == 0:
							continue
						if i == n and s[n - 1:n + 1] == 'AB' and cur == 0 and last == 0:
							continue
						dp[i][first][last][cur] += dp[i - 1][first][prev][last]

res = 0
for i in xrange(2):
	for j in xrange(2):
		for k in xrange(2):
			res += dp[n][i][j][k]

print res


n=int(input())
s=[c=='1' for c in input()]
m=len(s)
z=[[0,0]]
for c in s:
 ind = z[-1][c]
 z[-1][c] = len(z)
 z.append(z[ind][:])
assert(len(z) == m+1)
z[m][0] = z[m][1] = m # make it sticky

# how many things match directly
dp = [0 for _ in range(m+1)]
dp[0] = 1
for i in range(n):
 ndp = [0 for _ in range(m+1)]
 for i in range(m+1):
  ndp[z[i][0]] += dp[i]
  ndp[z[i][1]] += dp[i]
 dp = ndp
res = dp[m]

for k in range(1, m):
 s0 = 0
 for c in s[-k:]:
  s0 = z[s0][c]
 dp = [0 for _ in range(m+1)]
 dp[s0] = 1
 for i in range(n - k):
  ndp = [0 for _ in range(m+1)]
  for i in range(m+1):
   ndp[z[i][0]] += dp[i]
   ndp[z[i][1]] += dp[i]
  dp = ndp
 for s1 in range(m): # skip m
  v = dp[s1]
  for c in s[-k:]:
   if s1 == m: v = 0
   s1 = z[s1][c]
  if s1 == m: res += v
print(res)


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# 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")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans

class smt:
    def __init__(self,l,r,arr):
        self.l=l
        self.r=r
        self.value=(1<<31)-1 if l<r else arr[l]
        mid=(l+r)//2
        if(l<r):
            self.left=smt(l,mid,arr)
            self.right=smt(mid+1,r,arr)
            self.value&=self.left.value&self.right.value
        #print(l,r,self.value)
    def setvalue(self,x,val):
        if(self.l==self.r):
            self.value=val
            return
        mid=(self.l+self.r)//2
        if(x<=mid):
            self.left.setvalue(x,val)
        else:
            self.right.setvalue(x,val)
        self.value=self.left.value&self.right.value
    def ask(self,l,r):
        if(l<=self.l and r>=self.r):
            return self.value
        val=(1<<31)-1
        mid=(self.l+self.r)//2
        if(l<=mid):
            val&=self.left.ask(l,r)
        if(r>mid):
            val&=self.right.ask(l,r)
        return val

class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [(ch,len(list(g))) for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

t=1
for i in range(t):
    mod=998244353
    n,k=RL()
    h=RLL()
    res=GP(h)
    c=0
    for ch,cnt in res:
        c+=cnt-1
    n=len(res)
    if res[-1][0]==res[0][0]:
        c+=1
        n-=1
    ans=pow(k,c,mod)
    tmp=pow(k,n,mod)
    fact(n,mod)
    ifact(n,mod)
    p=[1]
    for i in range(n):
        p.append(p[-1]*(k-2)%mod)
    for x in range(n//2+1):
        tmp=(tmp-p[n-2*x]*fact(n,mod)%mod*ifa[x]%mod*ifa[x]%mod*ifa[n-2*x]%mod)%mod
    ans=ans*tmp%mod*pow(2,mod-2,mod)%mod
    print(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()


from bisect import *
from collections import *
from math import gcd,ceil,sqrt,floor,inf
from heapq import *
from itertools import *
from operator import add,mul,sub,xor,truediv,floordiv
from functools import *

#------------------------------------------------------------------------
import os
import sys
from io import BytesIO, IOBase
# 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")

#------------------------------------------------------------------------
def RL(): return map(int, sys.stdin.readline().rstrip().split())
def RLL(): return list(map(int, sys.stdin.readline().rstrip().split()))
def N(): return int(input())
#------------------------------------------------------------------------

farr=[1]
ifa=[]

def fact(x,mod=0):
    if mod:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr)%mod)
    else:
        while x>=len(farr):
            farr.append(farr[-1]*len(farr))
    return farr[x]

def ifact(x,mod):
    global ifa
    ifa.append(pow(farr[-1],mod-2,mod))
    for i in range(x,0,-1):
        ifa.append(ifa[-1]*i%mod)
    ifa=ifa[::-1]

def per(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return fact(i)//fact(i-j)
    return farr[i]*ifa[i-j]%mod

def com(i,j,mod=0):
    if i<j: return 0
    if not mod:
        return per(i,j)//fact(j)
    return per(i,j,mod)*ifa[j]%mod

def catalan(n):
    return com(2*n,n)//(n+1)

def linc(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t>f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rinc(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t<f(mid):
            r=mid-1
        else:
            l=mid
    return l

def ldec(f,t,l,r):
    while l<r:
        mid=(l+r)//2
        if t<f(mid):
            l=mid+1
        else:
            r=mid
    return l

def rdec(f,t,l,r):
    while l<r:
        mid=(l+r+1)//2
        if t>f(mid):
            r=mid-1
        else:
            l=mid
    return l

def isprime(n):
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True

def binfun(x):
    c=0
    for w in arr:
        c+=ceil(w/x)
    return c

def lowbit(n):
    return n&-n

def inverse(a,m):
    a%=m
    if a<=1: return a
    return ((1-inverse(m,a)*m)//a)%m

class BIT:
    def __init__(self,arr):
        self.arr=arr
        self.n=len(arr)-1

    def update(self,x,v):
        while x<=self.n:
            self.arr[x]+=v
            x+=x&-x

    def query(self,x):
        ans=0
        while x:
            ans+=self.arr[x]
            x&=x-1
        return ans

class smt:
    def __init__(self,l,r,arr):
        self.l=l
        self.r=r
        self.value=(1<<31)-1 if l<r else arr[l]
        mid=(l+r)//2
        if(l<r):
            self.left=smt(l,mid,arr)
            self.right=smt(mid+1,r,arr)
            self.value&=self.left.value&self.right.value
        #print(l,r,self.value)
    def setvalue(self,x,val):
        if(self.l==self.r):
            self.value=val
            return
        mid=(self.l+self.r)//2
        if(x<=mid):
            self.left.setvalue(x,val)
        else:
            self.right.setvalue(x,val)
        self.value=self.left.value&self.right.value
    def ask(self,l,r):
        if(l<=self.l and r>=self.r):
            return self.value
        val=(1<<31)-1
        mid=(self.l+self.r)//2
        if(l<=mid):
            val&=self.left.ask(l,r)
        if(r>mid):
            val&=self.right.ask(l,r)
        return val

class DSU:#容量+路径压缩
    def __init__(self,n):
        self.c=[-1]*n

    def same(self,x,y):
        return self.find(x)==self.find(y)

    def find(self,x):
        if self.c[x]<0:
            return x
        self.c[x]=self.find(self.c[x])
        return self.c[x]

    def union(self,u,v):
        u,v=self.find(u),self.find(v)
        if u==v:
            return False
        if self.c[u]<self.c[v]:
            u,v=v,u
        self.c[u]+=self.c[v]
        self.c[v]=u
        return True

    def size(self,x): return -self.c[self.find(x)]

class UFS:#秩+路径
    def __init__(self,n):
        self.parent=[i for i in range(n)]
        self.ranks=[0]*n

    def find(self,x):
        if x!=self.parent[x]:
            self.parent[x]=self.find(self.parent[x])
        return self.parent[x]

    def union(self,u,v):
        pu,pv=self.find(u),self.find(v)
        if pu==pv:
            return False
        if self.ranks[pu]>=self.ranks[pv]:
            self.parent[pv]=pu
            if self.ranks[pv]==self.ranks[pu]:
                self.ranks[pu]+=1
        else:
            self.parent[pu]=pv

def Prime(n):
    c=0
    prime=[]
    flag=[0]*(n+1)
    for i in range(2,n+1):
        if not flag[i]:
            prime.append(i)
            c+=1
        for j in range(c):
            if i*prime[j]>n: break
            flag[i*prime[j]]=prime[j]
            if i%prime[j]==0: break
    return prime

def dij(s,graph):
    d={}
    d[s]=0
    heap=[(0,s)]
    seen=set()
    while heap:
        dis,u=heappop(heap)
        if u in seen:
            continue
        for v in graph[u]:
            if v not in d or d[v]>d[u]+graph[u][v]:
                d[v]=d[u]+graph[u][v]
                heappush(heap,(d[v],v))
    return d

def GP(it): return [(ch,len(list(g))) for ch,g in groupby(it)]

class DLN:
    def __init__(self,val):
        self.val=val
        self.pre=None
        self.next=None

t=1
for i in range(t):
    mod=998244353
    n,k=RL()
    h=RLL()
    res=GP(h)
    c=0
    for ch,cnt in res:
        c+=cnt-1
    n=len(res)
    if n>1 and res[-1][0]==res[0][0]:
        c+=1
        n-=1
    ans=pow(k,c,mod)
    tmp=pow(k,n,mod)
    fact(n,mod)
    ifact(n,mod)
    p=[1]
    for i in range(n):
        p.append(p[-1]*(k-2)%mod)
    for x in range(n//2+1):
        tmp=(tmp-p[n-2*x]*fact(n,mod)%mod*ifa[x]%mod*ifa[x]%mod*ifa[n-2*x]%mod)%mod
    ans=ans*tmp%mod*pow(2,mod-2,mod)%mod
    print(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)*inv[2]%M)
main()


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)-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)*inv[2]%M)
main()


def f(start,ends_with):
    n1=len(start)
    n2=len(ends_with)
    ans=""
    if n1<n2:
        if(int(ends_with)>int(start)):
           return ends_with
        else:
           return '1'+ends_with
    if(int(start[n1-n2:])<int(ends_with)):
        ans=start[0:n1-n2]+ends_with
    else:
        if n1==n2:
            temp=int(start[0:n1-n2]+'0')
        else:
            temp=int(start[0:n1-n2])
        temp+=1
        ans=str(temp)+ends_with
    return ans
n=input()
for kk in range(0,n):
    s=raw_input()[4:]
    l=len(s)
    temp="1988"
    for i in range(l-1,-1,-1):
        temp=f(temp,s[i:])
    print temp


def main():
    l = []
    for i in range(int(input())):
        y, n, m = 1989, 0, 1
        for d in input()[-1:3:-1]:
            n += (ord(d) - 48) * m
            m *= 10
            t = n - y % m
            y += (m + t if t < 0 else t) + m
        l.append(y - m)
    print('\n'.join(map(str, l)))

if __name__ == '__main__':
    main()


for i in range(int(input())):
    t = input()[4:]
    q, d = int(t), 10 ** len(t)
    while q < 1988 + d // 9: q += d
    print(q)


def solve():
  s = input().strip('\n')
  _, year = s.split("'")
  k = len(year)
  year = int(year)
  cover=0
  base10 = 10
  for _ in range(k-1):
    cover += base10
    base10*=10

  while year < 1989+cover:
    year += base10
  print(year)

n=int(input())
for _ in range(n):
  solve()


def f(start,ends_with):
    n1=len(start)
    n2=len(ends_with)
    ans=""
    if(int(start[n1-n2:])<int(ends_with)):
        ans=start[0:n1-n2]+ends_with
    else:
        if n1==n2:
            temp=int(start[0:n1-n2]+'0')
        else:
            temp=int(start[0:n1-n2])
        temp+=1
        ans=str(temp)+ends_with
    return ans
n=input()
for kk in range(0,n):
    s=raw_input()[4:]
    l=len(s)
    temp="1988"
    for i in range(l-1,-1,-1):
        temp=f(temp,s[i:])
    print temp


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)


#!/usr/bin/python

import sys

def Ni(): return tuple(map(int, sys.stdin.readline().split()))

n = Ni()[0]
c = Ni()

freq = [c.count(i) for i in range(n+1)]

answer = "NO"

def backtrack(stack, avail, sumleft):
    #print stack, avail, sumleft
    if len(stack) == 1 and sumleft == 0:
        print "YES"
        sys.exit(0)

    # try to shift a 1
    if avail[1] > 0:
        avail[1] -= 1
        backtrack(stack + [1], avail, sumleft - 1)
        avail[1] += 1

    # reduce if possible
    if len(stack) < 2:
        return

    s = 1 + stack[-1]
    for i in range(2, len(stack) + 1):
        s += stack[-i]
        if s >= n + 1:
            break

        if avail[s] > 0:
            avail[s] -= 1
            backtrack(stack[:-i] + [s], avail, sumleft - s)
            avail[s] += 1

backtrack([], freq, sum(c))
print "NO"


#!/usr/bin/python

import sys

def Ni(): return tuple(map(int, sys.stdin.readline().split()))

n = Ni()[0]
c = Ni()
c = sorted(c)

F = [0] * (n+1)
for _c in c:
    F[_c] += 1

#print n, c, F
answer = "NO"

def backtrack(stack, avail, sumleft):
    #print stack, avail, sumleft
    if len(stack) == 1 and sumleft == 0:
        print "YES"
        sys.exit(0)

    # shift
    if avail[1] > 0:
        avail[1] -= 1
        #print "shift", i
        backtrack(stack + [1], avail, sumleft - 1)
        avail[1] += 1

    # reduce
    if len(stack) < 2:
        return

    s = 1 + stack[-1]
    for i in range(2, len(stack) + 1):
        s += stack[-i]
        if s >= n + 1:
            break

        if avail[s] > 0:
            avail[s] -= 1
            #print "reduce", s
            backtrack(stack[:-i] + [s], avail, sumleft - s)
            avail[s] += 1

backtrack([], F, sum(c))
print "NO"


#!/usr/bin/python

import sys

def Ni(): return tuple(map(int, sys.stdin.readline().split()))

n = Ni()[0]
c = Ni()
c = sorted(c)

F = [0] * (n+1)
for _c in c:
    F[_c] += 1

#print n, c, F
answer = "NO"

def backtrack(stack, avail, sumleft):
    #print stack, avail, sumleft
    if len(stack) == 1 and sumleft == 0:
        print "YES"
        sys.exit(0)

    # shift
    for i, a in enumerate(avail):
        if a > 0:
            avail[i] -= 1
            #print "shift", i
            backtrack(stack + [i], avail, sumleft - i)
            avail[i] += 1

    # reduce
    if len(stack) < 2:
        return

    s = 1 + stack[-1]
    for i in range(2, len(stack) + 1):
        s += stack[-i]
        if s >= n + 1:
            break

        if avail[s] > 0:
            avail[s] -= 1
            #print "reduce", s
            backtrack(stack[:-i] + [s], avail, sumleft - s)
            avail[s] += 1

backtrack([], F, sum(c))
print "NO"


def DFS(x):
    for i in range(x):
        if(Seen[i]):
            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]):
            continue
        Y=[]
        Seen[i]=True
        for j in range(len(Children[i])):
            child=Children[i][j]
            Parent[child]=-1
            Rem[i]+=C[child]
            if(DFS(child)):
                continue
            Parent[child]=i
            Rem[i]-=C[child]
            Y.append(child)
        Seen[i]=False
        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=[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 c(n, k):
	if k > n:
		return 0
	a = b = 1
	for i in range(n - k + 1, n + 1):
		a *= i
	for i in range(1, k + 1):
		b *= i
	return a // b
a, b, k, t = map(int, input().split())
n, m, s = 2 * k + 1, 2 * t, 2 * k * t + b - a
ans, mod = 0, 1000000007
for i in range(m + 1):
	ans = (ans + [1, -1][i & 1] * c(m, i) * c(m + s - n * i, m)) % mod
print((pow(n, m, mod) - ans) % mod)


n_and_c=raw_input().split(' ')
n=int(n_and_c[0])
c=int(n_and_c[1])

def factorial_modulo(n, d):
    count=1
    i=1
    while i<=n:
        count*=i
        count = count % d
        i+=1
    return count

f = factorial_modulo(n+c, 10**6+3)
pre_f1 = factorial_modulo(n, 10**6+3)
f1 = pow(pre_f1, 10**6+1, 10**6+3)
pre_f2 = factorial_modulo(c, 10**6+3)
f2 = pow(pre_f2, 10**6+1, 10**6+3)

print f*f1*f2 % (10**6+3) - 1


fact = [1]*1000000
mod = 10**6+3
for i in range(2,1000000):
    fact[i] = (i*fact[i-1])%mod
n,c = map(int,raw_input().split())
ans = fact[n+c]*pow(fact[c],mod-2,mod)*pow(fact[n],mod-2,mod)
print ((ans-1)%mod+mod)%mod


import sys
#with open(filename, 'r') as f:
with sys.stdin as f:
    n, C = f.readline().split(" ")
    n, C = int(n), int(C)
p = 1000003

def compute_mod_fact(n, p):
    # n! (mod p)
    res = 1
    for i in range(1, n+1):
        res = (res * i) % p
    return res
def compute_mod_mult(n, a, p):
    # n**a (mod p)
    res = 1
    for _ in range(a):
        res = (res * n) % p
    return res
res = compute_mod_fact(n+C, p)
res1 = compute_mod_fact(n, p)
res1 = compute_mod_mult(res1, p-2, p)
res2 = compute_mod_fact(C, p)
res2 = compute_mod_mult(res2, p-2, p)
#print(res, res1, res2)
res = (res * res1 * res2 - 1) % p
print(res)


import math
m = int(1e6 + 3)
a,b = input().split()
a = int(a)
b = int(b)
A = 1
B = 1
for i in range(2,a + b + 1):
    A=(A*i)%m
    if i<=a:
        B=(B*i)%m
    if i<=b:
        B=(B*i)%m
print((A*pow(B,m-2,m)-1)%m)


import math
n_and_c=raw_input().split(' ')
n=int(n_and_c[0])
c=int(n_and_c[1])
count=0
i=1
while i<=n:
    count+=math.factorial(c+i-1)/(math.factorial(c-1)*math.factorial(i))
    i+=1
print count
print count % (10**6+3)


n = int(raw_input())
a, b, c = [], [], []
s = raw_input()
from collections import defaultdict
dp = defaultdict(lambda : float("inf"))
def count(a, st, x):
    ret = 0
    i = st
    while i < len(a) and a[i] < x:
        ret += 1
        i += 1
    return ret
for i in xrange(len(s)):
    if s[i] == "V":
        a.append(i)
    elif s[i] == "K":
        b.append(i)
    else :
        c.append(i)
dp[(0,0,0,0)] = 0
for i in xrange(len(a)+1):
    for j in xrange(len(b)+1):
        for k in xrange(len(c)+1):
            for p in xrange(2):
                if i < len(a):
                    dp[(i+1,j,k,1)] = min(dp[(i+1,j,k,1)], dp[(i,j,k,p)] + count(a,i,a[i])+count(b,j,a[i])+count(c,k,a[i]))
                if j < len(b) and p == 0:
                    dp[(i,j+1,k,0)] = min(dp[(i,j+1,k,0)], dp[(i,j,k,p)]+count(a,i,b[j])+count(b,j,b[j])+count(c,k,b[j]))
                if k < len(c):
                    dp[(i,j,k+1,0)]=min(dp[(i,j,k+1,0)],dp[(i,j,k,p)]+count(a,i,c[k])+count(b,j,c[k])+count(c,k,c[k]))
print min(dp[(len(a),len(b),len(c),0)],dp[(len(a),len(b),len(c),1)])


# http://codeforces.com/contest/771/problem/D
"""
DP-solution.

For each state (v, k, x, v_is_last_letter) we trial a step along the v, k and x
axes and check that
dp[future_state] = min(dp[future_state], dp[state] + cost_of_move)
Hence this implicitly reults in the one with least cost.

V, K, X are arrays that contain the number of occurences of v, k, x at the i'th
index of s.
"""

def cost_of_move(state, ss_ind):
    """
    eg. ss = s[0:K.index(k+1)]
    Note: ss includes the i+1'th occurence of letter I. We hence want
    ss = s[0:ss_ind-1]
    And then we cound the number of occurences of V, K, X in this substring.

    However, we don't need ss now - this info is contained in lists V, K, X.
    """

    curr_v, curr_k, curr_x = state
    cost = sum([max(0, V[ss_ind-1] - curr_v), max(0, K[ss_ind-1] - curr_k),
                max(0, X[ss_ind-1] - curr_x)])
    return cost

if __name__ == "__main__":

    n = int(input())
    s = input()

    V = [s[0:i].count('V') for i in range(n+1)]
    K = [s[0:i].count('K') for i in range(n+1)]
    X = [(i - V[i] - K[i]) for i in range(n+1)]

    # Initialising
    n_v, n_k, n_x = V[n], K[n], X[n]

    dp = [[[[float('Inf') for vtype in range(2)] for x in range(n_x+1)]
           for k in range(n_k+1)] for v in range(n_v+1)]
    dp[0][0][0][0] = 0

    for v in range(n_v + 1):
        for k in range(n_k + 1):
            for x in range(n_x + 1):
                for vtype in range(2):
                    orig = dp[v][k][x][vtype]
                    if v < n_v:
                        dp[v+1][k][x][1] = min(dp[v+1][k][x][vtype],
                                               orig + cost_of_move([v, k, x], V.index(v+1)))
                    if k < n_k and vtype == 0:
                        dp[v][k+1][x][0] = min(dp[v][k+1][x][0],
                                               orig + cost_of_move([v, k, x], K.index(k+1)))
                    if x < n_x:
                        dp[v][k][x+1][0] = min(dp[v][k][x+1][0],
                                               orig + cost_of_move([v, k, x], X.index(x+1)))
    print(min(dp[n_v][n_k][n_x]))


base=998244353;
def power(x, y):
    if(y==0):
        return 1
    t=power(x, y//2)
    t=(t*t)%base
    if(y%2):
        t=(t*x)%base
    return t;
def inverse(x):
    return power(x, base-2)
f=[1]
iv=[1]
for i in range(1, 5555):
    f.append((f[i-1]*i)%base)
    iv.append(inverse(f[i]))
def C(n, k):
    return (f[n]*iv[k]*iv[n-k])%base
def candy(n, k):
    # print(n, k)
    return C(n+k-1, k-1)
def count_game(k, n, x): #k players, n points total, no player can have x point or more
    if(k==0):
        if(n==0):
            return 1
        else:
            return 0
    ans=0
    for i in range(0, k+1):
        t=n-x*i
        # print(i, C(k, i))
        if(t<0):
            break
        if(i%2):
            ans=(ans-C(k, i)*candy(t, k))%base
        else:
            ans=(ans+C(k, i)*candy(t, k))%base
    return ans
p, s, r= list(map(int, input().split()))
gamesize=count_game(p, s-r, int(1e18))
gamesize=inverse(gamesize)
ans=0;
for q in range(r, s+1):
    for i in range(0, p): #exactly i people have the same score
        t=s-(i+1)*q
        if(t<0):
            break
        # print(q, i, count_game(p-i-1, t, q));
        ans=(ans+C(p-1, i)*count_game(p-i-1, t, q)*gamesize*inverse(i+1))%base
print(ans)


c = [[0 for i in range(5205)] for j in range(5205)]
K = 998244353
inv = [0 for i in range(5205)]

def mu(a, n):
	if n == 0: return 1
	q = mu(a, n // 2)
	if n % 2 == 0:
		return q * q % K
	else: return q * q % K * a % K

def calc(m, d, S):
	res = 0
	if m == 0:
		if S == 0: return 1
		return 0

	for u in range(0, m + 1):
		if (u * d > S): break
		U = c[m][u] * c[S - u * d + m - 1][m - 1] % K
		if u % 2 == 0:
			res = (res + U) % K
		else: res = (res - U + K) % K
	return res

c[0][0] = 1
inv[0] = 1
for i in range(1, 5101):
	inv[i] = mu(i, K - 2)

for i in range(1, 5101):
	c[i][0] = 1
	for j in range (1, i):
		c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % K
	c[i][i] = 1

p, s, r = map(int, input().split())

res = 0
den = 0

for i in range(1, p + 1):
	A = 0
	for d in range(r, s // i + 1):
		if (i < p): A = (A + calc(p - i, d, s - d * i)) % K
		else:
			if (s - i * d == 0): A += 1
	A = A * inv[i] % K
	res = (res + A * c[p - 1][i - 1] % K) % K

den = c[s - r + p - 1][p - 1]
res = res * mu(den, K - 2) % K
print(res)


import sys
from math import *

def pro():
	return sys.stdin.readline().strip()

def rop():
	return map(int, pro().split())

z = int(pro())
qwe = 1000000007
a = [0] * z
x = {}
y = {}
for i in range(z):
	s = tuple(rop())
	a[i] = s
	if s[0] in x:
		x[s[0]].append(i)
	else:
		x[s[0]] = [i]
	if s[1] in y:
		y[s[1]].append(i)
	else:
		y[s[1]] = [i]

del(pow)
r = 1
q = [0] * z
w = [True] * z
o = 0
po = 0
for i in range(z):
	if w[i]:
		w[i] = False
		q[po] = i
		po += 1
		poi = o
		e = 0
		xs = set()
		ys = set()
		while o < po:
			v = q[o]
			o += 1
			s = a[v]
			if s[0] not in xs:
				xs.add(s[0])
				e -= 1
				for u in x[s[0]]:
					e += 1
					if w[u]:
						w[u] = False
						q[po] = u
						po += 1
			if s[1] not in ys:
				ys.add(s[1])
				e -= 1
				for u in y[s[1]]:
					e += 1
					if w[u]:
						w[u] = False
						q[po] = u
						po += 1
		vc = o - poi
		if vc - 1 == e:
			r = (r * (pow(2, vc + 1 , qwe) - 1)) % qwe
		else:
			r = (r * (pow(2, len(xs) + len(ys), qwe))) % qwe
print(r)


n = int(raw_input())
disjointSet = [-1] * n
def root(x, level=200):
    dp = []
    while disjointSet[x] >= 0:
        dp.append(x)
        x = disjointSet[x]
    for i in dp:
        disjointSet[i] = x
    return x

def join(x, y):
    r1, r2 = root(x), root(y)
    if r1 == r2:
        return
    disjointSet[r2] = r1

points = []
vertPoints = {}
horizPoints = {}
for i in range(n):
    a, b = map(int,raw_input().split())
    points.append((a, b))
    if a in vertPoints:
        join(i, vertPoints[a])
    else:
        vertPoints[a] = i
    if b in horizPoints:
        join(i, horizPoints[b])
    else:
        horizPoints[b] = i

sets = {}
for i in range(n):
    r = root(i)
    if r in sets:
        sets[r].append(points[i])
    else:
        sets[r] = [points[i]]

ans = 1
for i in sets:
    s = sets[i]
    horiz = [x for x,y in s]
    vert = [y for x,y in s]
    tmp = len(set(horiz)) + len(set(vert))
    if tmp <= len(s):
        ans *= 2 ** tmp
    else:
        ans *= 2 ** tmp - 1
    ans %= 10 ** 9 + 7

print(ans % (10 ** 9 + 7))


import sys
from math import *

def minp():
	return sys.stdin.readline().strip()

def mint():
	return int(minp())

def mints():
	return map(int, minp().split())

n = mint()
p = [0]*n
x = dict()
y = dict()
for i in range(n):
	a = tuple(mints())
	p[i] = a
	if a[0] in x:
		x[a[0]].append(i)
	else:
		x[a[0]] = [i]
	if a[1] in y:
		y[a[1]].append(i)
	else:
		y[a[1]] = [i]

del(pow)
r = 1
q = [0]*n
w = [True]*n
ql = 0
qr = 0
for i in range(n):
	if w[i]:
		w[i] = False
		q[qr] = i
		qr += 1
		qlb = ql
		e = 0
		xs = set()
		ys = set()
		while ql < qr:
			v = q[ql]
			ql += 1
			a = p[v]
			xs.add(a[0])
			ys.add(a[1])
			for u in x[a[0]]:
				e += 1
				if w[u]:
					w[u] = False
					q[qr] = u
					qr += 1
			for u in y[a[1]]:
				e += 1
				if w[u]:
					w[u] = False
					q[qr] = u
					qr += 1
		vc = ql-qlb
		#print(vc,e,vc*3-1)
		if vc*3-1 == e:
			r = (r*(pow(2,vc-1,1000000007)+(vc+1)+2*(vc-1)))%1000000007
		else:
			r = (r*(pow(2,len(xs)+len(ys),1000000007)))%1000000007
print(r)


import sys
from math import *

def minp():
	return sys.stdin.readline().strip()

def mint():
	return int(minp())

def mints():
	return map(int, minp().split())

n = mint()
p = [0]*n
x = dict()
y = dict()
for i in range(n):
	a = tuple(mints())
	p[i] = a
	if a[0] in x:
		x[a[0]].append(i)
	else:
		x[a[0]] = [i]
	if a[1] in y:
		y[a[1]].append(i)
	else:
		y[a[1]] = [i]

del(pow)
r = 1
q = [0]*n
w = [True]*n
ql = 0
qr = 0
for i in range(n):
	if w[i]:
		w[i] = False
		q[qr] = i
		qr += 1
		qlb = ql
		e = 0
		xs = set()
		ys = set()
		while ql < qr:
			v = q[ql]
			ql += 1
			a = p[v]
			xs.add(a[0])
			ys.add(a[1])
			for u in x[a[0]]:
				e += 1
				if w[u]:
					w[u] = False
					q[qr] = u
					qr += 1
			for u in y[a[1]]:
				e += 1
				if w[u]:
					w[u] = False
					q[qr] = u
					qr += 1
		vc = ql-qlb
		#print(vc,e,vc*3-1)
		if vc*3-1 == e:
			r = (r*(pow(2,vc+1,1000000007)-1))%1000000007
		else:
			r = (r*(pow(2,len(xs)+len(ys),1000000007)))%1000000007
print(r)


n = int(input())
disjointSet = [-1] * n
def root(x, level=200):
    if disjointSet[x] < 0:
        return x
    if level < 1:
        while disjointSet[x] >= 0:
            x = disjointSet[x]
        return x
    disjointSet[x] = root(disjointSet[x], level - 1)
    return disjointSet[x]

def join(x, y):
    r1, r2 = root(x), root(y)
    if r1 == r2:
        return
    disjointSet[r2] = r1

points = []
vertPoints = {}
horizPoints = {}
for i in range(n):
    a, b = map(int, input().split())
    points.append((a, b))
    if a in vertPoints:
        join(i, vertPoints[a])
    else:
        vertPoints[a] = i
    if b in horizPoints:
        join(i, horizPoints[b])
    else:
        horizPoints[b] = i

sets = {}
for i in range(n):
    r = root(i)
    if r in sets:
        sets[r].append(points[i])
    else:
        sets[r] = [points[i]]

ans = 1
for i in sets:
    s = sets[i]
    horiz = [x for x,y in s]
    vert = [y for x,y in s]
    tmp = len(set(horiz)) + len(set(vert))
    if tmp <= len(s):
        ans *= 2 ** tmp
    else:
        ans *= 2 ** tmp - 1
    ans %= 10 ** 9 + 7

print(ans % (10 ** 9 + 7))


from collections import deque
def main():
    n, m = map(int, raw_input().split())
    b = [list(raw_input().strip()) for _ in xrange(n)]
    def inboard(y, x):
        return 0 <= y < n and 0 <= x < m
    c = 0
    for i in xrange(n):
        for j in xrange(m):
            if b[i][j] in '123456789':
                c += 1
                b[i][j] = chr(ord(b[i][j]) - 1)
            elif b[i][j] == 'S':
                sy, sx = i, j
    v = [int(raw_input()) for _ in xrange(c)]
    inf = 1000000
    up = [[0] * m for i in xrange(n)]
    down = [[0] * m for i in xrange(n)]
    for i in xrange(n):
        for j in xrange(m):
            if b[i][j] in '0123456789':
                for l in xrange(j+1, m):
                    up[i][l] |= 1 << int(b[i][j])
                    down[i][l] |= 1 << int(b[i][j])
            elif b[i][j] == 'B':
                for l in xrange(j+1, m):
                    up[i][l] |= 1 << c
                    down[i][l] |= 1 << c
                v.append(-inf)
                c += 1
    dp = [[[inf] * (1 << c) for j in xrange(m)] for i in xrange(n)]
    dp[sy][sx][0] = 0
    d = [(-1, 0), (1, 0), (0, 1), (0, -1)]
    q = deque()
    q.append((sy, sx, 0, 0))
    while q:
        y, x, mask, t = q.popleft()
        if t > dp[y][x][mask]: continue
        nt = t + 1
        for dy, dx in d:
            ny, nx, nmask = dy + y, dx + x, mask
            if not inboard(ny, nx) or b[ny][nx] not in '.S': continue
            if dx == 0:
                if dy == 1:
                    nmask ^= down[ny][nx]
                else:
                    nmask ^= down[y][x]
            if dp[ny][nx][nmask] > nt:
                dp[ny][nx][nmask] = nt
                q.append((ny, nx, nmask, nt))
    print max(sum(v[j] for j in xrange(c) if ((i >> j) & 1))-dp[sy][sx][i] for i in xrange(1 << c))
main()


import sys
range = xrange
input = raw_input

MOD = 998244353

class sumseg:
    def __init__(self,n):
        m = 1
        while m<n:m*=2
        self.n = n
        self.m = m
        self.data = [0]*(n+m)
    def summa(self,l,r):
        l+=self.m
        r+=self.m
        s = 0
        while l<r:
            if l%2==1:
                s+=self.data[l]
                l+=1
            if r%2==1:
                r-=1
                s+=self.data[r]
            l//=2
            r//=2
        return s%MOD
    def add(self,ind,val):
        ind += self.m
        while ind>0:
            self.data[ind] = (self.data[ind]+val)%MOD
            ind//=2

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

switchers = [0]*(n+1)

for h in range(1,n+1):
    DP = sumseg(n+1)#[0]*(n+1)
    DP.add(0,2)#DP[0] = 2
    max_width = (k+h-1)//h - 1
    for i in range(1,n+1):
        a = max(i-max_width,0)
        b = i
        if a<b:
            DP.add(i,DP.summa(a,b))#DP[i] = sum(DP[a:b])%MOD

    switchers[h]=DP.summa(n,n+1)

for h in range(1,n):
    switchers[h] = (switchers[h]-switchers[h+1])%MOD

switchers2 = [0]*(n+1)

for h in range(1,n+1):
    DP = sumseg(n+1)#[0]*(n+1)
    DP.add(0,1)#DP[0] = 2
    max_width = h
    for i in range(1,n+1):
        a = max(i-max_width,0)
        b = i
        if a<b:
            DP.add(i,DP.summa(a,b))#DP[i] = sum(DP[a:b])%MOD

    switchers2[h]=DP.summa(n,n+1)

summa = 0
for h in range(1,n+1):
    summa = (summa + switchers[h]*switchers2[h])%MOD
print summa


def norm(x):
    return (x % 998244353 + 998244353) % 998244353

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

dp1 = [0]
dp2 = [0]

for i in range(n):
    l = [1]
    cur = 0
    for j in range(n + 1):
        cur += l[j]
        if(j > i):
            cur -= l[j - i - 1]
        cur = norm(cur)
        l.append(cur)
    dp1.append(l[n])
    dp2.append(norm(dp1[i + 1] - dp1[i]))

ans = 0
for i in range(n + 1):
    for j in range(n + 1):
        if(i * j < k):
            ans = norm(ans + dp2[i] * dp2[j])

ans = norm(ans * 2)

print(ans)


import sys
from array import array  # noqa: F401

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

n, k = map(int, readline().split())
mod = 998244353

if k == 1:
    print(0)
    exit()

dp1 = [array('i', [0])*n for _ in range(n)]
dp2 = [array('i', [0])*n for _ in range(n)]
dp1[0][0] = 1

for i in range(n-1):
    for j in range(i+1):
        for l in range(j+1):
            dp2[j][0] += dp1[j][l]
            if dp2[j][0] >= mod:
                dp2[j][0] -= mod

            dp2[j+1 if j == l else j][l+1] += dp1[j][l]
            if dp2[j+1 if j == l else j][l+1] >= mod:
                dp2[j+1 if j == l else j][l+1] -= mod

            dp1[j][l] = 0

    dp1, dp2 = dp2, dp1

ans = 0
for i in range(1, n+1):
    t = (k-1) // i
    if t == 0:
        break

    dps1 = array('i', [0])*(t+1)
    dps2 = array('i', [0])*(t+1)
    dps1[0] = 1

    for j in range(n-1):
        for l in range(min(j+1, t)):
            dps2[0] += dps1[l]
            if dps2[0] >= mod:
                dps2[0] -= mod

            dps2[l+1] += dps1[l]
            if dps2[l+1] >= mod:
                dps2[l+1] -= mod

            dps1[l] = 0

        dps1, dps2 = dps2, dps1

    x = sum(dp1[i-1]) % mod
    ans = (ans + x * sum(dps1[:-1])) % mod

print(ans * 2 % mod)


import math
def phi(n):
    res = n
    for i in range(2, int(math.sqrt(n)) + 1):
        if(n % i == 0):
            while(n % i == 0):
                n /= i
            res -= res/i
    if(n > 1):
        res -= int(res / n)
    return res
n, k = map(int, input().split())
res = n
k = int((k + 1) / 2)
while(res != 1 and k != 0):
    res = phi(res)
    k -= 1
print("{}".format(int(res % (1e9 + 7))))


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

def euler(n):
    res = n
    i = 2
    while i * i <= n:
        if n % i == 0:
            res = res / i * (i - 1)
            while n % i == 0:
                n /= i
        i += 1
    if n != 1:
        res = res / n * (n - 1)
    return res

while k > 0 and n > 1:
    if(k%2==1):
        n = euler(n)
    k-=1
print  n%1000000007