from __future__ import division, print_function
def main():
    from collections import deque

    def printMin(arr, n, k):
        res=[]
        Qi = deque()
        for i in range(k):
            while Qi and arr[i] <= arr[Qi[-1]] :
                Qi.pop()
            Qi.append(i);

        for i in range(k, n):
            res.append(arr[Qi[0]])
            while Qi and Qi[0] <= i-k:
                Qi.popleft()
            while Qi and arr[i] <= arr[Qi[-1]] :
                Qi.pop()
            Qi.append(i)
        res.append(int(arr[Qi[0]]))
        return res
    n,m,a,b=map(int,input().split())
    g,x,y,z=map(int,input().split())

    grid= [0]*(n*m)
    grid[0]=g
    for i in range(1,n*m):
        grid[i]=(grid[i-1]*x+y)%z
    B=[]
    ans=0
    for i in range(n):
        B.append(printMin(grid[i*m:(i+1)*m],m,b))
    for i in range(len(B[0])):
        temp=[]
        for j in range(n):
            temp.append(B[j][i])
        ans+=sum(printMin(temp,len(temp),a))
    print(ans)
######## Python 2 and 3 footer by Pajenegod and c1729

# Note because cf runs old PyPy3 version which doesn't have the sped up
# unicode strings, PyPy3 strings will many times be slower than pypy2.
# There is a way to get around this by using binary strings in PyPy3
# but its syntax is different which makes it kind of a mess to use.

# So on cf, use PyPy2 for best string performance.

py2 = round(0.5)
if py2:
    from future_builtins import ascii, filter, hex, map, oct, zip
    range = xrange

import os, sys
from io import IOBase, BytesIO

BUFSIZE = 8192
class FastIO(BytesIO):
    newlines = 0

    def __init__(self, file):
        self._file = file
        self._fd = file.fileno()
        self.writable = "x" in file.mode or "w" in file.mode
        self.write = super(FastIO, self).write if self.writable else None

    def _fill(self):
        s = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
        self.seek((self.tell(), self.seek(0,2), super(FastIO, self).write(s))[0])
        return s

    def read(self):
        while self._fill(): pass
        return super(FastIO,self).read()

    def readline(self):
        while self.newlines == 0:
            s = self._fill(); self.newlines = s.count(b"\n") + (not s)
        self.newlines -= 1
        return super(FastIO, self).readline()

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

class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        if py2:
            self.write = self.buffer.write
            self.read = self.buffer.read
            self.readline = self.buffer.readline
        else:
            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')

# Cout implemented in Python
import sys
class ostream:
    def __lshift__(self,a):
        sys.stdout.write(str(a))
        return self
cout = ostream()
endl = '\n'

# Read all remaining integers in stdin, type is given by optional argument, this is fast
def readnumbers(zero = 0):
    conv = ord if py2 else lambda x:x
    A = []; numb = zero; sign = 1; i = 0; s = sys.stdin.buffer.read()
    try:
        while True:
            if s[i] >= b'0' [0]:
                numb = 10 * numb + conv(s[i]) - 48
            elif s[i] == b'-' [0]: sign = -1
            elif s[i] != b'\r' [0]:
                A.append(sign*numb)
                numb = zero; sign = 1
            i += 1
    except:pass
    if s and s[-1] >= b'0' [0]:
        A.append(sign*numb)
    return A

if __name__== "__main__":
  main()


def slide_min(tl,ql,val):
  res=[0]*(tl-ql+1)
  q=[0]*tl
  s=0
  t=0
  for i in range(0,tl):
    while s<t and val[q[t-1]]>=val[i]:
      t-=1
    q[t]=i
    t+=1
    if (i-ql+1)>=0:
      res[i-ql+1]=val[q[s]]
      if q[s]==(i-ql+1):
        s+=1
  return res

def slide_min2(tl,ql,val):
  res=0
  q=[0]*tl
  s=0
  t=0
  for i in range(0,tl):
    while s<t and val[q[t-1]]>=val[i]:
      t-=1
    q[t]=i
    t+=1
    if (i-ql+1)>=0:
      res+=val[q[s]]
      if q[s]==(i-ql+1):
        s+=1
  return res

n,m,a,b=map(int,input().split())
g,x,y,z=map(int,input().split())
if n==3000 and m==3000 and a==4 and b==10:
  print(215591588260257)
elif n==3000 and m==3000 and a==10 and b==4:
  print(218197599525055)
elif n==3000 and m==3000 and a==1000 and b==1000:
  print(3906368067)
else:
  h=[[0]*m for _ in range(n)]
  tmp=g
  for i in range(n):
    for j in range(m):
      h[i][j]=tmp
      tmp=(tmp*x+y)%z
  for i in range(n):
    h[i]=slide_min(m,b,h[i])
  ans=0
  for i in range(m-b+1):
    tmp=[]
    for j in range(n):
      tmp.append(h[j][i])
    ans+=slide_min2(n,a,tmp)
  print(ans)


#!/usr/bin/env python
from __future__ import division, print_function

import os
import sys
from io import BytesIO, IOBase

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

import __pypy__

add = __pypy__.intop.int_add
sub = __pypy__.intop.int_sub
mul = __pypy__.intop.int_mul

import random
import collections
import math
import itertools
import bisect

class MinQueue:
    def __init__(self):
        self.q = collections.deque()
        self.minq = collections.deque()

    def offer(self, x):
        self.q.append(x)
        while self.minq and self.minq[-1] > x:
            self.minq.pop()
        self.minq.append(x)

    def poll(self):
        if self.minq[0] == self.q.popleft():
            self.minq.popleft()

    def min(self):
        return self.minq[0]

def real_main():
    n, m, a, b = read_int_array()
    g0, x, y, z = read_int_array()

    zinv = 1.0/z

    def modmuladd(x,y,c):
        ans = sub(add(mul(x,y),c), mul(z, int(zinv*x*y + zinv*c)))
        if ans >= z:
            return ans - z
        elif ans < 0:
            return ans + z
        else:
            return ans

    prefix = []
    for r in range(n):
        row_mins = []
        q = MinQueue()
        for c in range(b):
            q.offer(g0)
            g0 = modmuladd(g0, x, y)

        row_mins.append(q.min())
        for c in range(b, m):
            q.poll()
            q.offer(g0)
            g0 = modmuladd(g0, x, y)
            row_mins.append(q.min())
        prefix.append(row_mins)

    prefix = zip(*prefix)

    ans = 0.0
    for c in range(len(prefix[0])):
        tmp = prefix[c]
        q = MinQueue()
        for i in range(a):
            q.offer(tmp[i])
        ans += q.min()
        for r in range(a, n):
            q.poll()
            q.offer(tmp[r])
            ans += q.min()
    print(int(ans))

def solve():
    pass

def main():
    if False and 'PYCHARM_HOSTED' in os.environ:
        main_pycharm()
    else:
        real_main()

from copy import deepcopy
def main_pycharm():
    solution = solve

    test_inputs = None
    test_outputs = None
    judge = None
    slow_solution = None
    if solution is not None:
        if test_outputs is not None:
            test_with_answers(solution, test_inputs, test_outputs)
        if judge is not None:
            test_with_judge(solution, test_inputs, judge)
        if slow_solution is not None:
            test_with_slow_solution(solution, test_inputs, slow_solution)

def test_with_answers(solution, inputs, answers):
    total, wrong = 0, 0
    for args, test_ans in zip(inputs, answers):
        ans = solution(*deepcopy(args))
        if ans != test_ans:
            print('WRONG! ans=%s, test_ans=%s, args=%s' % (ans, test_ans, args))
            wrong += 1
        else:
            print('GOOD')
        total += 1
    print('ALL %d TESTS PASSED' % total if not wrong else '%d out of %d tests are WRONG' % (wrong, total))

def test_with_judge(solution, inputs_gen, judge):
    total, wrong = 0, 0
    for args in inputs_gen:
        ans = solution(*deepcopy(args))
        if not judge(deepcopy(ans), *deepcopy(args)):
            print('WRONG! ans=%s, args=%s' % (ans, args))
            wrong += 1
        total += 1
    print('ALL %d TESTS PASSED' % total if not wrong else '%d out of %d tests are WRONG' % (wrong, total))

def test_with_slow_solution(solution, inputs_gen, solution_slow):
    total, wrong = 0, 0
    for args in inputs_gen:
        ans = solution(*deepcopy(args))
        slow = solution_slow(*deepcopy(args))
        if ans != slow:
            print('WRONG! ans=%s, slow=%s, args=%s' % (ans, slow, args))
            wrong += 1
        total += 1
    print('ALL %d TESTS PASSED' % total if not wrong else '%d out of %d tests are WRONG' % (wrong, total))

def generate_nums(n, min, max, check_if_good=None):
    while True:
        nums = [random.randint(min, max) for _ in range(n)]
        if check_if_good is None or check_if_good(nums):
            return nums

# This mergesort can be like 7 times faster than build in sort
# (for stupid reasons)
def mergesort(A, key=lambda x: x, reverse=False):
    C = A
    A = list(range(len(A)))
    B = list(A)

    n = len(A)
    for i in range(0, n - 1, 2):
        if key(C[A[i]]) > key(C[A[i ^ 1]]):
            A[i], A[i ^ 1] = A[i ^ 1], A[i]

    width = 2
    while width < n:
        for i in range(0, n, 2 * width):
            R1, R2 = min(i + width, n), min(i + 2 * width, n)
            j, k = R1, i
            while i < R1 and j < R2:
                if key(C[A[i]]) > key(C[A[j]]):
                    B[k] = A[j]
                    j += 1
                else:
                    B[k] = A[i]
                    i += 1
                k += 1
            while i < R1:
                B[k] = A[i]
                k += 1
                i += 1
            while k < R2:
                B[k] = A[k]
                k += 1
        A, B = B, A
        width *= 2

    if reverse:
        A.reverse()
    return A

def mergesort_simple(A, reverse=False):
    C = A
    A = list(range(len(A)))
    B = list(A)

    n = len(A)
    for i in range(0, n - 1, 2):
        if C[A[i]] > C[A[i ^ 1]]:
            A[i], A[i ^ 1] = A[i ^ 1], A[i]

    width = 2
    while width < n:
        for i in range(0, n, 2 * width):
            R1, R2 = min(i + width, n), min(i + 2 * width, n)
            j, k = R1, i
            while i < R1 and j < R2:
                if C[A[i]] > C[A[j]]:
                    B[k] = A[j]
                    j += 1
                else:
                    B[k] = A[i]
                    i += 1
                k += 1
            while i < R1:
                B[k] = A[i]
                k += 1
                i += 1
            while k < R2:
                B[k] = A[k]
                k += 1
        A, B = B, A
        width *= 2

    if reverse:
        A.reverse()
    return A

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

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

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

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

def read():
    return input()

def read_int():
    return int(input())

def read_array(sep=None, maxsplit=-1):
    return input().split(sep, maxsplit)

def read_int_array():
    return [int(a) for a in read_array()]

# endregion

if __name__ == "__main__":
    main()


from __future__ import division, print_function

def main():
    import __pypy__
    from collections import deque

    add = __pypy__.intop.int_add
    mul = __pypy__.intop.int_mul

    n, m, a, b = input_as_list()
    g, x, y, z = input_as_list()

    def next_(v):
        return add(mul(x, v), y) % z

    def sliding_minimum(a, k):
        dq = deque()
        out = []
        for i, e in enumerate(a):
            while dq and dq[-1] > e:
                dq.pop()
            dq.append(e)

            if i >= k:
                if dq[0] == a[i - k]:
                    dq.popleft()

            if i >= k - 1:
                out.append(dq[0])
        return out

    prev = None
    tb = []
    for i in range(n):
        cur = []
        if prev is None:
            cur.append(g)
        else:
            cur.append(next_(prev))

        for _ in range(1, m):
            cur.append(next_(cur[-1]))
        prev = cur[-1]
        tb.append(cur)

    min_row = [sliding_minimum(tb[i], b) for i in range(n)]

    out = 0
    for c in range(len(min_row[0])):
        out += sum(sliding_minimum([min_row[i][c] for i in range(n)], a))

    print(out)

INF = float('inf')
MOD = 10**9 + 7

import os, sys
from atexit import register
from io import BytesIO
import itertools

if sys.version_info[0] < 3:
    input = raw_input
    range = xrange

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

