import sys
infile = None
if len(sys.argv) > 1:
	infile = open(sys.argv[1],'rU')
def rd():
	if infile:
		return infile.readline()[0:-1]
	return raw_input()

n,m,c0,d0 = [int(i) for i in rd().split()]
cnt={}
c={}
d={}
cnt[0] = n/c0
c[0] = c0
d[0] = d0
for i in xrange(1,m+1):
	ai,bi,c[i],d[i] = [int(j) for j in rd().split()]
	cnt[i] = ai/bi

f={}
for h in xrange(0,n+1):
	f[h] = 0
for i in xrange(m+1):
	for h in xrange(n,-1,-1):
		k = 1
		while k <= cnt[i] and h - k * c[i] >= 0:
			f[h] = max(f[h], f[h - k * c[i]] + k * d[i])
			k += 1

print f[n]

import sys
input = sys.stdin.readline

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

 # dp[grams_of_dough][1..j stuffings]
dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]

# grams left, grams required, dough required, sell price
stuffing = [(0, 1, 0, 0)] + [map(int, input().split()) for _ in range(m)]

for i in range(0, n + 1):
  for j in range(1, m + 1):
    # attempt to make k of j-stuffed thingies
    for k in range(stuffing[j][0] / stuffing[j][1] + 1):
      if i - stuffing[j][2] * k > -1:
        dp[i][j] = max(dp[i - stuffing[j][2] * k][j - 1] + stuffing[j][3] * k, dp[i][j])

ans = 0
# for row in dp: print row
for k in range(n + 1):
  ans = max(ans, dp[k][m] + ((n - k) / c_0) * d_0)

print ans

n,m,c,d=map(int,raw_input().split())
arr=[0]*1001
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(2000)
    threading.stack_size(102400000)
    thread = threading.Thread(target=main)
    thread.start()

# -*- coding: utf-8 -*-

import sys

data = sys.stdin.readlines()

n, m, c0, d0 = map(int, data[0].split())

a = [0]
b = [0]
c = [0]
d = [0]

for i in xrange(1, m + 1):
    da, db, dc, dd = map(int, data[i].split())
    a.append(da)
    b.append(db)
    c.append(dc)
    d.append(dd)

dp = []      # n x m
for i in xrange(0, n + 1): dp.append([ 0 for j in xrange(0, m+1)])

for i in xrange(0, n + 1):
    for j in xrange(1, m + 1):
        for k in xrange(0, a[j]/b[j] + 1):
            if i - c[j]*k >= 0:
                dp[i][j] = max(dp[i][j], dp[i-c[j]*k][j-1] + d[j]*k)

#for i in xrange(0, n):
#    for j in xrange(0, m+1):
#        print "%3s " % dp[i][j],
#    print
#print

tugrics = 0
for k in xrange(0, n + 1):
    tugrics = max(tugrics, dp[k][m] + ((n-k)/c0)*d0)

print tugrics

import sys

sys.setrecursionlimit(10 ** 6)

def pyes_no(condition) :
  if condition :
    print ("YES")
  else :
    print ("NO")

def plist(a, s = ' ') :
  print (s.join(map(str, a)))

def rint() :
  return int(sys.stdin.readline())

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

def rfield(n, m = None) :
  if m == None :
    m = n

  field = []
  for i in xrange(n) :
    chars = sys.stdin.readline().strip()
    assert(len(chars) == m)
    field.append(chars)
  return field

def pfield(field, separator = '') :
  print ('\n'.join(map(lambda x: separator.join(x), field)))

def check_field_equal(field, i, j, value) :
  if i >= 0 and i < len(field) and j >= 0 and j < len(field[i]) :
    return value == field[i][j]
  return None

def digits(x, p) :
  digits = []
  while x > 0 :
    digits.append(x % p)
    x //= p
  return digits

def modpower(a, n, mod) :
  r = a ** (n % 2)
  if n > 1 :
    r *= modpower(a, n // 2, mod) ** 2
  return r % mod

def gcd(a, b) :
  if a > b :
    a, b = b, a

  while a > 0 :
    a, b = b % a, a

  return b

n, m, c0, d0 = rints()
n += 1

prev = [0] * n
for i in range((n - 1) / c0 + 1) :
  prev[i * c0] = i * d0

for i in range(m) :
  new = prev[:]
  a, b, c, d = rints()
  for start in range(n) :
    for bake in range(1, min((n - start - 1) / c + 1, a / b + 1)) :
      new[start + bake * c] = max(new[start + bake * c], prev[start] + bake * d, prev[start + bake * c])

  prev = new

print max(prev)

n = [int(i) for i in raw_input().split()]
ab = [[0,0] for i in xrange(n[1])]
cd = [[0,0] for i in xrange(n[1])]
for i in xrange(n[1]):
	x = [int(j) for j in raw_input().split()]
	ab[i][0] = x[0];ab[i][1] = x[1];cd[i][0] = x[2];cd[i][1] = x[3]
dp = [[0 for i in xrange(n[1])] for j in xrange(n[0] + 1)]
for i in xrange(1,n[0] + 1):
	for j in xrange(0,n[1]):
		sum1 = 0
		for k in xrange(0,ab[j][0]//ab[j][1] + 1):
			if(  i >= k * cd[j][0]):
				ol = 0
				if(j>=1):
					ol = dp[i - k*cd[j][0]][j - 1]
				sum1 = max(sum1,k*cd[j][1] +  ol)
		sum2 = 0
		if(j>=1):
			sum2 = dp[i][j - 1]
		#print(sum1,sum2)
		dp[i][j] = max(sum1,sum2)
maximum = 0
for i in xrange(n[0] + 1):
	maximum = max(maximum,dp[i][n[1] - 1] + (n[0] - i)//n[2] * n[3])
print(maximum)

n, m, c0, d0 = list(map(int, input().split()))

A, B, C, D = [0], [0],[0],[0]
for _ in range(m):
	a, b, c, d = list(map(int, input().split()))
	A.append(a); B.append(b); C.append(c), D.append(d);

# max money from i gram and using 1...j items.
dp = [[0]*(m+1) for _ in range(n+1)]

for i in range(n+1):
	dp[i][0] = (i//c0)*d0

for i in range(1, n+1):
	for j in range(1, m+1):

		for k in range(A[j]//B[j] + 1):
			if (i - k*C[j] >= 0):
				dp[i][j] = max( dp[i - k*C[j] ] [j-1] + k*D[j],  dp[i][j])

		dp[i][j] = max(dp[i][j], dp[i][j-1])

print(dp[n][m])

from sys import stdin
from math import floor

buf = []
for line in stdin:
    buf.append(line.strip())
buf.reverse()

def getints():
    return tuple([int(e) for e in buf.pop().split()])

n, m, c, d = getints()
dat = [0 for i in range(n+1)]
for k in range(n/c+1):
    dat[k*c] = k*d
for i in range(m):
    a, b, c, d = getints()
    for j in reversed(range(n)):
        for k in range(min((n-j)/c, a/b)+1):
            q = j+k*c
            dat[q] = max(dat[q], dat[j]+k*d)

print max(dat)

import sys
from sys import stdin, stdout
def R():
    return map(int, stdin.readline().strip().split())

n, m, c, d = R()

arr1 = []
for i in range(n//c):
    arr1.append((c, d))
for i in range(m):
    a, b, c, d = R()
    for j in range(min(a//b, n//c)):
        arr1.append((c, d))

dp = [[0 for i in range(n+1)] for i in range(len(arr1))]
if len(dp) == 0:
    print(0)
    exit()
for i in range(len(arr1)):
    c, d = arr1[i-1]
    for w in range(n+1):
        dp[i][w] = dp[i-1][w]
        if w >= c:
            if dp[i-1][w-c] + d > dp[i][w]:
                dp[i][w] = dp[i-1][w-c] + d
# print(dp, arr1)
stdout.write(str(dp[-1][-1]))
# print(arr1)
# for i in dp:
#     print(i)

# 106C

def do():
    n, m, c0, d0 = map(int, input().split(" "))
    dp = [0] * (n + 1)
    for i in range(c0, n + 1):
        dp[i] = i // c0 * d0
    for _ in range(m):
        a, b, c, d = map(int, input().split(" "))
        for i in range(n, c - 1, -1):
            for j in range(1, a // b + 1):
                if i >= j * c:
                    dp[i] = max(dp[i], dp[i - j * c] + j * d)
    return dp[-1]

print(do())

n,m,c0,d0=map(int,input().split(" "))
a,b,c,d=[0],[0],[0],[0]

for i in range(m):
    x,y,z,e=map(int,input().split(" "))
    a.append(x)
    b.append(y)
    c.append(z)
    d.append(e)

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

for i in range(n+1):
    for j in range(1,m+1):
        mx=0
        for k in range(a[j]//b[j]+1):
            if i>=c[j]*k:
                mx=max(dp[i-c[j]*k][j-1] + d[j]*k,mx)
        dp[i][j]=mx
ans=0

for i in range(n+1):
    ans=max(ans,dp[i][m]+((n-i)//c0)*d0)

print(ans)

# n grams of dough
# m stuffings
# a[i] grams left of stuffing i
# b[i] grams needed
# c[i] grams of dough
# d[i] price
#
# without stuffing: (special case)
# a0 = infinite
# b0 = 0
# c0 grams of dough
# d0 price
# maximize price over all buns

# at each step a choice of 1..k of m-th stuffings or no stuffing
#
# IH: we know how to find the max profit for dough n-1 and stuffings S[]
#
def f(n, a, b, c, d):
    m = len(a)
    P = [[-1] * m for _ in range(n + 1)] # n * m

    def rec(weight, index):
        if index < 0: return 0

        # memoization
        if P[weight][index] != -1:
            return P[weight][index]

        profit = 0

        # we can create at most a[i] // b[i] stuffings
        stuffing, count = 0, 0
        while stuffing <= a[index]:
            remains = weight - (count * c[index])

            # not enough dough
            if remains < 0:
                break

            prev_profit = rec(remains, index - 1)

            profit = max(profit, prev_profit + count * d[index])

            # try more stuffing
            stuffing += b[index]
            count += 1

        P[weight][index] = profit

        return profit

    ans = rec(n, m - 1)
    return ans

inf = float("inf")
A = [inf, 7,  12 ]
B = [1,   3,   3 ]
C = [2,   2,   1 ]
D = [1,  100, 10 ]
assert f(10, A, B, C, D) == 241

n, m, c0, d0 = map(int, input().split())
a, b, c, d = [inf], [0], [c0], [d0]
for _ in range(m):
    _a, _b, _c, _d = map(int, input().split())
    a.append(_a)
    b.append(_b)
    c.append(_c)
    d.append(_d)

ans = f(n, a, b, c, d)
print(ans)

#!/usr/bin/env python
"""(c) gorlum0 [at] gmail.com"""
import itertools as it
from sys import stdin

for line in stdin:
    n, m, c0, d0 = map(int, line.split())

    xss = [map(int, next(stdin).split()) for _ in xrange(m)]
    xss.insert(0, [0]*4)
    a, b, c, d = zip(*xss)
    ## print a, b, c, d

    dp = [[0]*(m+1) for n in xrange(n+1)]
    for i in xrange(n+1):
        for j in xrange(1, m+1):
            dp[i][j] = max(dp[i-c[j]*k][j-1] + d[j]*k \
                            for k in xrange(a[j]//b[j]+1) if i-c[j]*k >= 0)
    print max(dp[k][m] + (n-k)//c0 * d0 for k in xrange(n+1))

from sys import stdin

n, m, c0, d0 = map(int, next(stdin).split())

xss = [map(int, next(stdin).split()) for _ in xrange(m)]
xss.insert(0, [0]*4)
a, b, c, d = zip(*xss)

dp = [[0]*(m+1) for n in xrange(n+1)]
for i in xrange(n+1):
    for j in xrange(1, m+1):
        dp[i][j] = max(dp[i-c[j]*k][j-1] + d[j]*k \
                        for k in xrange(a[j]//b[j]+1) if i-c[j]*k >= 0)
print max(dp[k][m] + (n-k)//c0 * d0 for k in xrange(n+1))

str = raw_input()
arr = [int(s) for s in str.split(' ')]
pir = range(arr[1])
ans = range(arr[0]+1)
for i in range(0, arr[1]):
   str = raw_input()
   pir[i] = [int(s) for s in str.split(' ')]
for i in range (0, arr[0]+1):
    ans[i] = (i / arr[2])*arr[3]

for j in range(0, arr[1]):
 mx = pir[j][0]/pir[j][1]
 for i in range(arr[0],-1, -1):
   if i / pir[j][2] < mx:
      am = i / pir[j][2]
   else:
      am = mx
   while am > 0:
      k = am * pir[j][2]
      if ans[i] < ans[i-k]+am*pir[j][3]:
         ans[i] = ans[i-k]+am*pir[j][3]
      am -= 1
print ans[arr[0]]

from sys import stdin, setrecursionlimit

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():
    ans = 0
    for j in range(len(arr)):
        mem[j][n] = 0

    if arr:
        if n - arr[0][0] >= 0:
            mem[0][n - arr[0][0]] = arr[0][1]

        for j in range(1, len(arr)):
            for i in range(n + 1):
                mem[j][i] = mem[j - 1][i]

                if i + arr[j][0] <= n:
                    if mem[j - 1][i + arr[j][0]] != -1:
                        mem[j][i] = max(mem[j][i], mem[j - 1][i + arr[j][0]] + arr[j][1])
                        ans = max(ans, mem[j][i])

    # print(dp(0, n))
    for j in range(len(arr) + 1):
        for i in range(n, -1, -1):
            ext = (i // c0) * d0
            if mem[j][i] == -1:
                mem[j][i] = ext
            else:
                mem[j][i] += ext
            ans = max(ans, mem[j][i])
    print(ans)

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

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

    mem = [[-1 for i in range(n + 1)] for j in range(len(arr) + 1)]
    main()

r=lambda:map(int,raw_input().split())
[n,m,c0,d0]=r()
cnt=[1000]
c=[c0]
d=[d0]
for i in range(m):
	[a,b,c1,d1]=r()
	cnt+=[a/b]
	c+=[c1]
	d+=[d1]
l=[-1]*(n+1)
l[0]=0
for i in range(m+1):
	for k in xrange(n,-1,-1):
		for j in xrange(cnt[i]+1):
			ind=k+j*c[i]
			if l[k]!=-1 and ind<=n:
				l[ind] = max(l[ind],l[k]+j*d[i])
print max(l)

n,m,c,d=map(int,raw_input().split())
arr=[0]*1001
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]

n, m, c, d = map(int, raw_input().split())
arr = [0] * 1001
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]

import sys # sys.exit() quit()
R = lambda: map(int, raw_input().split())
#sys.stdin = open('input.txt','r'); sys.stdout = open('output.txt','w')

v=[0] * 1010
n,m,c0,d0 = R()

for i in xrange(c0,n+1):
    v[i] = v[i-c0]+d0
a=[0]*20
b=[0]*20
c=[0]*20
d=[0]*20
for _ in xrange(m):
    a[_],b[_],c[_],d[_]=R()
    for i in xrange(a[_]/b[_]):
        for j in xrange(n,c[_]-1,-1):
            v[j]=max(v[j],v[j-c[_]]+d[_])
print v[n]

#Copied

n,m,c,d=map(int,input().split())
dp=[[0 for i in range(n+1)] for j in range(m+1)]
for i in range(1,n+1):
    if(i<c):dp[0][i]=dp[0][i-1]
    else:dp[0][i]=max(dp[0][i-c]+d,dp[0][i-1])
for i in range(1,m+1):
    a,b,c,d=map(int,input().split())
    for j in range(1,n+1):
        if(j<c):
            dp[i][j]=dp[i-1][j]
        else:
            for k in range(a//b+1):
                if(k*c<=j):dp[i][j]=max(dp[i][j],dp[i-1][j-k*c]+k*d)
                else:break
print(dp[m][n])

mikla, types, c0, d0 = map(int, input().split())
pieejamais = [0];pildijumapaterins = [0];miklaspaterins = [0];cena = [0]
for recepte in range(types):
    a, b, c, d = map(int, input().split())
    pieejamais.append(a);pildijumapaterins.append(b);miklaspaterins.append(c);cena.append(d)

tabula = [[0 for t in range(types + 1)] for m in range(mikla + 1)]
for n in range(mikla + 1):
    tabula[n][0] = (n // c0) * d0
for miklasdaudz in range(1, mikla + 1):
    for pildijumi in range(1, types + 1):
        maxx = 0
        for k in range(pieejamais[pildijumi] // pildijumapaterins[pildijumi] + 1):
            if miklasdaudz - miklaspaterins[pildijumi] * k >= 0:
                izmantotamikla = k * miklaspaterins[pildijumi]
                atlikusimikla = miklasdaudz - izmantotamikla
                pelna = cena[pildijumi] * k
                s = tabula[atlikusimikla][pildijumi - 1]
                if pelna + s > maxx:
                    maxx = pelna + s
        tabula[miklasdaudz][pildijumi] = maxx
print(tabula[mikla][types])

n, m, c, d = map(int, raw_input().split())
t = [(d / c, 1000, c, d)] + [0] * m
for i in range(1, m + 1):
    a, b, c, d = map(int, raw_input().split())
    t[i] = (float(d) / c, a / b, c, d)
t.sort(reverse = True)
s, p = [0], [0] * (n + 1)
for i in range(m + 1):
    x, k, c, d = t[i]
    for j in range(k):
        r = []
        for x in s:
            y = x + c
            if y > n: break
            if p[y] < p[x] + d:
                p[y] = p[x] + d
                r.append(y)
        if not r: break
        s = r
    x, s = 0, [0]
    for i in range(1, n + 1):
        if p[i] > x:
            s.append(i)
            x = p[i]
        else: p[i] = x
print p[n]

import sys
def read_values():
  return map(int,raw_input().split())

n,m,c0,d0=read_values()
a = [0]+[0]*m
b = [0]+[0]*m
c = [c0]+[0]*m
d = [d0]+[0]*m
for i in range(1,m+1):
  a[i],b[i],c[i],d[i]=read_values()

res = [[0]*(n+1) for i in range(m+1)]
for N in range(n+1):
  res[0][N] = d[0]*(N/c[0])

for i in range(1,m+1):
  num=0
  while num*b[i]<=a[i] and num*c[i]<=n:
    for N in range(num*c[i],n+1):
      res[i][N] = max(res[i][N], res[i-1][N-num*c[i]]+num*d[i])
    num+=1

print res[m][n]

import functools

# The first line contains 4 integers n, m, c0 and d0 (1 ≤ n ≤ 1000, 1 ≤ m ≤ 10, 1 ≤ c0, d0 ≤ 100).
# Lavrenty has n grams of dough as well as m different stuffing types
# he can make buns without stuffings. Each of such buns requires c0 grams of dough and it can be sold for d0 tugriks
N, M, c0, d0 = map(int, input().split())

# Each of the following m lines contains 4 integers. The i-th line contains numbers ai, bi, ci and di (1 ≤ ai, bi, ci, di ≤ 100)
#  he has ai grams left of the i-th stuffing. It takes exactly bi grams of stuffing i and ci grams of dough to cook a bun with the i-th stuffing.
#  Such bun can be sold for di tugriks
recipes = []
available_filling = [0]
filling_consumption = [0]
dough_consumption = [0]
price = [0]
for m in range(M):
    ai,bi,ci,di = map(int, input().split())
    available_filling.append(ai)
    filling_consumption.append(bi)
    dough_consumption.append(ci)
    price.append(di)
    rec = (ai,bi,ci,di)
    recipes.append(rec)

# Let create array dp by size n x m. dp[i][j] means maximum number of tugriks that the baker can earn
# if he used i grams of dough and cook buns with stuffings of types 1..j.
#
# Initially dp[i][0] is 0 for all i.
#
# You can easily calculate this dp:
# dp[i][j] = max{ dp[ i-c[j]*k ][ j-1 ] + d[j]*k } for every k from 0 to a[j]/b[j], for which i-c[j]*k>=0

dp = [[0 for m in range(M + 1)] for n in range (N + 1)]
for n in range(N+1):
    dp[n][0] = (n // c0) * d0

for dough in range(1, N+1):
    for fill_considered in range(1, M+1):
        m = 0
        for k in range(available_filling[fill_considered] // filling_consumption[fill_considered] + 1):
            if dough-dough_consumption[fill_considered]*k>=0:
               prevdough = dough - dough_consumption[fill_considered] * k
               prevstuff = fill_considered - 1
               addition = price[fill_considered] * k
               m = max(m, dp[prevdough][prevstuff] + addition)
        dp[dough][fill_considered] = m

print(dp[N][M])

n, m, c, d = map(int, raw_input().split())
arr = [0]*1010

for i in range(c, n+1):
	arr[i] = arr[i-c] + d

for l in range(m):
	#get each description
	a, b, c, d = map(int, raw_input().split())
	for i in range(0, a/b):
		j = n	#maximum dough that I can use is n
		while j >= c:
			arr[j] = max(arr[j], arr[j-c] + d)
			j -= 1

print arr[n]

import sys
input=sys.stdin.readline
n,m,c0,d0=map(int,input().split())
maxi=(n//c0)*d0
dp=[[0 for i in range(n+1)] for j in range(m+1)]
i=1
while i*c0<=n:
    dp[0][i*c0]=i*d0
    i+=1
for i in range(1,m+1):
    a,b,c,d=map(int,input().split())
    for j in range(n+1):
        k=0
        while k*c+j<=n and b*k<=a:
            dp[i][k*c+j]=max(dp[i][k*c+j],max(dp[i-1][k*c+j],dp[i-1][j]+k*d))
            k+=1
    for j in range(n+1):
        dp[i][j]=max(dp[i][j],dp[i-1][j])

for i in range(m+1):
    for j in range(n+1):
        maxi=max(maxi,dp[i][j])
print(maxi)

inp = lambda: map(int, input().split())

n, m, c0, d0 = inp()

a = [0]
b = [0]
c = [0]
d = [0]

for i in range(m):
  ai, bi, ci, di = inp()
  a.append(ai)
  b.append(bi)
  c.append(ci)
  d.append(di)

dp = [[0 for _ in range(n+1)] for _ in range(m+1)]

for i in range(n+1):
  dp[0][i] = (i//c0)*d0

for i in range(1, m+1):
  for j in range(1, n+1):
    for k in range((a[i]//b[i])+1):  #maximum buns made with stuffing
      if j - (k*c[i]) >= 0:  #array boundary check
        dp[i][j] = max(dp[i][j], dp[i-1][j-(k*c[i])] + k*d[i])

print(dp[m][n])

R = lambda: map(int, input().split())
n, m, c0, d0 = R()
a, b, c, d = [0], [0], [0], [0]
for i in range(m):
    t1, t2, t3, t4 = R()
    a.append(t1)
    b.append(t2)
    c.append(t3)
    d.append(t4)
dp = [[0] * (n + 1) for i in range(m + 1)]
for j in range(n + 1):
    dp[0][j] = j // c0 * d0
for i in range(1, m + 1):
    for j in range(1, n + 1):
        x = 0
        dp[i][j] = dp[i - 1][j]
        while j >= x * c[i] and a[i] >= b[i] * x:
            dp[i][j] = max(dp[i][j], dp[i - 1][j - x * c[i]] + x * d[i])
            x += 1
print(dp[m][n])

n,m,c0,d0 = map(int, raw_input().strip().split())

z = [n] +  [0]*(m+1)
c = [c0] + [0]*(m+1)
d = [d0] + [0]*(m+1)
for i in range(1, m+1):
    a,b,c[i],d[i]=map(int, raw_input().strip().split())
    z[i] = a//b
ans = 0

# dp[j][i] := max gain up to i, using j grams of dough
# = max_{k from 0 up to max(z[i], j // c[i])} {k*d[i] + dp[j - k*c[i]][i-1], dp[j][i-1]}
dp = [[0] * (m+1) for _ in range(n+1)]
for j in range(n+1):
    dp[j][0] = (j//c[0])*d[0]
    for i in range(1, m+1):
        dp[j][i] = dp[j][i-1]
        for k in range(min(z[i], j // c[i])+1):
            g  = k*d[i] + dp[j-k*c[i]][i-1]
            dp[j][i] = max(g, dp[j][i])

print max([dp[j][m] for j in range(n+1)])

n, m, c, d = map(int, input().split())
arr = [0]*1010
for i in range(c, n+1):
    arr[i] = arr[i-c] + d
for l in range(m):
    a, b, c, d = map(int, 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,c0,d0=map(int,input().split()) # testo, kol nac, test bez nac, pribil
dp=[]
for i in range(n+1): dp.append(i//c0*d0)
for i in range(m):
    a,b,c,d=map(int,input().split())#ost nach, need nach, need tes, pribil
    for j in range(1,a//b+1):
        for k in range(n,c-1,-1):
            dp[k]=max(dp[k],dp[k-c]+d)
print(dp[n])

#!/usr/bin/env python3

n, m, c0, d0 = map(int, input().rstrip().split())
cnt, c, d = [n//c0], [c0], [d0]

for i in range(m):
    ai, bi, ci, di = map(int, input().rstrip().split())
    cnt_i = min(n//ci, ai//bi)
    cnt.append(cnt_i)
    c.append(ci)
    d.append(di)

def binarize(v):
    b = 0
    while (b << 1) + 1 <= v:
        b = (b << 1) + 1  # 111..
        yield (b + 1) >> 1  # 111... + 1 = 1000...

    if b < v:
        yield v - b

dp = [0] * (n+1)
for i in range(m+1):
    for sub_cnt in binarize(cnt[i]):
        dough, gain = sub_cnt * c[i], sub_cnt * d[i]
        for pos in range(n, dough-1, -1):
            dp[pos] = max(dp[pos], dp[pos-dough] + gain)

print(dp[n])

n,m,c,d=map(int,input().split())
ar=[0]*1005
for i in range(c,n+1):
    ar[i]=ar[i-c]+d
for i in range(m):
    a,b,c,d=map(int,input().split())
    for j in range(a//b):
        e=n
        while(e>=c):
            ar[e]=max(ar[e],ar[e-c]+d)
            e-=1
print(ar[n])

n,m,c0,d0 = [int(j) for j in input().split()]
nach = []
nach.append([0,0,c0,d0])
for i in range(m):
    nach.append([int(j) for j in input().split()])

profit = []
nabor = [[0] * (m+1) for i in range(n+1)]
profit = [0] * (n+1)
for nn in range(1,n+1):
    for j in range(m+1):
        if nn - nach[j][2] >= 0:
            if (nabor[nn - nach[j][2]][j] + 1) * nach[j][1] <= nach[j][0] and profit[nn-nach[j][2]]+nach[j][3] > profit[nn]:
                profit[nn] = profit[nn-nach[j][2]]+nach[j][3]
                for k in range(m+1):
                    nabor[nn][k] = nabor[nn - nach[j][2]][k]
                nabor[nn][j] += 1
MaxProfit = 0
for i in range(n+1):
    if MaxProfit < profit[i]:
        MaxProfit = profit[i]

print(MaxProfit)

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

t = [(d / c, 1000, 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)

s, p = [0], [0] * (n + 1)

for i in range(m + 1):

    x, k, c, d = t[i]

    for j in range(k):

        r = []

        for x in s:

            y = x + c

            if y > n: continue

            if p[y] < p[x] + d:

                p[y] = p[x] + d

                r.append(y)

        if not r: break

        s = r

    x, s = 0, [0]

    for i in range(1, n + 1):

        if p[i] > x:

            s.append(i)

            x = p[i]

        else: p[i] = x

print(p[n])

# Made By Mostafa_Khaled

n,m,c0,d0=map(int,input().split())
lst=[(d0/c0,1000,c0,d0)]
for _ in range(m):
    a,b,c,d=map(int,input().split())
    lst.append((d/c,a//b,c,d))
lst.sort(reverse=True)
ind,res=[0],[0]*(n+1)
for _,(x,k,c,d) in enumerate(lst):
    for i in range(k):
        new=[]
        for j,y in enumerate(ind):
            if y+c>n:continue
            if res[y]+d>res[y+c]:
                res[y+c]=res[y]+d
                new.append(y+c)
        if new==[]:break
        ind=new[:]
    ind,elem=[0],0
    for i,x in enumerate(res):
        if x>elem:
            elem=x
            ind.append(i)
        else:res[i]=elem
print(res[-1])

N,M,A,B = map(int,raw_input().split())
dp = [0 for x in range(N+1)]
for i in range(M):
    a,b,c,d = map(int,raw_input().split())
    for j in range(N-1,-1,-1):
        for k in range(1,a/b+1):
            if k*c+j>N:
                continue
            dp[k*c+j] = max(dp[k*c+j],dp[j]+d*k)
ans = 0
for i in range(N+1):
    ans = max(ans,dp[i]+(N-i)/A*B)
print ans

import sys
input = sys.stdin.readline

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

 # dp[grams_of_dough][1..j stuffings]
dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]

# grams left, grams required, dough required, sell price
stuffing = [(0, 1, 0, 0)] + [map(int, input().split()) for _ in range(m)]

for i in range(0, n + 1):
  for j in range(1, m + 1):
    # attempt to make k of j-stuffed thingies
    for k in range(stuffing[j][0] / stuffing[j][1] + 1):
      if i - stuffing[j][2] * k > -1:
        dp[i][j] = max(dp[i - stuffing[j][2] * k][j - 1] + stuffing[j][3] * k, dp[i][j])

ans = 0
# for row in dp: print row
for k in range(n):
  ans = max(ans, dp[k][m] + ((n - k) / c_0) * d_0)

print ans

from sys import stdin

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

n, m, c0, d0 = arr_inp(1)
staff, percent, ans = [arr_inp(1) for i in range(m)], [[0, d0 / c0]], 0

for i in range(m):
    percent.append([i + 1, staff[i][-1] / staff[i][-2]])

percent.sort(reverse=True, key=lambda x: x[1])

for i, j in percent:
    if i:
        val = min(staff[i - 1][0] // staff[i - 1][1], n // staff[i - 1][2])
        ans += staff[i - 1][-1] * val
        n -= val * staff[i - 1][2]
    else:
        ans += d0 * (n // c0)
        n -= (n // c0) * c0

    # print(n, i, ans)

print(ans)

import sys

sys.setrecursionlimit(10 ** 6)

def pyes_no(condition) :
  if condition :
    print ("YES")
  else :
    print ("NO")

def plist(a, s = ' ') :
  print (s.join(map(str, a)))

def rint() :
  return int(sys.stdin.readline())

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

def rfield(n, m = None) :
  if m == None :
    m = n

  field = []
  for i in xrange(n) :
    chars = sys.stdin.readline().strip()
    assert(len(chars) == m)
    field.append(chars)
  return field

def pfield(field, separator = '') :
  print ('\n'.join(map(lambda x: separator.join(x), field)))

def check_field_equal(field, i, j, value) :
  if i >= 0 and i < len(field) and j >= 0 and j < len(field[i]) :
    return value == field[i][j]
  return None

def digits(x, p) :
  digits = []
  while x > 0 :
    digits.append(x % p)
    x //= p
  return digits

def modpower(a, n, mod) :
  r = a ** (n % 2)
  if n > 1 :
    r *= modpower(a, n // 2, mod) ** 2
  return r % mod

def gcd(a, b) :
  if a > b :
    a, b = b, a

  while a > 0 :
    a, b = b % a, a

  return b

n, m, c0, d0 = rints()
n += 1

prev = [0] * n
for i in range((n - 1) / c0 + 1) :
  prev[i * c0] = i * d0

for i in range(m) :
  new = prev[:]
  a, b, c, d = rints()
  for start in range(n) :
    for bake in range(1, min((n - start - 1) / c + 1, a / b + 1)) :
      new[start + bake * c] = max(new[start + bake * c], prev[start] + bake * d)

  prev = new
print prev[-1]

import sys
from sys import stdin, stdout
def R():
    return map(int, stdin.readline().strip().split())

n, m, c, d = R()

arr1 = []
for i in range(n//c):
    arr1.append((c, d))
for i in range(m):
    a, b, c, d = R()
    for j in range(min(a//b, n//c)):
        arr1.append((c, d))

dp = [[0 for i in range(n+1)] for i in range(len(arr1))]
if len(dp) == 0:
    print(0)
    exit()
for i in range(len(arr1)):
    c, d = arr1[i-1]
    for w in range(n+1):
        dp[i][w] = dp[i-1][w]
        if w >= c:
            if dp[i-1][w-c] + d > dp[i][w]:
                dp[i][w] = dp[i-1][w-c] + d
print(dp, arr1)
stdout.write(str(dp[-1][-1]))
# print(arr1)
# for i in dp:
#     print(i)

# n grams of dough
# m stuffings
# a[i] grams left of stuffing i
# b[i] grams needed
# c[i] grams of dough
# d[i] price
#
# without stuffing: (special case)
# a0 = infinite
# b0 = 0
# c0 grams of dough
# d0 price
# maximize price over all buns

# at each step a choice of 1..k of m-th stuffings or no stuffing
#
# IH: we know how to find the max profit for dough n-1 and stuffings S[]
#
def f(n, a, b, c, d):
    m = len(a)
    P = [[-1] * m for _ in range(n + 1)] # n * m

    def rec(weight, index):
        if index < 0: return 0

        # memoization
        if P[weight][index] != -1:
            return P[weight][index]

        profit = 0

        # we can create at most a[i] // b[i] stuffings
        stuffing, count = 0, 0
        while stuffing <= a[index]:
            remains = weight - (count * c[index])

            # not enough dough
            if remains < 0:
                break

            prev_profit = rec(remains, index - 1)

            profit = max(profit, prev_profit + count * d[index])

            # try more stuffing
            stuffing += b[index]
            count += 1

        return profit

    ans = rec(n, m - 1)
    print(ans)
    return ans

inf = float("inf")
A = [inf, 7,  12 ]
B = [1,   3,   3 ]
C = [2,   2,   1 ]
D = [1,  100, 10 ]
assert f(10, A, B, C, D) == 241

n, m, c0, d0 = map(int, input().split())
a, b, c, d = [inf], [0], [c0], [d0]
for _ in range(m):
    _a, _b, _c, _d = map(int, input().split())
    a.append(_a)
    b.append(_b)
    c.append(_c)
    d.append(_d)

ans = f(n, a, b, c, d)
print(ans)

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():
    ans = 0
    for j in range(len(arr)):
        mem[j][n] = 0

    if arr:
        if arr[0][0] <= n:
            mem[0][n - arr[0][0]] = arr[0][1]

        for j in range(1, len(arr)):
            for i in range(n + 1):
                mem[j][i] = mem[j - 1][i]

                if i + arr[j][0] <= n:
                    if mem[j - 1][i + arr[j][0]] != -1:
                        mem[j][i] = max(mem[j][i], mem[j - 1][i + arr[j][0]] + arr[j][1])
                        ans = max(ans, mem[j][i])

    # print(dp(0, n))
    for j in range(len(arr) + 1):
        for i in range(n, -1, -1):
            ext = (i // c0) * d0
            if mem[j][i] != -1:
                mem[j][i] += ext
            ans = max(ans, mem[j][i])
    print(ans)

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

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

    mem = [[-1 for i in range(n + 1)] for j in range(len(arr) + 1)]
    main()

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():
    ans = 0
    for j in range(len(arr)):
        mem[j][n] = 0

    if arr:
        mem[0][n - arr[0][0]] = arr[0][1]

        for j in range(1, len(arr)):
            for i in range(n + 1):
                mem[j][i] = mem[j - 1][i]

                if i + arr[j][0] <= n:
                    if mem[j - 1][i + arr[j][0]] != -1:
                        mem[j][i] = max(mem[j][i], mem[j - 1][i + arr[j][0]] + arr[j][1])
                        ans = max(ans, mem[j][i])

    # print(dp(0, n))
    for j in range(len(arr) + 1):
        for i in range(n, -1, -1):
            ext = (i // c0) * d0
            if mem[j][i] == -1:
                mem[j][i] = ext
            else:
                mem[j][i] += ext
            ans = max(ans, mem[j][i])
    print(ans)

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

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

    mem = [[-1 for i in range(n + 1)] for j in range(len(arr) + 1)]
    main()

from sys import stdin

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

n, m, c0, d0 = arr_inp(1)
staff, percent, ans = [arr_inp(1) for i in range(m)], [[0, d0 / c0]], 0

for i in range(m):
    percent.append([i + 1, staff[i][-1] / staff[i][-2]])

percent.sort(reverse=True, key=lambda x: x[1])

# print(percent)
for i, j in percent:
    if i:
        val = min(staff[i - 1][0] // staff[i - 1][1], n // staff[i - 1][2])
        ans += staff[i - 1][-1] * val
        n -= val * staff[i - 1][2]
    else:
        ans += d0 * (n // c0)
        n -= (n // c0) * c0

    # print(n, i, ans)

print(ans)

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():
    ans = 0
    for i in range(len(arr)):
        mem[i][n] = 0

    for j in range(len(arr)):
        for i in range(n, -1, -1):

            if mem[j][i] != -1:
                if i - arr[j][0] >= 0:
                    mem[j + 1][i - arr[j][0]] = max(mem[j + 1][i - arr[j][0]], mem[j][i] + arr[j][1])
                    ans = max(ans, mem[j + 1][i - arr[j][0]])

                tem = i
                while tem - c0 >= 0:
                    tem -= c0
                    mem[j + 1][tem] = max(mem[j + 1][tem], mem[j + 1][tem + c0] + d0)
                    ans = max(ans, mem[j + 1][tem])

    # print(dp(0, n))
    if not arr:
        ans = d0 * (n // c0)
    print(ans)

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

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

    mem = [[-1 for i in range(n + 1)] for j in range(len(arr) + 1)]
    main()

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():
    ans = 0
    for i in range(len(arr)):
        mem[i][n] = 0

    for j in range(len(arr)):
        for i in range(n, -1, -1):

            if mem[j][i] != -1:
                if i - arr[j][0] >= 0:
                    mem[j + 1][i - arr[j][0]] = max(mem[j + 1][i - arr[j][0]], mem[j][i] + arr[j][1])
                    ans = max(ans, mem[j + 1][i - arr[j][0]])

                tem = i
                while tem - c0 >= 0:
                    tem -= c0
                    mem[j + 1][tem] = max(mem[j + 1][tem], mem[j + 1][tem + c0] + d0)
                    ans = max(ans, mem[j + 1][tem])

    # print(dp(0, n))
    print(ans)

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

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

    mem = [[-1 for i in range(n + 1)] for j in range(len(arr) + 1)]

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

import functools as ft
mikla, types, c0, d0 = map(int, input().split())
pieejamais = [0];pildijumapaterins = [0];miklaspaterins = [0];cena = [0]
for recepte in range(types):
    a, b, c, d = map(int, input().split())
    pieejamais.append(a);pildijumapaterins.append(b);miklaspaterins.append(c);cena.append(d)

@ft.lru_cache(maxsize=524288)
def izd(miklasdaudz, pildijumi):
    if miklasdaudz == 0:
        return 0
    if pildijumi == 0:
        return (miklasdaudz // c0) * d0
    maxx = 0
    for k in range(pieejamais[pildijumi] // pildijumapaterins[pildijumi] + 1):
        izmantotamikla = k * miklaspaterins[pildijumi]
        atlikusimikla = miklasdaudz - izmantotamikla
        pelna = cena[pildijumi] * k
        s = izd(atlikusimikla, pildijumi - 1)
        if pelna + s > maxx:
            maxx = pelna + s
    return maxx
print(izd(mikla, types))

import functools

# The first line contains 4 integers n, m, c0 and d0 (1 ≤ n ≤ 1000, 1 ≤ m ≤ 10, 1 ≤ c0, d0 ≤ 100).
# Lavrenty has n grams of dough as well as m different stuffing types
# he can make buns without stuffings. Each of such buns requires c0 grams of dough and it can be sold for d0 tugriks
N, M, c0, d0 = map(int, input().split())

# Each of the following m lines contains 4 integers. The i-th line contains numbers ai, bi, ci and di (1 ≤ ai, bi, ci, di ≤ 100)
#  he has ai grams left of the i-th stuffing. It takes exactly bi grams of stuffing i and ci grams of dough to cook a bun with the i-th stuffing.
#  Such bun can be sold for di tugriks
recipes = []
available_filling = [0]
filling_consumption = [0]
dough_consumption = [0]
price = [0]
for m in range(M):
    ai,bi,ci,di = map(int, input().split())
    available_filling.append(ai)
    filling_consumption.append(bi)
    dough_consumption.append(ci)
    price.append(di)
    rec = (ai,bi,ci,di)
    recipes.append(rec)

# Let create array dp by size n x m. dp[i][j] means maximum number of tugriks that the baker can earn
# if he used i grams of dough and cook buns with stuffings of types 1..j.
#
# Initially dp[i][0] is 0 for all i.
#
# You can easily calculate this dp:
# dp[i][j] = max{ dp[ i-c[j]*k ][ j-1 ] + d[j]*k } for every k from 0 to a[j]/b[j], for which i-c[j]*k>=0

@functools.lru_cache()
def dp(dough, fill_considered):
    if dough == 0:
        return 0
    if fill_considered == 0:
        return (dough // c0) * d0
    m = 0
    for k in range(available_filling[fill_considered] // filling_consumption[fill_considered] + 1):
        prevdough = dough - dough_consumption[fill_considered] * k
        prevstuff = fill_considered - 1
        addition = price[fill_considered] * k
        m = max(m, dp(prevdough, prevstuff) + addition)
    return m

print(dp(N, M))

R = lambda: map(int, input().split())
n, m, c0, d0 = R()
a, b, c, d = [0], [0], [0], [0]
for i in range(m):
    t1, t2, t3, t4 = R()
    a.append(t1)
    b.append(t2)
    c.append(t3)
    d.append(t4)
dp = [[0] * (n + 1) for i in range(m + 1)]
for j in range(n + 1):
    dp[0][j] = j // c0 * d0
for i in range(1, m + 1):
    for j in range(1, n + 1):
        x = 0
        while j > x * c[i] and a[i] >= b[i] * x:
            dp[i][j] = max(dp[i][j], dp[i - 1][j - x * c[i]] + x * d[i])
            x += 1
print(dp[m][n])

n,m,c0,d0=map(int,input().split()) # testo, kol nac, test bez nac, pribil
dp=[] # max kol deneg za index testa
for i in range(n+1): dp.append(i//c0*d0)
for i in range(m):
    a,b,c,d=map(int,input().split())#ost nach, need nach, need tes, pribil
    for k in range(n,c-1,-1):
        dp[k]=max(dp[k],dp[k-c]+d)
print(dp[n])

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 - n) // c + 1
        n += c * k
        p -= d * k
print(p)

# -*- coding: utf-8 -*-

import sys

data = sys.stdin.readlines()

n, m, c0, d0 = map(int, data[0].split())

a = [0]
b = [0]
c = [0]
d = [0]

for i in xrange(1, m + 1):
    da, db, dc, dd = map(int, data[i].split())
    a.append(da)
    b.append(db)
    c.append(dc)
    d.append(dd)

dp = []      # n x m
for i in xrange(0, n): dp.append([ 0 for j in xrange(0, m+1)])

for i in xrange(0, n):
    for j in xrange(1, m + 1):
        for k in xrange(0, a[j]/b[j] + 1):
            if i - c[j]*k >= 0:
                dp[i][j] = max(dp[i][j], dp[i-c[j]*k][j-1] + d[j]*k)

#for i in xrange(0, n):
#    for j in xrange(0, m+1):
#        print "%3s " % dp[i][j],
#    print
#print

tugrics = 0
for k in xrange(0, n):
    tugrics = max(tugrics, dp[k][m] + ((n-k)/c0)*d0)

print tugrics

# -*- coding: utf-8 -*-

import sys

data = sys.stdin.readlines()

n, m, c0, d0 = map(int, data[0].split())

a = [0]
b = [0]
c = [0]
d = [0]

for i in xrange(1, m + 1):
    da, db, dc, dd = map(int, data[i].split())
    a.append(da)
    b.append(db)
    c.append(dc)
    d.append(dd)

dp = []      # n x m
for i in xrange(0, n): dp.append([ 0 for j in xrange(0, m+1)])

for i in xrange(0, n):
    for j in xrange(1, m + 1):
        for k in xrange(0, a[j]/b[j] + 1):
            if i + 1 - c[j]*k >= 0:
                dp[i][j] = max(dp[i][j], dp[i-c[j]*k][j-1] + d[j]*k)

#for i in xrange(0, n):
#    for j in xrange(0, m+1):
#        print "%3s " % dp[i][j],
#    print
#print

tugrics = 0
for k in xrange(0, n):
    tugrics = max(tugrics, dp[k][m] + ((n-k)/c0)*d0)

print tugrics

# -*- coding: utf-8 -*-

import sys

data = sys.stdin.readlines()

n, m, c0, d0 = map(int, data[0].split())

a = []
b = []
c = []
d = []

for i in xrange(1, m + 1):
    da, db, dc, dd = map(int, data[i].split())
    a.append(da)
    b.append(db)
    c.append(dc)
    d.append(dd)

dp = []      # n x m
for i in xrange(0, n): dp.append([ 0 for j in xrange(0, m+1)])

for i in xrange(0, n):
    for j in xrange(0, m):
        for k in xrange(0, a[j]/b[j]):
            if i - c[j]*k >= 0:
                dp[i][j+1] = max(dp[i-c[j]*k][j] + d[j]*k, dp[i][j+1])

#for i in xrange(0, n):
#    for j in xrange(0, m+1):
#        print "%3s " % dp[i][j],
#    print

print

tugrics = 0
for k in xrange(0, n):
    tugrics = max(tugrics, dp[k][m] + ((n-k)/c0)*d0)

print tugrics

str = raw_input()
arr = [int(s) for s in str.split(' ')]
pir = []
ans = range(arr[1]+1)
ans[0] = []
for j in range(0, arr[0]+1):
   ans[0].append( (j / arr[2])*arr[3])
for i in range(1, arr[1]+1):
   str = raw_input()
   pir = [int(s) for s in str.split(' ')]
   ans[i] = []
   last = 0
   am = (pir[0]/pir[1])*pir[2]
   for j in range(0, arr[0]+1):
       if(j <= am):
           last = (j / pir[2])*pir[3]
           ans[i].append(last)
       else:
           ans[i].append(last)
taken = []
z = arr[0]
bigA = 0
while True:
   max = -1
   k = -1
   for i in range(0, arr[1]+1):
       b = True
       for j in taken:
           if j == i:
              b = False
              break
       if b == False:
          continue
       if max < ans[i][z]:
            max = ans[i][z]
            k = i
  # print "max", max
 #  print "k", k
   if k == -1:
         break
   taken.append(k)
   bigA += max
   t = -1
   for i in range(0,len(ans[k])):
       if ans[k][i] == max:
         z = z - i
         break
#print "z", z
print bigA

str = raw_input()
arr = [int(s) for s in str.split(' ')]
pir = range(arr[1])
ans = range(arr[0]+1)
for i in range(0, arr[1]):
   str = raw_input()
   pir[i] = [int(s) for s in str.split(' ')]
for i in range (0, arr[0]+1):
    ans[i] = (i / arr[2])*arr[3]

for j in range(0, arr[1]):
 am = pir[j][0]/pir[j][1]
 for i in range(arr[0],-1, -1):
   if i / pir[j][2] < am:
      am = i / pir[j][2]
   k = am * pir[j][2]
   if ans[i] < ans[i-k]+am*pir[j][3]:
      ans[i] = ans[i-k]+am*pir[j][3]
print ans[arr[0]]

str = raw_input()
arr = [int(s) for s in str.split(' ')]
pir = range(arr[1])
ans = range(arr[0]+1)
for i in range(0, arr[1]):
   str = raw_input()
   pir[i] = [int(s) for s in str.split(' ')]
for i in range (0, arr[0]+1):
    ans[i] = (i / arr[2])*arr[3]

for j in range(0, arr[1]):
 am = pir[j][0]/pir[j][1]
 for i in range(arr[0],-1, -1):
   if i / pir[j][2] < am:
      am = i / pir[j][0]
   k = am * pir[j][2]
   if ans[i] < ans[i-k]+am*pir[j][3]:
      ans[i] = ans[i-k]+am*pir[j][3]
print ans[arr[0]]

l = []
n, m, c, d = map(int, raw_input().split())
l.append([0, 0, c, d])
for _ in xrange(m):
    l.append(map(int, raw_input().split()))

l.sort(key = lambda x: float(x[3]) / x[2], reverse = True)
ans = 0
i = 0
while True:
    if l[i][0] >= l[i][1]:
        if n >= l[i][2]:
            l[i][0] -= l[i][1]
            n -= l[i][2]
            ans += l[i][3]
        else:
            break
    else:
        i += 1
print ans

n,m,c0,d0 = map(int, raw_input().strip().split())

z = [n] +  [0]*(m+1)
c = [c0] + [0]*(m+1)
d = [d0] + [0]*(m+1)
for i in range(1, m+1):
    a,b,c[i],d[i]=map(int, raw_input().strip().split())
    z[i] = a//b
    print z[i]
ans = 0

# dp[j][i] := max gain up to i, using j grams of dough
# = max_{k from 0 up to max(z[i], j // c[i])} {k*d[i] + dp[j - k*c[i]][i-1], dp[j][i-1]}
dp = [[0] * (m+1) for _ in range(n+1)]
for j in range(n+1):
    dp[j][0] = (j//c[0])*d[0]
    for i in range(1, m+1):
        dp[j][i] = dp[j][i-1]
        for k in range(min(z[i], j // c[i])+1):
            g  = k*d[i] + dp[j-k*c[i]][i-1]
            dp[j][i] = max(g, dp[j][i])

print max([dp[j][m] for j in range(n+1)])