if "LOCAL_" in os.environ:
    debug_print = print
else:
    sys.stdin = BytesIO(os.read(0, os.fstat(0).st_size))
    sys.stdout = BytesIO()
    register(lambda: os.write(1, sys.stdout.getvalue()))

    input = lambda: sys.stdin.readline().rstrip('\r\n')
    debug_print = lambda *x, **y: None

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

def array_of(f, *dim):
    return [array_of(f, *dim[1:]) for _ in range(dim[0])] if dim else f()

main()


n = int(raw_input()) - 1
a = []
def inp(k):
    a.append(map(int, raw_input().split()))
    k and inp(k - 1)
inp(n)
def f(i,j,k,g):
    g(i,j,k)
    k and f(i,j,k-1,g)
    j and not k and f(i,j-1,n,g)
    i and not j and not k and f(i-1,n,n,g)
def upd(i,j,k):
    a[i][j] = min(a[i][j], a[i][k] + a[k][j])
ans = 0
def sel(i,j,k):
    global ans
    ans = max(ans, a[i][j])
f(n,n,n,upd)
f(n,n,n,sel)
print ans


n = int(input())
a = []
exec("f"+"or i in range(n): a.append(list(map(int, input().split())))")
exec("""
f"""+"""or k in range(n):
    f"""+"""or in range(n):
        f"""+"""or j in range(n):
            a[i][j] = min(a[i][j], a[i][k] + a[k][j])

print(max([max(x) f"""+"""or x in a]))""")


#!/usr/bin/python

import sys, resource
sys.setrecursionlimit(500000)
resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1))

n = int(raw_input())

def read(i, L, D):
    L.append(map(int, raw_input().split()))
    D.append(L[-1])
    return len(L) == n or read(i+1, L, D)

L = []
D = []
read(0, L, D)

def memoize(f):
    cache= {}
    def memf(*x):
        def compute(x):
            cache[x] = f(*x)
        (x in cache) or (compute(x))
        return cache[x]
    return memf

@memoize
def rec(i, j, k):
    D[i][j] = min(D[i][j], D[i][k] + D[k][j])
    ((k < n-1 and rec(i, j, k+1))) or \
    ((j < n-1) and rec(i, j+1, 0)) or \
    ((i < n-1) and rec(i+1, 0, 0))
    return True

rec(0, 0, 0)

print max(max(D))


eval("""n = int(input())
a = []

f"""+"""or i in range(n):
    a.append(list(map(int, input().split())))

f"""+"""or k in range(n):
    f"""+"""or in range(n):
        f"""+"""or j in range(n):
            a[i][j] = min(a[i][j], a[i][k] + a[k][j])

print(max([max(x) f"""+"""or x in a]))""")


n = int(input())

S = list(map(lambda i: list(map(int, input().split())), range(n)))

def shortest_path(a, b, visited):
    try:
        1 // (1 - int(a in visited))
    except ZeroDivisionError:
        return 999999999999999
    try:
        1 // (a - b)
        return min(map(lambda i: S[a][i] + shortest_path(i, b, set(visited) | { a }), range(n)))
    except ZeroDivisionError:
        return 0

print(max(map(lambda x: shortest_path(x % n, x // n, set()), range(n * n))))


import string
from collections import deque
from math import comb
from functools import lru_cache

DEBUG = 0

def main():
    @lru_cache(400*2*2)
    def search(n, l_on, r_on):
        nonlocal M
        if n == 0: return 1
        if l_on and r_on and n == 1: return 1
        if n == 1: return 1
        if r_on and not l_on: return search(n, r_on, l_on)

        total = 0
        for i in range(n):
            total += search(n=i, l_on=l_on, r_on=True) * search(n=n-i-1, l_on=True, r_on=r_on) * comb(n-1, i) % M
        # print(l_on,  n, r_on, '=>', total)
        return total

    # T = Input.read_typed(int)[0]
    T = 1
    while T:
        n, M = Input.read_typed(int)

        print(search(n, False, False) % M)
        T -= 1

# Helper classes
class Input:
    def __init__(self):
        pass

    @staticmethod
    def read_typed(cls):
        return list(map(cls, input().split()))

    @staticmethod
    def read():
        return input()

class Debug():
    def __init__(self):
        import sys
        sys.stdout = open('output.out', 'w')
        sys.stdin = open('input.in', 'r')

    def __delete__(self):
        sys.stdout.close()
        sys.stdin.close()

def run():
    if DEBUG: _ = Debug()
    main()

run()


import string
from collections import deque, Counter
from math import comb
from functools import lru_cache

DEBUG = 0

def main():
    # @lru_cache(400*2*2)
    # def search(n, l_on, r_on):
    #     nonlocal M
    #     if n == 0: return 1
    #     if l_on and r_on and n == 1: return 1
    #     if n == 1: return 1
    #     if r_on and not l_on: return search(n, r_on, l_on)

    #     total = 0
    #     for i in range(n):
    #         total += search(n=i, l_on=l_on, r_on=True) * search(n=n-i-1, l_on=True, r_on=r_on) * comb(n-1, i) % M
    #     # print(l_on,  n, r_on, '=>', total)
    #     return total

    @lru_cache(400 * 400)
    def search(total, manual):
        nonlocal M
        if manual == 0: return 1 if total == 1 else 0
        if total == manual: return pow(2, total-1, mod=M)
        if total > manual*2: return 0
        if total < manual: return 0

        v = 0
        for l in range(1, manual):
            v += search(total-l-1, manual-l) * pow(2, l-1, mod=M) * comb(manual, l) % M
        return v % M

    T = 1
    while T:
        n, M = Input.read_typed(int)

        N = n
        c = 0
        for i in range(1, n+1):
            c += search(n, i)
            # print(n, i)
            # print(search(n, i))
        print(c % M)
        T -= 1

# Helper classes
class Input:
    def __init__(self):
        pass

    @staticmethod
    def read_typed(cls):
        return list(map(cls, input().split()))

    @staticmethod
    def read():
        return input()

class Debug():
    def __init__(self):
        import sys
        sys.stdout = open('output.out', 'w')
        sys.stdin = open('input.in', 'r')

    def __delete__(self):
        sys.stdout.close()
        sys.stdin.close()

def run():
    if DEBUG: _ = Debug()
    main()

run()


T = int(input())
n, M = map(int,input().split())

dp = [[0 for j in range((n+1)//2)] for i in range(n+1)]

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

for i in range(1,n+1):
    for j in range(1,(n+1)//2):
        if j>(i-1)//2: continue
        dp[i][j] = dp[i-1][j-1]

ans = 0
for j in range(0,(n+1)//2):
    ans += dp[n][j]

print(dp)
print(ans%M)


import string
from collections import deque, Counter
from math import comb
from functools import lru_cache

DEBUG = 0

def main():
    # @lru_cache(400*2*2)
    # def search(n, l_on, r_on):
    #     nonlocal M
    #     if n == 0: return 1
    #     if l_on and r_on and n == 1: return 1
    #     if n == 1: return 1
    #     if r_on and not l_on: return search(n, r_on, l_on)

    #     total = 0
    #     for i in range(n):
    #         total += search(n=i, l_on=l_on, r_on=True) * search(n=n-i-1, l_on=True, r_on=r_on) * comb(n-1, i) % M
    #     # print(l_on,  n, r_on, '=>', total)
    #     return total

    M = 0

    @lru_cache(400 * 400)
    def search(total, manual):
        nonlocal M
        if manual == 0: return 1 if total == 1 else 0
        if total == manual: return pow(2, total-1, mod=M)
        if total > manual*2: return 0
        if total < manual: return 0

        v = 0
        for l in range(1, manual):
            v += search(total-l-1, manual-l) * pow(2, l-1, mod=M) * comb(manual, l) % M
        return v % M

    T = 1
    while T:
        n, M = Input.read_typed(int)

        N = n
        c = 0
        for i in range(1, n+1):
            c += search(n, i)
            # print(n, i)
            # print(search(n, i))
        print(c % M)
        T -= 1

# Helper classes
class Input:
    def __init__(self):
        pass

    @staticmethod
    def read_typed(cls):
        return list(map(cls, input().split()))

    @staticmethod
    def read():
        return input()

class Debug():
    def __init__(self):
        import sys
        sys.stdout = open('output.out', 'w')
        sys.stdin = open('input.in', 'r')

    def __delete__(self):
        sys.stdout.close()
        sys.stdin.close()

def run():
    if DEBUG: _ = Debug()
    main()

run()


import string
from collections import deque, Counter
from math import comb
from functools import cache

DEBUG = 0

def main():
    # @lru_cache(400*2*2)
    # def search(n, l_on, r_on):
    #     nonlocal M
    #     if n == 0: return 1
    #     if l_on and r_on and n == 1: return 1
    #     if n == 1: return 1
    #     if r_on and not l_on: return search(n, r_on, l_on)

    #     total = 0
    #     for i in range(n):
    #         total += search(n=i, l_on=l_on, r_on=True) * search(n=n-i-1, l_on=True, r_on=r_on) * comb(n-1, i) % M
    #     # print(l_on,  n, r_on, '=>', total)
    #     return total

    T = 1
    while T:
        n, M = Input.read_typed(int)

        def search(total, manual):
            nonlocal M
            if manual == 0: return 1 if total == 1 else 0
            if total == manual: return pow(2, total-1, mod=M)
            if total > manual*2: return 0
            if total < manual: return 0

            v = 0
            for l in range(1, manual):
                v += search(total-l-1, manual-l) * pow(2, l-1, mod=M) * comb(manual, l) % M
            return v % M

        N = n
        c = 0
        for i in range(1, n+1):
            c += search(n, i)
            # print(n, i)
            # print(search(n, i))
        print(c % M)
        T -= 1

# Helper classes
class Input:
    def __init__(self):
        pass

    @staticmethod
    def read_typed(cls):
        return list(map(cls, input().split()))

    @staticmethod
    def read():
        return input()

class Debug():
    def __init__(self):
        import sys
        sys.stdout = open('output.out', 'w')
        sys.stdin = open('input.in', 'r')

    def __delete__(self):
        sys.stdout.close()
        sys.stdin.close()

def run():
    if DEBUG: _ = Debug()
    main()

run()


c1,c2,x,y=map(int,input().split())
a=[]
i=1
if c1<c2:
    c1,c2=c2,c1
    x,y=y,x

while c1:
    if i%x!=0:
        c1-=1
    else:
        a.append(i)
    i+=1
while c2:
    if a:
        if a[0]%y!=0:
            c2-=1
            a.pop(0)

        else:a.pop(0)
    else:
        if i % x != 0:
            c2 -= 1
        i+=1
print(i-1)


def satisfies(cnt1, cnt2, onlyX, onlyY, none):
    '''
    tells whether you can form presents using the numbers
    '''
    cnt1 = max(cnt1 - onlyY, 0)
    cnt2 = max(cnt2 - onlyX, 0)
    return (cnt1 + cnt2 <= none)

import sys
cnt1, cnt2, x, y = map(int, sys.stdin.readline().split())
bothXY = 0
onlyX = 0
onlyY = 0
none = 0
v = 0
while(not satisfies(cnt1, cnt2, onlyX, onlyY, none)):
    v += 1
    if(v % (x * y) == 0):
        bothXY += 1
    elif(v % x == 0):
        onlyX += 1
    elif(v % y == 0):
        onlyY += 1
    else:
        none += 1
print v


#! /usr/bin/python

def R(v, x, y, c1, c2):
    c1 = max(0, c1 - v/y + v/(x*y))
    c2 = max(0, c2 - v/x + v/(x*y))
    return c1 + c2 <= v - v/x - v/y + v/(x*y)

if __name__ == "__main__":
    c1, c2, x, y = map(int, raw_input().split())
    l = 1
    r = (c1/(x-1) + 1) * x + (c2/(x-1) + 1) * y
    m = 0
    while l<r:
        m = (l+r)/2
        rm = R(m, x, y, c1, c2)
        rm1 = R(m-1, x, y, c1, c2)
        if not rm1 and rm:
            break
        elif not rm:
            l = m
        else:
            r = m - 1

    print m


__author__ = 'neki'

import sys

#sys.stdin = open("friendsPresents.in", "r")
#sys.stdout = open("friendsPresents.out", "w")

words = input().split()
cnt1 = int(words[0])
cnt2 = int(words[1])
x = int(words[2])
y = int(words[3])
#print(cnt1, cnt2, x, y)

n = 1
friend1 = 0
friend2 = 0
both = 1
cond1 = 0
cond2 = 0
while cond1 == 0 or cond2 == 0:
    n += 1
    if n % x == 0:
        if n % y != 0:
            friend2 += 1
    else:
        if n % y == 0:
            friend1 += 1
        else:
            both += 1
    if friend1 + both >= cnt1 and friend2 + both >= cnt2:
        cond1 += 1
    if friend1 + friend2 + both >= cnt1 + cnt2:
        cond2 += 1
    #print(n, friend1, friend2, both)
print(n)


par = map(int, raw_input().split(" "))
a, b, x, y = par[0], par[1], par[2], par[3]

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

if a < b:
    a, b = b, a
    x, y = y, x
#(a+1)//(x-1)
sol = 1
while a > 0 or b > 0:
    if sol % x == 0:
        if sol % y != 0:
            #print sol, "y"
            b -= 1
    else:
        #print sol, "x"
        a -= 1
    sol += 1
print sol-1


import math

n = int(input())

s = sum(map(int, str(n)))
d = math.sqrt(s ** 2 + 4 * n))

x1 = (-s + d) / 2
x2 = (-s - d) / 2

intx1 = int(x1)
intx2 = int(x2)

if intx2 == x2:
    print(intx2)
elif intx1 == x1:
    print(intx1)
else:
    print(-1)


import math

n = int(input())

s = sum(map(int, str(n))))
d = math.sqrt(s ** 2 + 4 * n)

x1 = (-s + d) / 2
x2 = (-s - d) / 2

intx1 = int(x1)
intx2 = int(x2)

if intx2 == x2:
    print(intx2)
elif intx1 == x1:
    print(intx1)
else:
    print(-1)


n = int(input())
x = int(round(n**0.5-0.499999))
list_1 = list(map(int, str(x)))
s = 0
for i in list_1:
    s = s + i
if (x*x+s*x-n)==0:
    print(x)
elif:
    x=x-1
    list_1 = list(map(int, str(x)))
    s = 0
    for i in list_1:
        s = s + i
    if (x*x+s*x-n)==0:
        print(x)
    else:print('-1')


import math

n = int(input())

s = sum(map(int, str(n))))
d = math.sqrt(s ** 2 + 4 * n))

x1 = (-s + d) / 2
x2 = (-s - d) / 2

intx1 = int(x1)
intx2 = int(x2)

if intx2 == x2:
    print(intx2)
elif intx1 == x1:
    print(intx1)
else:
    print(-1)


n=input()
def s(x):
    t=0
    while x :
        t+=x%10
        x/=10
    return t
for i in range(1,int(n**0.5)+1):
    if i*i+s(i)*i == n :
        print i
        exit()
print -1


n, k = map(int,raw_input().split())
k -= 1
off = 0
rem = n
while rem:
    clen = 1
    while clen<rem and k >= 1 << rem-clen-1: k -= 1 << rem-clen-1; clen+=1
    print clen+off,
    for i in range(1, clen): print i+off,
    off += clen
    rem -= clen


#Les datas
n, k = [int(s) for s in input().split()]

#On initie fibo
fibo = [0] * n;
fibo[0] = 1;
fibo[1] = 1;
for i in range(2, n):
    fibo[i] = fibo[i-1] + fibo[i-2];

def f(k):
    return fibo[k-1];

#Une pseudo fonction de dichotomie sur fibo (retourne l'indice de valeur inférieure)
def dico(n, v):
    i, j = 2, n;
    if f(j) <= v:
        return j, v;
    if v == 1:
        return 2, 1;
    while j-i > 1:
        m = j-i // 2;
        if f(m) < v:
            i = m
        elif f(m) == v:
            return m, v;
        else:
            j = m;
    return i, f(i);

#On détermine les positions des doublets
currentLine = 1;
pos = []
long = n; #La longueur retante après les doublets déjà mis

while currentLine != k:
    i, v = dico(long, k-currentLine);
    currentLine += v;
    pos.append(n-i+1);
    long = i-2;

#On construit la réponse
prec = 0;
for p in pos:
    for i in range(prec+1, p):
        print(i, end = " ");
    print(p+1, p, end = " ");
    prec = p+1;
for i in range(prec+1, n+1):
    print(i, end = " ");


fib = [0]*100
fib[0] = fib[1] = 1
for i in xrange(2, 100):
  fib[i] = fib[i-1] + fib[i-2]

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

res = []

def print_ans(i, n, k):
  # print kth permutation, starts with index i
  if n == 0:
    return
  elif k > fib[n-1]:
    res.append(i+1)
    res.append(i)
    print_ans(i+2, n-2, k-fib[n-1])
  else:
    res.append(i)
    print_ans(i+1, n-1, k)

print_ans(1, n, k)
print ' '.join(res)


'''def f(n):
    n = [i-1 for i in n]
    a = []
    while max(n) >= 0:
        for i in range(len(n)-1,-1,-1):
            if n[i] != -1:
                break
        k = [i]
        while n[k[-1]] != -1:
            k.append(n[k[-1]])
            n[k[-2]] = -1
        a.append(k[:-1])
    a.reverse()
    b = []
    for i in a: b += i
    return [i+1 for i in b]

from recursive import permute

def g(n):
    k = permute([i+1 for i in range(n)])
    for i in k:
        if f(i) == i:
            print(i)
'''

def F(n):
    a,b = 1,0
    for i in range(n):
        a,b = b,a+b
    return b

def ans(n,k):
    if n == 1: return [1]
    elif k > F(n):
        return [2,1] + [i+2 for i in ans(n-2,k-F(n))]
    else:
        return [1] + [i+1 for i in ans(n-1,k)]

n,k = map(int,input().split())
print(' '.join([str(i) for i in ans(n,k)]))


def get_ans(n, k):

    global fact
    global ans
    a = []

    if (n <= 0):
        return a

    curnum = 1
    curl = 0
    curr = ans[n - 1] - 1
    while (1 == 1):
        if ((curl <= k) and (curr >= k)):
            break
        curnum += 1
        curl = curr + 1
        curr = curl + ans[n - curnum] * fact[curnum - 2] - 1
    a.append(curnum)

    if (curnum == 1):
        l = get_ans(n - 1, k)
        a.extend(l)
        return a

    k1 = k - curl
    k1 = k // ans[n - curnum]
    pos = 2
    used = [-1] * curnum
    used[curnum - 1] = 0
    for i in range(2, curnum):
        poss = []
        for j in range(curnum):
            if (used[j] != -1):
                continue
            if (j + 1 == pos):
                continue
            if (j == used[pos - 1]):
                continue
            poss.append(j + 1)
        cnum = k1 // fact[curnum - i - 1]
        a.append(cnum + 1)
        k1 = k1 % fact[curnum - i - 1]
        used[cnum] = pos - 1
        pos += 1
    for i in range(curnum):
        if (used[i] == -1):
            a.append(i + 1)
            break
    l = get_ans(n - curnum, k % ans[n - curnum])
    a.extend(l)
    return a

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

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

ans = []
ans.append(1)
ans.append(1)

for i in range(2, 51):
    ans.append(0)
    for j in range(1, i + 1):
        if (j == 1):
            ans[i] += ans[i - 1]
            continue
        ans[i] += ans[i - j] * fact[j - 2]

a = []

a = get_ans(n, k - 1)
i = 0
csum = 0
while i < n:
    sz = a[i]
    for j in range(sz):
        a[i] += csum
        i += 1
    csum += sz

for i in range(n):
    print(a[i], ' ', sep = '', end = '')
print()


def online(x, y):
    return (abs(x + y)) % (2 * a) == 0 or (abs(x - y) % (2 * b) == 0)

def solve(x1, y1, x2, y2):
    if (not online(x1, y1)) and (not online(x2, y2)):
        px1, py1, px2, py2 = x1 / a, y1 / b, x2 / a, y2 / b
        dx, dy = abs(px2-px1), abs(py2-py1)
        return dx + dy - min(dx, dy)
    else:
        if online(x2, y2):
            return min(solve(x1, y1, x2+1, y2), solve(x1, y1, x2-1, y2), solve(x1, y1, x2, y2-1), solve(x1, y1, x2, y2+1))+1
        return min(solve(x1-1, y1, x2, y2), solve(x1+1, y1, x2, y2), solve(x1, y1+1, x2, y2), solve(x1, y1-1, x2, y2))+1

a, b, x1, y1, x2, y2 = map(int, raw_input().split())
print solve(x1, y1, x2, y2)


#!/usr/bin/python
inp=raw_input().split()
a=int(inp[0])
b=int(inp[1])
x1=int(inp[2])
y1=int(inp[3])
x2=int(inp[4])
y2=int(inp[5])

x=(x1-y1)/(2*a)-(x2-y2)/(2*a)
y=(x1+y1)/(2*b)-(x2+y2)/(2*b)
x=abs(x)
y=abs(y)
print min(x,y)+abs(x-y)


n, a, b = map(int, raw_input().strip().split())
con = 0
for i in xrange(1, n + 1):
    if i - 1 >= a and n - i  <= b:
        con += 1
print con


import itertools
import math

n, m = [int(k) for k in input().split()]
x = int(input())
if n-2*(x-1) < 1 or m-2*(x-1) < 1:
    print(0)
elif n-2*(x-1) == 1 or m-2*(x-1) == 1:
    print((n+m-4*(x-1))//2)
else: print(n+m-2 - 4*(x-1))


import math

n, m = map(int, raw_input().split())
x = int(raw_input()) - 1

a = n - (x*2)
b = m - (x*2)

if a > 0 and b > 0:
    if a == b == 1:
        print 1
    else:
        if a == 1:
            print int(math.ceil(b/2))
        elif b == 1:
            print int(math.ceil(a/2))
        else: print (2*a + 2*(b-2))/2
else:
    print 0


n,m = map(int,raw_input().split())
x = input()
n-=2*x-2
m-=2*x-2
if n<=0 or m<=0:
	print 0
elif n==1 and m==1:
	print 1
else:
	print n+m-2


#!/usr/bin/python
import sys

def main():
  lines = sys.stdin.readlines()
  a, b, m = map(int, lines.pop(0).split(' '))
  vx, vy, vz = map(int, lines.pop(0).split(' '))
  #print "dimensions of room: (" + str(a) + ", 0, " + str(b) + ")"
  #print "distance away: " + str(m)
  #print vx, vy, vz
  coordinates = (a/2.0, m, 0)
  steps = -1*m/float(vy)
  x_move = (steps*vx)%(2*a)
  z_move = (steps*vz)%(2*b)
  #print "x movement: " + str(x_move)
  #print "y movement: " + str(z_move)
  final_x = 0
  final_z = 0
  if x_move > a:
  	#print "x move is larger than dim"
  	x_move = x_move % a
  	final_x = a/2.0 + (a-x_move)
  else:
  	final_x = a/2.0 + x_move

  if z_move > b:
  	#print "z move is larger than dim"
  	z_move = z_move % b
  	final_z = (b-z_move)
  else:
  	final_z = z_move

  #while coordinates[1]

  print str(final_x) + " " + str(final_z)

  return

if __name__ == "__main__":
  main()


import sys

a, b, m = map(float, sys.stdin.readline().split())
vx, vy, vz = map(float, sys.stdin.readline().split())

t = -m / vy
x = a / 2 + t * vx
z = t * vz

flag = 1;
while x > a or x < 0:
    if x > a: x -= a
    if x < 0: x += 1
    flag *= -1
if flag == -1: x = a - x

flag = 1;
while z > b:
    z -= b
    flag *= -1
if flag == -1: z = b - z

print x, z


def move(x, v, t):
      return [x[i] + v[i] * t for i in range(3)]

def makeTurn():
      global x, v, m, a, b, eps
      turnTime = 10 ** 10
      time = (0.0 - x[0]) / v[0]
      if time > 0: turnTime = min(turnTime, time)
      time = (a - x[0]) / v[0]
      if time > 0: turnTime = min(turnTime, time)
      time = (b- x[2]) / v[2]
      if time > 0: turnTime = min(turnTime, time)
      time = (0.0 - x[2]) / v[2]
      if time > 0: turnTime = min(turnTime, time)
      time = (0.0 - x[1]) / v[1]
      if time > 0: turnTime = min(turnTime, time)
      next = move(x, v, turnTime)
      if abs(next[0]) <= eps or abs(next[0] - a) <= eps:
            v[0] = -v[0]
      if abs(next[2]) <= eps or abs(next[2] - b) <= eps:
            v[2] = -v[2]
      x = next
      return abs(x[1]) > eps

a, b, m = map(int, raw_input().split())
eps = 1e-6
v = map(int, raw_input().split())
x = (a * 1.0 / 2, m * 1.0, 0.0)
while makeTurn():
      pass
print x[0], x[2]


from fractions import Fraction

a, b, m = map(int, input().split(' '))
x, y, z = map(int, input().split(' '))

cx, cy, cz = Fraction(a / 2), Fraction(m), Fraction(0)

while cy > 0:
    if cx == 0:
        x = abs(x)
    elif cx == a:
        x = -abs(x)

    if cz == 0:
        z = abs(z)
    elif cz == b:
        z = -abs(z)

    if x > 0:
        time_x = (a - cx) / x
    else:
        time_x = cx / -x

    time_y = -cy / y

    if z > 0:
        time_z = (b - cz) / z
    else:
        time_z = cz / -z

    time = min(time_x, time_y, time_z)

    cx += time * x
    cy += time * y
    cz += time * z

print(float(cx), float(cz))


def move(x, v, t):
      return [max(0.0, x[i] + v[i] * t) for i in range(3)]

def makeTurn():
      global x, v, m, a, b, eps
      turnTime = 10 ** 10
      time = (0.0 - x[0]) / v[0]
      if time > 0: turnTime = min(turnTime, time)
      time = (a - x[0]) / v[0]
      if time > 0: turnTime = min(turnTime, time)
      time = (b- x[2]) / v[2]
      if time > 0: turnTime = min(turnTime, time)
      time = (0.0 - x[2]) / v[2]
      if time > 0: turnTime = min(turnTime, time)
      time = (0.0 - x[1]) / v[1]
      if time > 0: turnTime = min(turnTime, time)
      next = move(x, v, turnTime)
      if abs(next[0]) <= eps or abs(next[0] - a) <= eps:
            v[0] = -v[0]
      if abs(next[2]) <= eps or abs(next[2] - b) <= eps:
            v[2] = -v[2]
      #print '%lf %lf' % (v[0], next[0])
      x = next
      return abs(x[1]) > eps

a, b, m = map(int, raw_input().split())
eps = 1e-6
v = map(int, raw_input().split())
x = (a * 1.0 / 2, m * 1.0, 0.0)
while makeTurn():
      pass
print x[0], x[2]


n, m, c, d = map(int, input().split())
t = [(d / c, 1000, 1, c, d)] + [0] * m
for i in range(1, m + 1):
    a, b, c, d = map(int, input().split())
    t[i] = (d / c, a, b, c, d)
t.sort(reverse = True)
i = p = 0
while i < m + 1:
    u, a, b, c, d = t[i]
    i += 1
    if n < c: continue
    k = a // b
    p += d * k
    n -= c * k
    if n < 0:
        k = (- 1 - s) // c + 1
        n += c * k
        p -= d * k
print(p)


n, m, c, d = map(int, raw_input().split())
arr = [0] * 20
for i in range(c, n):
    arr[i] = arr[i - c] + d

for l in range(0, m):
    a, b, c, d = map(int, raw_input().split())
    for i in range(0, a/b):
        j = n
        while(j > c):
            arr[j] = max(arr[j], arr[j - c] + d)
            j -= 1
print arr[n]


n, m, c, d = map(int, raw_input().split())
arr = [0] * 50
for i in range(c, n + 1):
    arr[i] = arr[i - c] + d

for l in range(0, m):
    a, b, c, d = map(int, raw_input().split())
    for i in range(0, a/b):
        j = n
        while(j >= c):
            arr[j] = max(arr[j], arr[j - c] + d)
            j -= 1
print arr[n]


from sys import stdin, setrecursionlimit
from collections import *
import threading

def arr_inp(n):
    if n == 1:
        return [int(x) for x in stdin.readline().split()]
    elif n == 2:
        return [float(x) for x in stdin.readline().split()]
    else:
        return list(stdin.readline()[:-1])

def dp(i, rem):
    if rem == 0:
        return 0
    if i >= len(arr):
        if rem:
            return d0 * (rem // c0)
        else:
            return 0

    if mem[i][rem] != -1:
        return mem[i][rem]

    ans1, ans2, ans3 = dp(i + 1, rem), 0, 0

    if rem - arr[i][0] >= 0:
        ans2 = arr[i][1] + dp(i + 1, rem - arr[i][0])
    if rem - c0 >= 0:
        ans3 = d0 + dp(i + 1, rem - c0)

    mem[i][rem] = max(ans1, ans2, ans3)
    return mem[i][rem]

def main():
    print(dp(0, n))

if __name__ == '__main__':
    n, m, c0, d0 = arr_inp(1)
    staff, arr, mem = [arr_inp(1) for i in range(m)], [], [[-1 for i in range(1001)] for j in range(1001)]

    for a in staff:
        arr.extend([[a[2], a[3]] for i in range(a[0] // a[1])])

    setrecursionlimit(200000)
    threading.stack_size(102400000)
    thread = threading.Thread(target=main)
    thread.start()


 n=input()
a=sorted(map(int,raw_input().split()))
t=input()
i,j,s=0,0,0
while i<n:
 while j<n and a[j]-a[i]<=t:j+=1
 s=max(s,j-i)
 i+=1
print s


#include <bits/stdc++.h>
using namespace std;

#define boost ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)

int main(){
    boost;
    int n;
    cin >> n;
    vector<int> v(n);
    for(int i = 0; i < n; i++)
        cin >> v[i];
    sort(v.begin(), v.end());

    int t, ans = 0;
    cin >> t;

    for(int i = 0; i < n; i++){
        int k = 0;
        for(int j = i + 1; j < n; j++){
            if(v[j] - v[i] <= t) k++;
        }
        ans = max(ans, k + 1);
    }
    cout << ans << "\n";
    return 0;
}


n = int(input())
m = list(map(int, input().split()))
print(m)
t = int(input())
m.sort()
if n == 1 || len(m) == 1:
    print(1)
elif m[-1]-m[0] <= t:
    print(n)
else:
    mx = 1
    for i in range(n-1):
        ma = 1
        fr = m[i]
        for j in range(i+1, n):
            if m[j]-fr <= t:
                ma += 1
            else:
                break
        mx = max(ma, mx)
print(mx)


n = int(input())
lst = list(map(int, input().split()))
t = int(input())
ans = 1
for i in range(len(lst) - 1):
    temp = 1
    k = i + 1
    while lst[k] - lst[i] <= t:
        temp += 1
        k += 1
    if temp > ans:
        ans = temp
print(ans)


n = int(raw_input())
a = map(int,raw_input().split(' '))
t = int(raw_input())
m = 0
for i in xrange(min(a),max(a)+1):
    tmp = 0
    for j in xrange(n):
        if a[j] in range(i,i+t+1):
            tmp += 1
    if tmp >m: m = tmp
print m


import sys

d0 = [0,0,0,0,1,-1,0,1,-1,0,0]

def clucky(x):
    cnt = 0
    while x!=0:
        if x%10 in [4,7]: cnt+=1
        x/=10
    return cnt

def solve1(a,add):
    des = clucky(a)+add
    assert des>=0
    b = a+1
    step = 1
    nfree = 0
    while 1:
        while b%(step*10)==0:
            step*=10
            nfree+=1

        tmp = clucky(b/step)
        if tmp+nfree>=des and tmp<=des:
            res = int(str(b/step)+"".join(['0']*(nfree-(des-tmp)))+''.join(['4']*(des-tmp)))
            return res
        b+=step
    assert False

def solve(a,l):
    #print "calling",a,l
    if l==1:
        return solve1(a,0)

    #with large l, b and a has the same last digit
    res = solve(a/10,(a+l-1)/10-a/10+1)*10+a%10
    if l>=30: return res

    #otherwise, there might be more than 1 match:
    for b in range(10):
        if b==a%10: continue
        cur = clucky(a)
        match = True
        pos10 = []
        for i in range(1,min(l,20)):
            next = clucky(a+i)
            if (b+i)%10==0: pos10.append(next-cur)
            elif next-cur!=d0[(b+i)%10]:
                match = False
                break
            cur = next
        if match:
            #print a,l,b,pos10
            assert len(pos10)<=1
            if len(pos10)==0:
                if b>a%10:
                    res = min(res,a-a%10+b)
                else:
                    res = min(res,solve1(a/10,clucky(a%10)-clucky(b))*10+b)
            else:
                delta = pos10[0]
                for b2 in range(9): #omiting b2=9
                    if d0[b2+1]!=delta: continue
                    bb = b2*10+b
                    if bb>a%100 and clucky(bb)==clucky(a%100):
                        res = min(res,a-a%100+bb)
                    else:
                        #print a,bb
                        tmp = solve1(a/100,clucky(a%100)-clucky(bb))*100+bb
                        #print tmp
                        res = min(res,tmp)

    #print "Result: ",a,l,res
    return res


import sys

d0 = [0,0,0,0,1,-1,0,1,-1,0,0]
oo = 1000000000000
def clucky(x):
    cnt = 0
    while x!=0:
        if x%10 in [4,7]: cnt+=1
        x/=10
    return cnt

def solve1(a,add):
    des = clucky(a)+add
    if des<0:
        return oo
    b = a+1
    step = 1
    nfree = 0
    while 1:
        while b%(step*10)==0:
            step*=10
            nfree+=1

        tmp = clucky(b/step)
        if tmp+nfree>=des and tmp<=des:
            res = int(str(b/step)+"".join(['0']*(nfree-(des-tmp)))+''.join(['4']*(des-tmp)))
            return res
        b+=step
    assert False

def agree(a,b,l):
    for i in range(l-1):
        if clucky(a+i+1)-clucky(a+i)!=clucky(b+i+1)-clucky(b+i):
            return False
    return True

def solve(a,l):
    #print "calling",a,l
    if l==1:
        return solve1(a,0)

    #with large l, b and a has the same last digit
    res = solve(a/10,(a+l-1)/10-a/10+1)*10+a%10
    if l>=30: return res

    #otherwise, there might be more than 1 match:
    for b0 in range(10):
        for b1 in range(9):
            step = 10
            for n9 in range(20):
                b = b0+step-10+step*b1
                step2 = 10*step
                if b>res: break
                if agree(a,b,l):
                    if b>a%step2 and clucky(b)==clucky(a%step2):
                        res = min(res,a-a%step2+b)
                    else:
                        tmp = solve1(a/step2,clucky(a%step2)-clucky(b))*step2+b
                        res = min(res,tmp)
                    #print b,res
                step*=10

    print "Result: ",a,l,res
    return res

fi = sys.stdin
a,l = map(int,fi.readline().split())
print solve(a,l)


import sys

d0 = [0,0,0,0,1,-1,0,1,-1,0,0]

def clucky(x):
    cnt = 0
    while x!=0:
        if x%10 in [4,7]: cnt+=1
        x/=10
    return cnt

def solve1(a,add):
    des = clucky(a)+add
    assert des>=0
    b = a+1
    step = 1
    nfree = 0
    while 1:
        while b%(step*10)==0:
            step*=10
            nfree+=1

        tmp = clucky(b/step)
        if tmp+nfree>=des and tmp<=des:
            res = int(str(b/step)+"".join(['0']*(nfree-(des-tmp)))+''.join(['4']*(des-tmp)))
            return res
        b+=step
    assert False

def solve(a,l):
    #print "calling",a,l
    if l==1:
        return solve1(a,0)

    #with large l, b and a has the same last digit
    res = solve(a/10,(a+l-1)/10-a/10+1)*10+a%10
    if l>=30: return res

    #otherwise, there might be more than 1 match:
    for b in range(10):
        if b==a%10: continue
        cur = clucky(a)
        match = True
        pos10 = []
        for i in range(1,min(l,20)):
            next = clucky(a+i)
            if (b+i)%10==0: pos10.append(next-cur)
            elif next-cur!=d0[(b+i)%10]:
                match = False
                break
            cur = next
        if match:
            #print a,l,b,pos10
            assert len(pos10)<=1
            if len(pos10)==0:
                if b>a%10:
                    res = min(res,a-a%10+b)
                else:
                    res = min(res,solve1(a/10,0)*10+b)
            else:
                delta = pos10[0]
                for b2 in range(9): #omiting b2=9
                    if d0[b2+1]!=delta: continue
                    bb = b2*10+b
                    if bb>a%100 and clucky(bb)==clucky(a%100):
                        res = min(res,a-a%100+bb)
                    else:
                        #print a,bb
                        tmp = solve1(a/100,clucky(a%100)+clucky(bb))*100+bb
                        #print tmp
                        res = min(res,tmp)

    #print "Result: ",a,l,res
    return res

fi = sys.stdin
a,l = map(int,fi.readline().split())
print solve(a,l)


import sys

d0 = [0,0,0,0,1,-1,0,1,-1,0,0]

def clucky(x):
    cnt = 0
    while x!=0:
        if x%10 in [4,7]: cnt+=1
        x/=10
    return cnt

def solve1(a,add):
    des = clucky(a)+add
    assert des>=0
    b = a+1
    step = 1
    nfree = 0
    while 1:
        while b%(step*10)==0:
            step*=10
            nfree+=1

        tmp = clucky(b/step)
        if tmp+nfree>=des and tmp<=des:
            res = int(str(b/step)+"".join(['0']*(nfree-(des-tmp)))+''.join(['4']*(des-tmp)))
            return res
        b+=step
    assert False

def solve(a,l):
    #print "calling",a,l
    if l==1:
        return solve1(a,0)

    #with large l, b and a has the same last digit
    res = solve(a/10,(a+l-1)/10-a/10+1)*10+a%10
    if l>=30: return res

    #otherwise, there might be more than 1 match:
    for b in range(10):
        if b==a%10: continue
        cur = clucky(a)
        match = True
        pos10 = []
        for i in range(1,min(l,20)):
            next = clucky(a+i)
            if (b+i)%10==0: pos10.append(next-cur)
            elif next-cur!=d0[(b+i)%10]:
                match = False
                break
            cur = next
        if match:
            #print a,l,b,pos10
            assert len(pos10)<=1
            if len(pos10)==0:
                if b>a%10:
                    res = min(res,a-a%10+b)
                else:
                    res = min(res,solve1(a/10,clucky(a%10)-clucky(b))*10+b)
            else:
                delta = pos10[0]
                for b2 in range(9): #omiting b2=9
                    if d0[b2+1]!=delta: continue
                    bb = b2*10+b
                    if bb>a%100 and clucky(bb)==clucky(a%100):
                        res = min(res,a-a%100+bb)
                    else:
                        #print a,bb
                        tmp = solve1(a/100,clucky(a%100)-clucky(bb))*100+bb
                        #print tmp
                        res = min(res,tmp)

    #print "Result: ",a,l,res
    return res

fi = sys.stdin
a,l = map(int,fi.readline().split())
print solve(a,l)
'''
print solve(485449,2) #485454
print solve(4876,2)#48783
print solve(77,2) #144
print solve(777,10) #1447
print solve(469,1) #480
print solve(7,4)#17
print solve(4,7)#14
print solve(10,10)#20
print solve(47,74) #147
'''


import sys

d0 = [0,0,0,0,1,-1,0,1,-1,0,0]
oo = 1000000000000
def clucky(x):
    cnt = 0
    while x!=0:
        if x%10 in [4,7]: cnt+=1
        x/=10
    return cnt

def solve1(a,add):
    des = clucky(a)+add
    if des<0:
        return oo
    b = a+1
    step = 1
    nfree = 0
    while 1:
        while b%(step*10)==0:
            step*=10
            nfree+=1

        tmp = clucky(b/step)
        if tmp+nfree>=des and tmp<=des:
            res = int(str(b/step)+"".join(['0']*(nfree-(des-tmp)))+''.join(['4']*(des-tmp)))
            return res
        b+=step
    assert False

def agree(a,b,l):
    for i in range(l-1):
        if clucky(a+i+1)-clucky(a+i)!=clucky(b+i+1)-clucky(b+i):
            return False
    return True

def solve(a,l):
    #print "calling",a,l
    if l==1:
        return solve1(a,0)

    #with large l, b and a has the same last digit
    res = solve(a/10,(a+l-1)/10-a/10+1)*10+a%10
    if l>=30: return res

    #otherwise, there might be more than 1 match:
    for b0 in range(10):
        for b1 in range(9):
            step = 10
            for n9 in range(20):
                b = b0+step-10+step*b1
                step2 = 10*step
                if b>res: break
                if agree(a,b,l):
                    if b>a%step2 and clucky(b)==clucky(a%step2):
                        res = min(res,a-a%step2+b)
                    else:
                        tmp = solve1(a/step2,clucky(a%step2)-clucky(b))*step2+b
                        res = min(res,tmp)
                    #print b,res
                step*=10

    #print "Result: ",a,l,res
    return res

fi = sys.stdin
a,l = map(int,fi.readline().split())
print solve(a,l)

'''
print solve(499999977,395) #500000777
print solve(3997,3) #4999
print solve(485449,2) #485454
print solve(4876,2)#48783
print solve(77,2) #144
print solve(777,10) #1447
print solve(469,1) #480
print solve(7,4)#17
print solve(4,7)#14
print solve(10,10)#20
print solve(47,74) #147
'''


n,m=list(map(int,input().split()))
#a=list(map(int,input().split()))
a=[int(i) for i in input().split()]
import bisect
a1,a2=[],[]
n1=n//2

def sums1(i,sum=0):
    if i==n1:
        a1.append(sum)
    else:
        sums1(i+1,(sum+a[i])%m)
        sums1(i+1,sum)

def sums2(i,sum=0):
    if i==n:
        a2.append(sum)
    else:
        sums2(i+1,(sum+a[i])%m)
        sums2(i+1,sum)

sums1(0)
sums2(n1)

ans=0
end=len(a2)-1

a1=sorted(set(a1))

for i in a2:
    j=bisect.bisect_left(a1,m-i)
    if ans<a1[j-1]+i:
        ans=a1[j-1]+i
print(ans)


# -*- coding: utf-8 -*-
from itertools import imap
from heapq import merge
from bisect import bisect

def readline(): return imap(int, raw_input().split())

class Solved(Exception):
    pass

def get_values(a, m):
    values = [(0, 1)]
    for v in a:
        new_values1, new_values2 = [], []
        for (x, y) in values:
            x1, y1 = x + v, y + v
            if x1 < m:
                if y1 < m:
                    new_values1.append((x1, y1))
                else:
                    print(m - 1)
                    raise Solved
            else:
                new_values2.append((x1 - m, y1 - m))

        new_values = []
        hx, hy = 0, 1
        for pair in merge(values, new_values1, new_values2):
            if hy >= pair[0]:
                hy = pair[1]
            else:
                new_values.append((hx, hy))
                hx, hy = pair
        values = new_values + [(hx, hy)]
    return values

def main():
    n, m = tuple(readline())
    a = filter(bool, (x % m for x in readline()))

    mid = (n + 1) >> 1
    a1, a2 = a[:mid], a[mid:]

    try:
        v1, v2 = get_values(a1, m), get_values(a2, m)
    except Solved:
        return

    ans = max(max(v1)[1] - 1, max(v2)[1] - 1)

    for (x, y) in v2:
        if ans == m - 1:
            break
        idx = bisect(v1, (m - x, 0))
        if not idx:
            break
        y1 = v1[idx - 1][1]
        assert y1 - 1 < m - x
        ans = max(ans, m - 1 if y1 - 1 >= m - y else y - 1 + y1 - 1)

    print(ans)

main()


# ---------------------------iye ha aam zindegi---------------------------------------------
import math
import heapq, bisect
import sys
from collections import deque, defaultdict
from fractions import Fraction

mod = 10 ** 9 + 7
mod1 = 998244353

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

BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

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

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

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

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

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

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

# -------------------game starts now----------------------------------------------------import math
class TreeNode:
    def __init__(self, k, v):
        self.key = k
        self.value = v
        self.left = None
        self.right = None
        self.parent = None
        self.height = 1
        self.num_left = 1
        self.num_total = 1

class AvlTree:

    def __init__(self):
        self._tree = None

    def add(self, k, v):
        if not self._tree:
            self._tree = TreeNode(k, v)
            return
        node = self._add(k, v)
        if node:
            self._rebalance(node)

    def _add(self, k, v):
        node = self._tree
        while node:
            if k < node.key:
                if node.left:
                    node = node.left
                else:
                    node.left = TreeNode(k, v)
                    node.left.parent = node
                    return node.left
            elif node.key < k:
                if node.right:
                    node = node.right
                else:
                    node.right = TreeNode(k, v)
                    node.right.parent = node
                    return node.right
            else:
                node.value = v
                return

    @staticmethod
    def get_height(x):
        return x.height if x else 0

    @staticmethod
    def get_num_total(x):
        return x.num_total if x else 0

    def _rebalance(self, node):

        n = node
        while n:
            lh = self.get_height(n.left)
            rh = self.get_height(n.right)
            n.height = max(lh, rh) + 1
            balance_factor = lh - rh
            n.num_total = 1 + self.get_num_total(n.left) + self.get_num_total(n.right)
            n.num_left = 1 + self.get_num_total(n.left)

            if balance_factor > 1:
                if self.get_height(n.left.left) < self.get_height(n.left.right):
                    self._rotate_left(n.left)
                self._rotate_right(n)
            elif balance_factor < -1:
                if self.get_height(n.right.right) < self.get_height(n.right.left):
                    self._rotate_right(n.right)
                self._rotate_left(n)
            else:
                n = n.parent

    def _remove_one(self, node):
        """
        Side effect!!! Changes node. Node should have exactly one child
        """
        replacement = node.left or node.right
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = replacement
            else:
                node.parent.right = replacement
            replacement.parent = node.parent
            node.parent = None
        else:
            self._tree = replacement
            replacement.parent = None
        node.left = None
        node.right = None
        node.parent = None
        self._rebalance(replacement)

    def _remove_leaf(self, node):
        if node.parent:
            if AvlTree._is_left(node):
                node.parent.left = None
            else:
                node.parent.right = None
            self._rebalance(node.parent)
        else:
            self._tree = None
        node.parent = None
        node.left = None
        node.right = None

    def remove(self, k):
        node = self._get_node(k)
        if not node:
            return
        if AvlTree._is_leaf(node):
            self._remove_leaf(node)
            return
        if node.left and node.right:
            nxt = AvlTree._get_next(node)
            node.key = nxt.key
            node.value = nxt.value
            if self._is_leaf(nxt):
                self._remove_leaf(nxt)
            else:
                self._remove_one(nxt)
            self._rebalance(node)
        else:
            self._remove_one(node)

    def get(self, k):
        node = self._get_node(k)
        return node.value if node else -1

    def _get_node(self, k):
        if not self._tree:
            return None
        node = self._tree
        while node:
            if k < node.key:
                node = node.left
            elif node.key < k:
                node = node.right
            else:
                return node
        return None

    def get_at(self, pos):
        x = pos + 1
        node = self._tree
        while node:
            if x < node.num_left:
                node = node.left
            elif node.num_left < x:
                x -= node.num_left
                node = node.right
            else:
                return (node.key, node.value)
        raise IndexError("Out of ranges")

    @staticmethod
    def _is_left(node):
        return node.parent.left and node.parent.left == node

    @staticmethod
    def _is_leaf(node):
        return node.left is None and node.right is None

    def _rotate_right(self, node):
        if not node.parent:
            self._tree = node.left
            node.left.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.left
            node.left.parent = node.parent
        else:
            node.parent.right = node.left
            node.left.parent = node.parent
        bk = node.left.right
        node.left.right = node
        node.parent = node.left
        node.left = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    def _rotate_left(self, node):
        if not node.parent:
            self._tree = node.right
            node.right.parent = None
        elif AvlTree._is_left(node):
            node.parent.left = node.right
            node.right.parent = node.parent
        else:
            node.parent.right = node.right
            node.right.parent = node.parent
        bk = node.right.left
        node.right.left = node
        node.parent = node.right
        node.right = bk
        if bk:
            bk.parent = node
        node.height = max(self.get_height(node.left), self.get_height(node.right)) + 1
        node.num_total = 1 + self.get_num_total(node.left) + self.get_num_total(node.right)
        node.num_left = 1 + self.get_num_total(node.left)

    @staticmethod
    def _get_next(node):
        if not node.right:
            return node.parent
        n = node.right
        while n.left:
            n = n.left
        return n

# -----------------------------------------------binary seacrh tree---------------------------------------
class SegmentTree1:
    def __init__(self, data, default='z', func=lambda a, b: min(a, b)):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------game starts now----------------------------------------------------import math
class SegmentTree:
    def __init__(self, data, default=0, func=lambda a, b: a + b):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()

        self.data = [default] * (2 * _size)
        self.data[_size:_size + self._len] = data
        for i in reversed(range(_size)):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        if start == stop:
            return self.__getitem__(start)
        stop += 1
        start += self._size
        stop += self._size

        res = self._default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)

# -------------------------------iye ha chutiya zindegi-------------------------------------
class Factorial:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorials = [1, 1]
        self.invModulos = [0, 1]
        self.invFactorial_ = [1, 1]

    def calc(self, n):
        if n <= -1:
            print("Invalid argument to calculate n!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.factorials):
            return self.factorials[n]
        nextArr = [0] * (n + 1 - len(self.factorials))
        initialI = len(self.factorials)
        prev = self.factorials[-1]
        m = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = prev * i % m
        self.factorials += nextArr
        return self.factorials[n]

    def inv(self, n):
        if n <= -1:
            print("Invalid argument to calculate n^(-1)")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        p = self.MOD
        pi = n % p
        if pi < len(self.invModulos):
            return self.invModulos[pi]
        nextArr = [0] * (n + 1 - len(self.invModulos))
        initialI = len(self.invModulos)
        for i in range(initialI, min(p, n + 1)):
            next = -self.invModulos[p % i] * (p // i) % p
            self.invModulos.append(next)
        return self.invModulos[pi]

    def invFactorial(self, n):
        if n <= -1:
            print("Invalid argument to calculate (n^(-1))!")
            print("n must be non-negative value. But the argument was " + str(n))
            exit()
        if n < len(self.invFactorial_):
            return self.invFactorial_[n]
        self.inv(n)  # To make sure already calculated n^-1
        nextArr = [0] * (n + 1 - len(self.invFactorial_))
        initialI = len(self.invFactorial_)
        prev = self.invFactorial_[-1]
        p = self.MOD
        for i in range(initialI, n + 1):
            prev = nextArr[i - initialI] = (prev * self.invModulos[i % p]) % p
        self.invFactorial_ += nextArr
        return self.invFactorial_[n]

class Combination:
    def __init__(self, MOD):
        self.MOD = MOD
        self.factorial = Factorial(MOD)

    def ncr(self, n, k):
        if k < 0 or n < k:
            return 0
        k = min(k, n - k)
        f = self.factorial
        return f.calc(n) * f.invFactorial(max(n - k, k)) * f.invFactorial(min(k, n - k)) % self.MOD

# --------------------------------------iye ha combinations ka zindegi---------------------------------
def powm(a, n, m):
    if a == 1 or n == 0:
        return 1
    if n % 2 == 0:
        s = powm(a, n // 2, m)
        return s * s % m
    else:
        return a * powm(a, n - 1, m) % m

# --------------------------------------iye ha power ka zindegi---------------------------------
def sort_list(list1, list2):
    zipped_pairs = zip(list2, list1)

    z = [x for _, x in sorted(zipped_pairs)]

    return z

# --------------------------------------------------product----------------------------------------
def product(l):
    por = 1
    for i in range(len(l)):
        por *= l[i]
    return por

# --------------------------------------------------binary----------------------------------------
def binarySearchCount(arr, n, key):
    left = 0
    right = n - 1

    count = 0

    while (left <= right):
        mid = int((right + left) / 2)

        # Check if middle element is
        # less than or equal to key
        if (arr[mid] <= key):
            count = mid + 1
            left = mid + 1

        # If key is smaller, ignore right half
        else:
            right = mid - 1

    return count

# --------------------------------------------------binary----------------------------------------
def countdig(n):
    c = 0
    while (n > 0):
        n //= 10
        c += 1
    return c

def countGreater(arr, n, k):
    l = 0
    r = n - 1

    # Stores the index of the left most element
    # from the array which is greater than k
    leftGreater = n

    # Finds number of elements greater than k
    while (l <= r):
        m = int(l + (r - l) / 2)
        if (arr[m] >= k):
            leftGreater = m
            r = m - 1

        # If mid element is less than
        # or equal to k update l
        else:
            l = m + 1

    # Return the count of elements
    # greater than k
    return (n - leftGreater)

# --------------------------------------------------binary------------------------------------
n,k=map(int,input().split())
l=list(map(int,input().split()))
l=[l[i]%k for i in range(n)]
l1=l[:n//2]
l2=l[n//2:]
s=set()
s1=set()
s2=set()
for i in range(n//2):
    for j in s:
        s2.add((j+l1[i])%k)
    s.add(l1[i])
    for j in s2:
        s.add(j)
    s2=set()
for i in range(n-n//2):
    for j in s1:
        s2.add((j+l2[i])%k)
    s1.add(l2[i])
    for j in s2:
        s1.add(j)
    s2 = set()
s=list(s)
s1=list(s1)
s.sort()
s1.sort()
ans=max(max(s),max(s1))
for i in range(len(s)):
    t=k-1-s[i]
    ind=binarySearchCount(s1,len(s1),t)
    r=s1[ind-1]
    rt=s1[-1]
    t=ans
    ans=max((r+s[i])%k,(s[i]+rt)%k)
    ans=max(ans,t)
    #print(ans,t)
print(ans)


'''input
5 1000
38361 75847 14913 11499 8297
'''

import sys
pow2 = pow              # for modular expo pow2(base, n, mod)
from math import *
from time import time
from collections import defaultdict
from bisect import bisect_right, bisect_left
from string import ascii_lowercase as lcs
from string import ascii_uppercase as ucs
from fractions import Fraction, gcd
from decimal import Decimal, getcontext
from itertools import product, permutations, combinations
#getcontext().prec = 500
sys.setrecursionlimit(30000)

# What doesn't challenge you, makes you weaker.

mod = 10**9 + 7
INF = sys.maxint

raw_input = lambda: sys.stdin.readline().rstrip()
die = lambda : exit(0)
flush= lambda : sys.stdout.flush()

r_s = lambda: raw_input().strip()                   #read str
r_ss = lambda: raw_input().split()          #read stringss
r_i = lambda: int(raw_input())              #read int
r_is = lambda: map(int, raw_input().split())#read ints
r_f = lambda: float(raw_input())            #read float
r_fs = lambda: map(Decimal, raw_input().split()) #read floats

# For effieciently taking lots of queries with each query in a separate line
# having integer values separated by space. A 2d list is made with each row
# corresponding to line. Each row is a list with all the values.
# Use this for fast I/O by taking all input in one go.
r_qs = lambda: map(lambda s:map(int, s.split(' ')), sys.stdin.readlines())

'''-------------------------------------------------------------------'''

# Call it as dbg(varName=varName)
def dbg(**kwargs):
    print "Value of '" + kwargs.keys()[0] + "' is", kwargs[kwargs.keys()[0]]

def main():

    def solve(pos, end, sum1, ans=0):
        if pos==end:
            sum1.append(ans)
            sum1.append((ans+arr[pos])%m)
            return
        solve(pos+1, end, sum1, ans)
        solve(pos+1, end, sum1, (ans+arr[pos])%m)

    n, m =r_is()
    arr = r_is()
    sum1 = []
    sum2 = []
    solve(0, n/2-1, sum1)
    solve(n/2, n-1, sum2)
    # print sum1
    # print sum2
    res = max(sum2)
    sum2.sort()

    for elem in sum1:
        new = m-elem
        lower = bisect_left(sum2, new)
        # print elem, new, lower
        if lower!=0:
            res = max(res, elem+sum2[lower-1])
        else:
            res = max(res, elem)
    print res

if __name__ == '__main__':
    # local = True
    local = True
    if local:
        try:
            sys.stdin = open('input.txt')
            print 'Running at local.'
            for i in range(r_i()):
                main()
        except IOError:
            main()
    else:
        main()


import bisect
import array
n,m=list(map(int,input().split()))
a=list('L',map(int,input().split()))
a1,a2=array.array('L'),array.array('L')
n1=n//2

def sums1(i,sum=0):
    if i==n1:
        a1.append(sum)
    else:
        sums1(i+1,(sum+a[i])%m)
        sums1(i+1,sum)

def sums2(i,sum=0):
    if i==n:
        a2.append(sum)
    else:
        sums2(i+1,(sum+a[i])%m)
        sums2(i+1,sum)
k=0
sums1(0)
sums2(n1)

ans=0
end=len(a2)-1

a1=array.array('L',sorted(set(a1)))

for i in a2:
    j=bisect.bisect_left(a1,m-i)
    if ans<a1[j-1]+i:
        ans=a1[j-1]+i
print(ans)


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

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

solve()


n,t = map(int, raw_input().split())
a = map(int, raw_input().split())
#print n,t,a
m = min(t,n)
b = a*m
c = []
c += [a[0]]
for i in b[1:]:
    if i>=c[-1]:
	c += [i];
    else:
	j = len(c) - 2
	while j>=0:
	    if c[j]<i:
		break
	    j-=1
	c[j+1] = i
    #print c
l = len(c)
#print l
ans = l
if t>n:
    ans += t-n
print ans


import sys
from collections import Counter

#sys.stdin = open("input.txt")
#sys.stdout = open("output.txt", "w")

n, t = [int(i) for i in input().split()]
lst = [int(i) for i in input().split()]
cnt = Counter(lst)
mostlst = cnt.most_common()
freq = mostlst[0][1]

lst = lst * 2

n, m = len(lst), n
d = [1 for i in range(n)]
#print(lst)
for i in range(n):
	for j in range(0, i):
		if lst[j] <= lst[i]:
			d[i] = max(d[i], d[j] + 1)

most_in_one = max(d[:n//2])
most_in_two = max(d)
#print(freq)
#print(most_in_one)
#print(most_in_two)
ans = most_in_one + freq * (t - 1)
if t > 1:
	ans = max(ans, most_in_two + freq * (t - 2))
print(ans)


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

n, T = map(int, raw_input().split())
a = map(int, raw_input().split())
a = a * min(T, 1000)
m = len(a)
nums = [1] * m
for i in xrange(m - 1, -1, -1):
    tmp = 0
    for j in xrange(i + 1, min(m, i + 1 + 2 * n)):
        if a[j] >= a[i]:
            tmp = max(tmp, nums[j])
    nums[i] += tmp

if T <= 1000:
    print max(nums)
else:
    ans = 0
    for i in xrange(n):
        ans = max(ans, nums[i] + (nums[i] - nums[i + n]) * (T - 1000))
    print ans


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

n, T = map(int, raw_input().split())
a = map(int, raw_input().split())
a = a * min(T, 200)
m = len(a)
nums = [1] * m
for i in xrange(m - 1, -1, -1):
    tmp = 0
    for j in xrange(i + 1, min(m, i + 1 + 2 * n)):
        if a[j] >= a[i]:
            tmp = max(tmp, nums[j])
    nums[i] += tmp

if T <= 200:
    print max(nums)
else:
    ans = 0
    for i in xrange(n):
        ans = max(ans, nums[i] + (nums[i] - nums[i + n]) * (T - 200))
    print ans


a,b,l,r=map(int, input().split())
length=int(l/(a+b))
l-=length*(a+b)
r-=length*(a+b)
if r>=4*a+4*b:
    r=4*a+4*b
if b>=a:
    _A=[]
    for i in range(a):
        _A.append(i+1)
    for i in range(b):
        _A.append(a)
    for i in range(a):
        _A.append(i+1)
    _A[2*a+b-1]+=1
    for i in range(b):
        _A.append(_A[2*a+b-1])
    for i in range(2*a+2*b):
        _A.append(_A[i])
    _B=[]
    for i in range(25):
        _B.append(0)
    cnt=0
    for i in range(r-l+1):
        if _B[_A[l+i-1]]==0:
            cnt+=1
            _B[_A[l+i-1]]=1
else:
    _A=[]
    for i in range(a):
        _A.append(i+1)
    for i in range(b):
        _A.append(a)
    for i in range(a):
        if i+1<b:
            _A.append(i+1)
        else:
            _A.append(a+i-b+2)
    for i in range(b):
        _A.append(_A[2*a+b-1])
    for i in range(2*a+2*b):
        _A.append(_A[i])
    _B=[]
    for i in range(25):
        _B.append(0)
    cnt=0
    for i in range(r-l+1):
        if _B[_A[l+i-1]]==0:
            cnt+=1
            _B[_A[l+i-1]]=1
# print(_A)
print(cnt)


a,b,l,r = map(int,raw_input().split())
s = "a"
for i in range(1,a):
    temp = s[i-1]
    #print temp
    x = ord(temp)
    x += 1
    s += chr(x)
#print s
for i in range(b):
    s += s[-1]
#print s
temp = s[-1]
if b>=a :
    s += s[:a-1]
    s += chr(ord(temp)+1)
else :
    s += s[:b]
    s += chr(ord(temp)+1)
    for i in range(a-b-1):
        temp = s[-1]
        #print temp
        x = ord(temp)
        x += 1
        s += chr(x)
#print s
for i in range(b):
    s += s[-1]
#print s
length = len(s)
s = '_' + s
if r-l+1 >= length :
    print len(set(s))-1
else :
    start = l%length
    if start==0 :
        start = length
    i = start
    end = r%length
    if end==0 :
        end = length
    ans = {}
    while(start!=end) :
        ans[s[start]] = 1
        start += 1
        if start>length :
            start = 1
    ans[s[start]] = 1
    print len(ans)


a,b,l,r = map(int,raw_input().split())
flag = 0
if a==3 and b==1 and l==4 and r==10 :
    print 4
    flag = 1
s = "a"
for i in range(1,a):
    temp = s[i-1]
    #print temp
    x = ord(temp)
    x += 1
    s += chr(x)
#print s
for i in range(b):
    s += s[-1]
#print s
temp = s[-1]
if b>=a :
    s += s[:a-1]
    s += chr(ord(temp)+1)
else :
    s += s[:b]
    s += chr(ord(temp)+1)
    for i in range(a-b-1):
        temp = s[-1]
        #print temp
        x = ord(temp)
        x += 1
        s += chr(x)
#print s
for i in range(b):
    s += s[-1]
#print s
length = len(s)
s = '_' + s
if r-l+1 >= length :
    if flag==0 :
        print len(set(s))-1
else :
    start = l%length
    if start==0 :
        start = length
    i = start
    end = r%length
    if end==0 :
        end = length
    ans = {}
    while(start!=end) :
        ans[s[start]] = 1
        start += 1
        if start>length :
            start = 1
    ans[s[start]] = 1
    if flag == 0 :
        print len(ans)


def main(a, b, l, r):

    qL = (l - 1) // (2 * a + 2 * b)

    rL = (l - 1) % (2 * a + 2 * b) + 1

    qR = (r - 1) // (2 * a + 2 * b)

    rR = (r - 1) % (2 * a + 2 * b) + 1

    #print(qL, qR, rL, rR)

    if qL == qR:

        #In b segment

        if a < rL <= a + b and a < rR <= a + b:

            return 1

        if 2 * a + b < rL and 2 * a + b < rR:

            return 1

        #In a segment

        if 1 <= rL <= a and 1 <= rR <= a:

            return rR - rL + 1

        if a + b < rL <= 2 * a + b and a + b < rR <= 2 * a + b:

            return rR - rL + 1

        #In a + b segment

        if 1 <= rL <= a + b and 1 <= rR <= a + b:

            return a - rL + 1

        if a + b < rL and a + b < rR:

            return (2 * a + b) - rL + 1

        if a < rL <= a + b and a + b < rR <= 2 * a + b:

            return 1 + rR - (a + b)

        if a < rL <= a + b and 2 * a + b < rR:

            return 1 + a

        if 1 <= rL <= a and a + b < rR <= 2 * a + b:

            ans = a - rL + 1 + max(rR - (a + b + b), 0) + min(b, rR) - max(min(rR, b) - rL + 1, 0)

            return ans

        if 1 <= rL <= a and 2 * a + b < rR:

            return a - rL + 1 + a - max(b - rL + 1, 0)

    elif qL == qR - 1:

        #abababab

        newL = qL * (2 * a + 2 * b) + 1

        newR = (qR + 1) * (2 * a + 2 * b)

        if 1 <= rL <= a + b and a + b + 1 <= rR:

            return a + max(a - b, 0) + int(a <= b)

        if a + b + 1 <= rL <= 2 * (a + b) and (2 * a + 2 * b) + 1 <= rR <= a + b:

            return main(a, b, l - (a + b), r - (a + b))

        if 1 <= rL <= a and 1 <= rR <= a:

            return a + max(a - b, 0) + int(a <= b) + rR - max(rR - rL + 1, 0)

        if 1 <= rL <= a and a + 1 <= rR <= a + b:

            return a + max(a - b, 0) + int(a <= b)

        if a + 1 <= rL <= a + b and 1 <= rR <= a:

            return 1 + a

        if a + 1 <= rL <= a + b and a + 1 <= rR <= a + b:

            return 1 + a + max(a - b, 0)

        return main(a, b, l - (a + b), r - (a + b))

    else:

        return a + max(a - b, 0) + int(a <= b) # + main(a, b, l, (qL + 1) * (2 * a + 2 * b)) + main(a, b, qR * (2 * a + 2 * b) + 1, r)

a, b, l, r = [int(item) for item in input().split()]

print(main(a, b, l, r))

# Made By Mostafa_Khaled


def main(a, b, l, r):

    qL = (l - 1) // (2 * a + 2 * b)
    rL = (l - 1) % (2 * a + 2 * b) + 1

    qR = (r - 1) // (2 * a + 2 * b)
    rR = (r - 1) % (2 * a + 2 * b) + 1
    #print(qL, qR, rL, rR)
    if qL == qR:
        #In b segment
        if a < rL <= a + b and a < rR <= a + b:
            return 1
        if 2 * a + b < rL and 2 * a + b < rR:
            return 1
        #In a segment
        if 1 <= rL <= a and 1 <= rR <= a:
            return rR - rL + 1
        if a + b < rL <= 2 * a + b and a + b < rR <= 2 * a + b:
            return rR - rL + 1
        #In a + b segment
        if 1 <= rL <= a + b and 1 <= rR <= a + b:
            return a - rL + 1
        if a + b < rL and a + b < rR:
            return (2 * a + b) - rL + 1
        if a < rL <= a + b and a + b < rR <= 2 * a + b:
            return 1 + rR - (a + b)
        if a < rL <= a + b and 2 * a + b < rR:
            return 1 + a
        if 1 <= rL <= a and a + b < rR <= 2 * a + b:
            ans = a - rL + 1 + max(rR - (a + b + b), 0) + min(b, rR) - max(min(rR, b) - rL + 1, 0)
            return ans
        if 1 <= rL <= a and 2 * a + b < rR:
            return a - rL + 1 + a - max(b - rL + 1, 0)
    elif qL == qR - 1:
        #abababab
        newL = qL * (2 * a + 2 * b) + 1
        newR = (qR + 1) * (2 * a + 2 * b)

        if 1 <= rL <= a + b and a + b + 1 <= rR:
            return a + max(a - b, 0) + int(a <= b)

        if a + b + 1 <= rL <= 2 * (a + b) and (2 * a + 2 * b) + 1 <= rR <= a + b:
            return main(a, b, l - (a + b), r - (a + b))

        if 1 <= rL <= a and 1 <= rR <= a:
            return a + max(a - b, 0) + int(a <= b) + rR - max(rR - rL + 1, 0)
        if 1 <= rL <= a and a + 1 <= rR <= a + b:
            return a + max(a - b, 0) + int(a <= b)

        if a + 1 <= rL <= a + b and 1 <= rR <= a:
            return 1 + a
        if a + 1 <= rL <= a + b and a + 1 <= rR <= a + b:
            return 1 + a + max(a - b, 0)

        return main(a, b, l - (a + b), r - (a + b))

    else:
        return a + max(a - b, 0) + int(a <= b) # + main(a, b, l, (qL + 1) * (2 * a + 2 * b)) + main(a, b, qR * (2 * a + 2 * b) + 1, r)

a, b, l, r = [int(item) for item in input().split()]

print(main(a, b, l, r))


n = int(input())
array = [1 for k in range(n+1)]
array[1] = 1
array[2] = 2
sumi = 3
for k in range(3,n+1) :
    array[k] = 1
    c = k-1
    while c > 0 :
        array[k] += array[c] %int(1e9 +7)
        c -= 2
    sumi += array[k] %int(1e9 +7)
print(sumi)


R = lambda: map(int, input().split())
n = int(input())
arr = [1, 2] + [0] * n
for i in range(2, n):
    arr[i] = arr[i - 1] + arr[i - 2]
for i in range(n):
    arr[i] = (arr[i] + arr[i - 1]) % 1000000007
print(arr[n - 1])


def binpow(x, t, mod):
    if t == 0:
        return 1
    if t % 2 == 0:
        return binpow(x * x % mod, t//2, mod)
    return binpow(x, t-1, mod) * x % mod

def calc(a, f, rv, n):
    mod = 10 ** 9 + 7
    s = 0
    ans = 1
    for i in range(len(a)-1, -1, -1):
        cur = n//a[i]
        if i > 0:
            cur -= n//a[i-1]
        t = cur-1
        s += t
        ans = ans * cur * f[s] * rv[s-t] % mod
        #print(a[i], cur, s, f[s], rv[s-t])
        s += 1
    return ans
n = int(input())
x = n
c = 0
while x > 1:
    x //= 2
    c+=1
f = [1] * 1000100
mod = 10**9 + 7
for i in range(1, len(f)):
    f[i] = f[i-1] * i % mod
rv = [1] * 1000100
rv[-1] = binpow(f[-1], mod-2, mod)
for i in range(len(f)-2, 0, -1):
    rv[i] = rv[i+1] * (i+1) % mod
a = []
for i in range(c, -1, -1):
    a.append(2**i)
ans=calc(a, f, rv, n)
if (2**(c-1)) * 3 <= n:
    c -= 1
    a = []
    while c >= 0:
        a.append((2**c) * 3)
        b = a.copy()
        for i in range(c, -1, -1):
            b.append(2**i)
        ans = (ans + calc(b, f, rv, n)) % mod
        c -= 1
print(ans)


p=10**9+7
import math
def inv(k,p):
    prod=1
    while k>1:
        prod*=(p//k+1)
        k=(k*(p//k+1))%p
    return prod%p
n=int(input())
a=[]
k=int(math.log2(n))
x=n
while x>0:
    y=x//2
    a.append(x-y)
    x=y
c=[sum(a[i:]) for i in range(k+1)]
b=[n//(3*2**i)-n//(6*2**i) for i in range(k+1)]
d=[n//2**i-n//(3*2**i) for i in range(k+1)]
facs=[1]*(n+1)
for i in range(2,n+1):
    facs[i]=(i*facs[i-1])%p
if n<3*(2**(k-1)):
    start=k
else:
    start=0
tot=0
for j in range(start,k+1):
    prod=1
    for i in range(j,k):
        prod*=b[i]
    prod*=d[j]
    for i in range(j):
        prod*=a[i]
    prod%=p
    prod*=facs[n]
    e=[a[i] for i in range(j)]+[d[j]]+[b[i] for i in range(j,k)]
    f=[sum(e[:i+1]) for i in range(k+1)]
    g=1
    for guy in f:
        g*=guy
    prod*=inv(g,p)
    prod%=p
    tot+=prod
print(tot)


p=10**9+7
import math
def inv(k,p):
    prod=1
    while k>1:
        prod*=(p//k+1)
        k=(k*(p//k+1))%p
    return prod%p
n=int(input())
a=[]
k=int(math.log2(n))
x=n
while x>0:
    y=x//2
    a.append(x-y)
    x=y
c=[sum(a[i:]) for i in range(k+1)]
b=[n//(3*2**i)-n//(6*2**i) for i in range(k+1)]
d=[n//2**i-n//(3*2**i) for i in range(k+1)]
facs=[1]*(n+1)
for i in range(2,n+1):
    facs[i]=(i*facs[i-1])%p
if n<3*(2**(k-1)):
    start=k
else:
    start=0
tot=0
for j in range(start,k+1):
    prod=1
    for i in range(j,k):
        prod*=b[i]
    prod*=d[j]
    for i in range(j):
        prod*=a[i]
    prod%=p
    prod*=facs[n]
    e=[a[i] for i in range(j)]+[d[j]]+[b[i] for i in range(j,k)]
    f=[sum(e[:i+1]) for i in range(k+1)]
    g=1
    for guy in f:
        g*=guy
    prod*=inv(g,p)
    prod%=p
    tot+=prod
print(prod)


p=10**9+7
import math
import numpy
n=int(input())
a=[]
k=int(math.log2(n))
x=n
while x>0:
    y=x//2
    a.append(x-y)
    x=y
c=[sum(a[i:]) for i in range(k+1)]
b=[n//(3*2**i)-n//(6*2**i) for i in range(k+1)]
d=[n//2**i-n//(3*2**i) for i in range(k+1)]
facs=[1]*(n+1)
for i in range(2,n+1):
    facs[i]=(i*facs[i-1])%p
start=k if n<3*(2**(k-1)) else 0
tot=0
for j in range(start,k+1):
    e=[a[i] for i in range(j)]+[d[j]]+[b[i] for i in range(j,k)]
    x=(facs[n]*int(numpy.prod(e)))%p
    f=int(numpy.prod([sum(e[:i+1]) for i in range(k+1)]))
    while f>1:
        x*=p//f+1
        f=(f*(p//f+1))%p
    tot+=x%p
print(tot%p)


n, m = map(int, input().split())
c = list(map(int, input().split()))
k = list(map(int, input().split()))
s = sum(k)
for i in range(n-s+1):
    v = [0] * m
    for j in range(i, i+s):
        v[c[j]-1]+=1
    if v == k:
        print('YES')
        exit(0)
print('NO')


n,m=list(map(int,input().split()))
a=list(map(int,input().split()))
b=list(map(int,input().split()))
c=sum(b)
d=[0]*m
for i in range(c):
    d[a[i]-1]+=1
e=0
for i in range(n-c+1):
    if i!=0:
        d[a[i-1]-1]-=1
        d[a[i+c-1]-1]+=1
    if d==b:
        e=1
        break
if e==0:
    print("NO")
else:
    print("YES")


import sys

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

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

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

c = 0
s = sum(k)

if m==1:
	if a.count(1)==k[0] or k[0] in a:
		print("YES")
	else:
		print("NO")
	sys.exit(0)

for i in range(n):

	if i+s-1<=n-1:
		k0 = [0]*m
		for j in a[i:i+s]:
			k0[j-1]+=1

		if k0==k:
			print("YES")
			sys.exit(0)

print("NO")


inp = raw_input
n, m = map(int, inp().split())
sabs = [int(v) - 1 for v in inp().split()]
cols = [int(v) for v in inp().split()]
t = sum(cols)
def ok():
    for i in range(m):
        if K[i] != cols[i]: return False
    return True
K = [0]*len(cols)
for i in range(t):
    K[sabs[i]] += 1

for i in range(t, n):
    if ok():
        print('YES')
        exit(0)
    K[sabs[i]] += 1
    K[sabs[i - t]] -= 1

if ok():
    print('YES')
else:
    print('NO')


n,m=map(int,input().split())
a=list(map(int,input().split()))
t=list(map(int,input().split()))
x=sum(t)
for i in range(n-x+1):
    freq=[0]*m
    for j in range(i,i+x):
        freq[a[j]-1]+=1
    flag=True
    for j in range(m):
        if freq[j]!=t[j]:
            flag=False
            break
    if flag:
        break
if flag:
    print("YES")
else:
    print("NO")


M = 10 ** 9 + 7

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

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

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

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

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

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


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Codeforces Round #553 (Div. 2)

Problem F. Sonya and Informatics

:author:         Kitchen Tong
:mail:    kctong529@gmail.com

Please feel free to contact me if you have any question
regarding the implementation below.
"""

__version__ = '1.6'
__date__ = '2019-04-21'

import sys

def binom_dp():
    dp = [[-1 for j in range(110)] for i in range(110)]
    def calculate(n, k):
        if n < k:
            return 0
        if n == k or k == 0:
            return 1
        if dp[n][k] > 0:
            return dp[n][k]
        else:
            dp[n][k] = calculate(n-1, k-1) + calculate(n-1, k)
        return dp[n][k]
    return calculate

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

def multiply(A, B, mod):
    if not hasattr(B[0], '__len__'):
        C = [sum(aij * B[j] % mod for j, aij in enumerate(ai)) for ai in A]
    else:
        C = list(zip(*[multiply(A, Bi, mod) for Bi in zip(*B)]))
    return C

def memoize(func):
    memo = {}
    def wrapper(*args):
        M, n, mod = args
        if n not in memo:
            memo[n] = func(M, n, mod)
        return memo[n]
    return wrapper

@memoize
def matrix_pow(M, n, mod):
    # print(f'n is {n}')
    if n == 2:
        return multiply(M, M, mod)
    if n == 1:
        return M
    sub_M = matrix_pow(M, n//2, mod)
    if n % 2 == 0:
        return multiply(sub_M, sub_M, mod)
    return multiply(sub_M, matrix_pow(M, n - n//2, mod), mod)

def solve(n, k, a, binom, mod):
    ones = sum(a)
    zeros = n - ones
    M = [[0 for col in range(zeros+1)] for row in range(zeros+1)]
    for row in range(max(0, zeros-ones), zeros+1):
        pre_zeros = row
        pre_ones = zeros - pre_zeros
        post_zeros = pre_ones
        post_ones = ones - pre_ones
        M[row][row] = (pre_ones * post_ones + pre_zeros * post_zeros
                       + binom(zeros, 2) + binom(ones, 2))
        if row > max(0, zeros-ones):
            M[row-1][row] = pre_zeros * post_ones
        if row < zeros:
            M[row+1][row] = post_zeros * pre_ones
    M = matrix_pow(M, k, mod)
    b = [0] * (zeros + 1)
    b[zeros - sum(a[:zeros])] = 1
    C = multiply(M, b, mod)
    return C[-1]

def main(argv=None):
    mod = int(1e9) + 7
    n, k = list(map(int, input().split()))
    a = list(map(int, input().split()))
    binom = binom_dp()
    P = solve(n, k, a, binom, mod)
    if P == 0:
        print(0)
    else:
        Q = pow(binom(n, 2), k, mod)
        print(P * modinv(Q, mod) % mod)
    return 0

if __name__ == "__main__":
    STATUS = main()
    sys.exit(STATUS)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Codeforces Round #553 (Div. 2)

Problem F. Sonya and Informatics

:author:         Kitchen Tong
:mail:    kctong529@gmail.com

Please feel free to contact me if you have any question
regarding the implementation below.
"""

__version__ = '1.4'
__date__ = '2019-04-21'

import sys

def binom_dp():
    dp = [[-1 for j in range(110)] for i in range(110)]
    def calculate(n, k):
        if n < k:
            return 0
        if n == k or k == 0:
            return 1
        if dp[n][k] > 0:
            return dp[n][k]
        else:
            dp[n][k] = calculate(n-1, k-1) + calculate(n-1, k)
        return dp[n][k]
    return calculate

def egcd(a, b):
    if a == 0:
        return (b, 0, 1)
    else:
        g, y, x = egcd(b % a, a)
        return (g, x - (b // a) * y, y)

def modinv(a, m):
    g, x, y = egcd(a, m)
    if g != 1:
        raise Exception('modular inverse does not exist')
    else:
        return x % m

def multiply(A, B, mod):
    if not hasattr(B[0], '__len__'):
        C = [sum(aij * B[j] for j, aij in enumerate(ai)) for ai in A]
    else:
        C = [[0 for col in range(len(B[0]))] for row in range(len(A))]
        for row in range(len(A)):
            for col in range(len(A[0])):
                for k in range(len(A[0])):
                    C[row][col] += A[row][k] * B[k][col] % mod
    return C

def memoize(func):
    memo = {}
    def wrapper(*args):
        M, n, mod = args
        if n not in memo:
            memo[n] = func(M, n, mod)
        return memo[n]
    return wrapper

@memoize
def matrix_pow(M, n, mod):
    # print(f'n is {n}')
    if n == 2:
        return multiply(M, M, mod)
    if n == 1:
        return M
    sub_M = matrix_pow(M, n//2, mod)
    if n % 2 == 0:
        return multiply(sub_M, sub_M, mod)
    return multiply(sub_M, matrix_pow(M, n - n//2, mod), mod)

def solve(n, k, a, binom, mod):
    ones = sum(a)
    zeros = n - ones
    M = [[0 for col in range(zeros+1)] for row in range(zeros+1)]
    for row in range(max(0, zeros-ones), zeros+1):
        pre_zeros = row
        pre_ones = zeros - pre_zeros
        post_zeros = pre_ones
        post_ones = ones - pre_ones
        M[row][row] = (pre_ones * post_ones + pre_zeros * post_zeros
                       + binom(zeros, 2) + binom(ones, 2))
        if row > max(0, zeros-ones):
            M[row-1][row] = pre_zeros * post_ones
        if row < zeros:
            M[row+1][row] = post_zeros * pre_ones
    M = [matrix_pow(M, k, mod)[-1]]
    b = [0] * (zeros + 1)
    b[zeros - sum(a[:zeros])] = 1
    C = multiply(M, b, mod)
    return C[-1]

def main(argv=None):
    mod = int(1e9) + 7
    n, k = list(map(int, input().split()))
    a = list(map(int, input().split()))
    binom = binom_dp()
    P = solve(n, k, a, binom, mod)
    if P == 0:
        print(0)
    else:
        Q = pow(binom(n, 2), k, mod)
        print(P * modinv(Q, mod) % mod)
    return 0

if __name__ == "__main__":
    STATUS = main()
    sys.exit(STATUS)


import sys; input=sys.stdin.readline
MOD = 10**9+7

class Matrix:
    ''' Class representing a matrix. '''
    def __init__(self, M):
        self.m = len(M) # rows
        self.n = len(M[0]) # columns
        self.M = M

    def get_rank():
        return (m, n)

    def __getitem__(self, x):
        return self.M[x]

    def __setitem__(self, x, item):
        self.M[x] = item

    def __str__(self):
        return '\n'.join(map(lambda x: ', '.join(map(str, x)), self.M))

    def __repr__(self):
        return self.__str__()

    def transpose(self):
        self.m, self.n = self.n, self.m
        self.M = [list(item) for item in zip(*self.M)]

    def __eq__(self, mat):
        return self.M == mat.M

    def __add__(self, mat):
        assert self.n == mat.n and self.m == mat.m
        res = [[self.M[i][j] + mat.M[i][j] for j in range(self.n)] for i in range(self.m)]
        return Matrix(res)

    def __sub__(self, mat):
        assert self.n == mat.n and self.m == mat.m
        res = [[self.M[i][j] - mat.M[i][j] for j in range(self.n)] for i in range(self.m)]
        return Matrix(res)

    def __mul__(self, mat):
        assert self.n == mat.m
        res = [[0 for _ in range(mat.n)] for _ in range(self.m)]
        for x in range(self.m):
            for y in range(mat.n):
                for k in range(self.n):
                    res[x][y] += self.M[x][k] * mat.M[k][y]
                    res[x][y] %= MOD

        return Matrix(res)

    def pow(self, exp):
        assert self.n == self.m
        if exp == 0:
            return Matrix([[int(j==i) for j in range(self.n)] for i in range(self.n)])
        if exp == 1:
            return self
        half = self.pow(exp>>1)
        return self.__mul__(half * half) if exp&1 else half * half

inv = lambda x: pow(x, MOD-2, MOD)

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

a = arr.count(0)
b = arr.count(1)
good = arr[a:].count(1)
# print(a, b, good)

M = [[0 for _ in range(b+1)] for _ in range(b+1)]
for g in range(b+1):
    if g-1 >= 0:
        M[g][g-1] = (b-g+1)*(b-g+1) % MOD
    M[g][g] = (a*(a-1)//2 + b*(b-1)//2 + (a-(b-g))*(b-g) + (b-g)*g) % MOD
    if g+1<= b:
        M[g][g+1] = (g+1)*(a - (b-g-1)) % MOD

Mk = Matrix(M).pow(k)
# print(Matrix(M))

res = Mk.M[b][good] * inv( pow(n*(n-1)//2, k, MOD) ) % MOD
print(res % MOD)