Problem:
 Score : 300 points    Problem Statement We have two desks: A and B. Desk A has a vertical stack of N books on it, and Desk B similarly has M books on it.  It takes us A_i minutes to read the i -th book from the top on Desk A (1 \leq i \leq N) , and B_i minutes to read the i -th book from the top on Desk B (1 \leq i \leq M) .  Consider the following action:   Choose a desk with a book remaining, read the topmost book on that desk, and remove it from the desk.   How many books can we read at most by repeating this action so that it takes us at most K minutes in total? We ignore the time it takes to do anything other than reading.      Constraints  1 \leq N, M \leq 200000  1 \leq K \leq 10^9  1 \leq A_i, B_i \leq 10^9  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  M  K  A_1  A_2  \ldots  A_N  B_1  B_2  \ldots  B_M       Output Print an integer representing the maximum number of books that can be read.        Sample Input 1 3 4 240
60 90 120
80 150 80 150      Sample Output 1 3  In this case, it takes us 60 , 90 , 120 minutes to read the 1 -st, 2 -nd, 3 -rd books from the top on Desk A, and 80 , 150 , 80 , 150 minutes to read the 1 -st, 2 -nd, 3 -rd, 4 -th books from the top on Desk B, respectively.  We can read three books in 230 minutes, as shown below, and this is the maximum number of books we can read within 240 minutes.   Read the topmost book on Desk A in 60 minutes, and remove that book from the desk.  Read the topmost book on Desk B in 80 minutes, and remove that book from the desk.  Read the topmost book on Desk A in 90 minutes, and remove that book from the desk.        Sample Input 2 3 4 730
60 90 120
80 150 80 150      Sample Output 2 7       Sample Input 3 5 4 1
1000000000 1000000000 1000000000 1000000000 1000000000
1000000000 1000000000 1000000000 1000000000      Sample Output 3 0  Watch out for integer overflows.

Solution (Python):
import sys, re, os
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians, acos, atan, asin, log, log10, gcd
from itertools import permutations, combinations, product, accumulate, combinations_with_replacement
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits

from decimal import *
import heapq
def debug(*args):
    if debugmode:
        print(*args)
def input(): return sys.stdin.readline().strip()
def STR(): return input()
def INT(): return int(input())
def FLOAT(): return float(input())
def MAP(): return map(int, input().split())
def S_MAP(): return map(str, input().split())
def LIST(): return list(map(int, input().split()))
def S_LIST(): return list(map(str, input().split()))
def lcm(a, b): return a * b // gcd(a, b)
sys.setrecursionlimit(10 ** 9)
inf = sys.maxsize
mod = 10 ** 9 + 7
dx = [0, 1, 0, -1, 1, -1, -1, 1]
dy = [1, 0, -1, 0, 1, -1, 1, -1]
debugmode = True


def search(arr, num):
    l = 0
    r = len(arr) - 1
    if arr[r] <= num:
        return r
    if arr[l] > num:
        return -1
    while r - l > 1:
        c = (r + l) // 2
        if arr[c] > num:
            r = c
        elif arr[c] < num:
            l = c
        else:
            r = c
            l = c
    return l

n, m, k = MAP()
a = LIST()
b = LIST()
aarr = [a[0]]
for i in range(1, n):
    aarr.append(aarr[-1] + a[i])
barr = [b[0]]
for i in range(1, m):
    barr.append(barr[-1] + b[i])




ans = 0
a_n = 0
b_n = 0
tim = 0
while tim <= k:
    if a_n == -1 and b_n == -1:
        break
    elif a_n == -1:
        pls = b[b_n]
        mode = 1
    elif b_n == -1:
        pls = a[a_n]
        mode = 0
    else:
        tmp1 = k - tim + aarr[a_n - 1] if a_n != 0 else k - tim
        tmp2 = k - tim + barr[b_n - 1] if b_n != 0 else k - tim
        anum = search(aarr, tmp1) - a_n + 1
        bnum = search(barr, tmp2) - b_n + 1
        
        if anum > bnum:
            pls = a[a_n]
            mode = 0
        else:
            pls = b[b_n]
            mode = 1
    
    if tim + pls <= k:
        ans += 1
        tim += pls
        if mode == 0:
            a_n += 1
            if a_n >= n:
                a_n = -1
        else:
            b_n += 1
            if b_n >= m:
                b_n = -1
    else:
        break
print(ans)

Solution (Python):
from bisect import bisect_left
n, m , k = [int(i) for i in input().split()]
A = [int(i) for i in input().split()]
B = [int(i) for i in input().split()]

cum_A = [A[0]]
for i in range(1, n):
    cum_A.append(cum_A[-1]+A[i])
cum_B = [B[0]]
for i in range(1, m):
    cum_B.append(cum_B[-1]+B[i])
ans = 0
for i in range(n+1):
    
    if i == 0:
        target = k
        ind = bisect_left(cum_B, target+0.5)
        ans = max(ans, i+ind)
    else:
        tmp_ans = cum_A[i-1]
        if tmp_ans > k:
            break
        target = k - tmp_ans
        ind = bisect_left(cum_B, target+0.5)
        ans = max(ans, i+ind)
print(ans)

Solution (Python):
from bisect import bisect_right
n, m, k = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))

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

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

ans = bisect_right(b, k)
for i, aa in enumerate(a):
    if aa > k:
        break
    j = bisect_right(b, k-aa)
    ans = max(i+j+1, ans)
print(ans)

Solution (Python):
from itertools import accumulate


def binary(N,T):  
    l, r = -1, N+1
    while r - l > 1:
        if T < b[(l + r) // 2]:  
            r = (l + r) // 2
        else:
            l = (l + r) // 2
    return r-1


n, m, k = map(int, input().split())
a = [0]+list(accumulate(map(int, input().split())))
b = [0]+list(accumulate(map(int, input().split())))

ans = 0
for i, ai in enumerate(a):
    t = k - ai
    if t >= 0:
        j = binary(m, t)
        ans = max(ans, i + j)
print(ans)

Solution (Python):
from bisect import bisect_left, bisect_right

N, M, K = map(int, input().split())
A0 = [int(x) for x in input().split()]
B0 = [int(x) for x in input().split()]

A = [0] * N
B = [0] * M
a = 0
for i in range(N):
    a += A0[i]
    A[i] = a
b = 0
for i in range(M):
    b += B0[i]
    B[i] = b
import sys

answer = max(bisect_right(A, K), bisect_right(B, K))
for a in range(N):
    if A[a] <= K:
        Kb = K - A[a]
        b = bisect_right(B, Kb) 
        
        answer = max(answer, a+b+1)
    else:
        break
print(answer)

Solution (Python):
import sys
readline = sys.stdin.readline

def solve():
    N, M, K = map(int, readline().split())
    A = list(map(int, readline().split()))
    B = list(map(int, readline().split()))

    cum_a = [0] * N
    cum_b = [0] * M
    for i in range(N):
        cum_a[i] = A[i] if i == 0 else A[i] + cum_a[i - 1]
    
    for i in range(M):
        cum_b[i] = B[i] if i == 0 else B[i] + cum_b[i - 1]

    d = 0
    for i in range(N):
        if cum_a[i] <= K:
            d = i + 1
        else:
            break
    

    ans = 0
    e = 0
    while d >= 0:
        rem = K - (cum_a[d - 1] if d != 0 else 0)
        while e < M and cum_b[e] <= rem:
            e += 1
        ans = max(ans, d + e)
        d -= 1
    
    print(ans)

solve()

Solution (Python):
import sys
import bisect
readline = sys.stdin.buffer.readline
def even(n): return 1 if n%2==0 else 0




n,m,k = map(int,readline().split())
lst1 = list(map(int,readline().split()))
lst2 = list(map(int,readline().split()))

def cumsum(lst): 
    res = lst[:]
    for i in range(1,len(res)):
        res[i] += res[i-1]
    return res
lst3 = [0] + cumsum(lst1)
lst4 = cumsum(lst2)


ans = 0
for i in range(0,n+1):
    res = k-lst3[i]
    if res < 0:
        break
    res2 = bisect.bisect_right(lst4,res)
    ans = max(ans,i+res2)

print(ans)

Solution (Python):


import bisect





def solve(N, M, K, As, Bs):
    sum_A = [0]
    max_read_A = 0
    for i in range(N):
        sum_A.append(sum_A[-1] + As[i])
        if sum_A[-1] <= K:
            max_read_A = i + 1
    sum_B = [0]
    max_read_B = 0
    for i in range(M):
        sum_B.append(sum_B[-1] + Bs[i])
        if sum_B[-1] <= K:
            max_read_B = i + 1

    
    

    ans = 0
    for i in range(max_read_A + 1):
        B_read_time = K - sum_A[i]
        B_read_num = bisect.bisect_right(sum_B, B_read_time) - 1
        ans = max(ans, i + B_read_num)
        

    print(ans)

if __name__ == '__main__':
    N, M, K = map(int, input().split())
    As = [int(i) for i in input().split()]
    Bs = [int(i) for i in input().split()]

    
    
    
    
    solve(N, M, K, As, Bs)

Solution (Python):
import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction

sys.setrecursionlimit(int(pow(10,6)))


mod = int(pow(10, 9) + 7)
mod2 = 998244353
def data(): return sys.stdin.readline().strip()
def out(*var, end="\n"): sys.stdout.write(' '.join(map(str, var))+end)
def l(): return list(sp())
def sl(): return list(ssp())
def sp(): return map(int, data().split())
def ssp(): return map(str, data().split())
def l1d(n, val=0): return [val for i in range(n)]
def l2d(n, m, val=0): return [l1d(n, val) for j in range(m)]


t=1

for _ in range(t):
    n,m,k=l()
    A=[0]+l()
    B=[0]+l()
    for i in range(1,m+1):
        B[i]+=B[i-1]
    curr=0
    ma=0
    for i in range(n+1):
        curr+=A[i]
        if curr>k:
            break
        low=0
        high=m
        mab=0
        while(low<=high):
            mid=(low+high)//2
            if B[mid]+curr<=k:
                mab=mid
                low=mid+1
            else:
                high=mid-1
        ma=max(ma,mab+i)
    print(ma)

Solution (Python):
n,m,k=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
t=0

aa=n-1
for i in range(n):
    t+=a[i]
    if t>k:
        aa=i-1
        t-=a[i]
        break
ans=[aa+1]
f=aa+1
s=0
for i in range(m):
    t+=b[i]
    f+=1
    while t>k:
        if aa<0:
            s=1
            f-=1
            break
        else:
            t-=a[aa]
            aa-=1
            f-=1
    ans.append(f)
    if s==1:
        break

print(max(ans))

Solution (Python):
import bisect

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


sa = [0] * (n + 1)
for i in range(n):
  sa[i + 1] = sa[i] + a[i]

sb = [0] * (m + 1)
for j in range(m):
  sb[j + 1] = sb[j] + b[j]

anses = [0]
for i in range(n + 1):
  if sa[i] > k:
    continue
  anses.append(i + bisect.bisect(sb, k - sa[i]) - 1)

print(max(anses))

Solution (Python):
N,M,K = map(int,input().split())
A = list(map(int,input().split()))
B = list(map(int,input().split()))
S = 0
ans = 0
for i in range(M):
  S += B[i]
  if S > K:
    b = i - 1
    S -= B[i]
    break
  else:
    ans += 1
    if i==M-1:
      b = M-1
if b==0:
  ans = 0
  S = 0
  for a in A:
    if S + a <= K:
      S += a
      ans += 1
    else:
      break
  if S + B[0]<=K:
    ans+=1
  print(ans)
else:
  a = 0
  max_ans = ans
  while a<N:
    if S + A[a] <= K:
      S += A[a]
      ans += 1
      a += 1
    else:
      break
  max_ans = max(max_ans, ans)
  for j in range(b, -1, -1):
    S -= B[j]
    ans -= 1
    while a<N:
      if S + A[a] <= K:
        S += A[a]
        ans += 1
        a += 1
      else:
        break
      
    max_ans = max(max_ans, ans)
  print(max_ans)

Solution (Python):
from sys import stdin
from sys import setrecursionlimit
from itertools import accumulate
import bisect

n,m,k = map(int,stdin.readline().rstrip().split())
a = list(map(int,stdin.readline().rstrip().split()))
b = list(map(int,stdin.readline().rstrip().split()))

aa = [0]+list(accumulate(a))
bb = [0]+list(accumulate(b))
ma = 0

for i,j in  enumerate(aa):
    if j > k:
        break
    nowa = i
    nowb = bisect.bisect(bb,k-j)-1
    ma = max(ma,nowa+nowb)

print(ma)

Solution (Python):
def lower_bound(al, key):
    """
    一般に左側が満たしておらず、右側は満たしている判定基準(境目は一つ)ならlower_boundになる
    (条件を満たすもののうち、最小のインデックスを返す)
    単調にさえなっていれば、左右が逆になっていても検索には使える(ng/okも一緒に逆にする必要がある)
    """
    def isOk(a):
        
        
        return a>key

    ng = -1
    ok = len(al)

    while abs(ok-ng)>1:
        mid = (ok+ng)//2

        if isOk(al[mid]):
            ok = mid
        else:
            ng = mid

    return ok

n,m,k = map(int, input().split())
al = list(map(int, input().split()))
bl = list(map(int, input().split()))

acc_a = [0]*(n+1)
acc_b = [0]*(m+1)
for i in range(n):
    acc_a[i+1] = acc_a[i] + al[i]
for i in range(m):
    acc_b[i+1] = acc_b[i] + bl[i]

res = 0

for i in range(n):
    s = acc_a[i+1]
    if s>k:
        continue
    j = lower_bound(acc_b, k-s)

    if j>=0:
        res = max(res, i+1 + j-1)

for i in range(m):
    s = acc_b[i+1]
    if s>k:
        continue
    j = lower_bound(acc_a, k-s)

    if j>=0:
        res = max(res, i+1 + j-1)

print(res)

Solution (Python):
import bisect
n,m,k=map(int,input().split())
A=list(map(int,input().split()))
B=list(map(int,input().split()))
RA=[0]*(n+1)
RB=[0]*(m+1)
for i in range(n):
    RA[i+1]=RA[i]+A[i]
for i in range(m):
    RB[i+1]=RB[i]+B[i]



r=0
for i in range(n+1):
    a=RA[i]
    if k-a>=0:
        j=bisect.bisect_right(RB,k-a)-1
        r=max(r,i+j)
for i in range(m+1):
    b=RB[i]
    if k-b>=0:
        j=bisect.bisect_right(RA,k-b)-1
        r=max(r,i+j)
print(r)

Solution (Python):
import sys
import heapq
import re
from itertools import permutations
from bisect import bisect_left, bisect_right
from collections import Counter, deque
from math import factorial, sqrt, ceil, gcd, cos, radians, floor
from functools import lru_cache, reduce
from decimal import Decimal
INF = 1 << 60
MOD = 1000000007
sys.setrecursionlimit(10 ** 7)


class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

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

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

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

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

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


def dijkstra_heap(s, edge, n):
    
    d = [10**20] * n
    used = [True] * n 
    d[s] = 0
    used[s] = False
    edgelist = []
    for a,b in edge[s]:
        heapq.heappush(edgelist,a*(10**6)+b)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        
        if not used[minedge%(10**6)]:
            continue
        v = minedge%(10**6)
        d[v] = minedge//(10**6)
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,(e[0]+d[v])*(10**6)+e[1])
    return d


def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            arr.append([i, cnt])

    if temp!=1:
        arr.append([temp, 1])

    if arr==[]:
        arr.append([n, 1])

    return arr


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


def lcm_list(numbers):
    return reduce(lcm, numbers, 1)


def gcd_list(numbers):
    return reduce(gcd, numbers)


def is_prime(n):
    if n <= 1:
        return False
    p = 2
    while True:
        if p ** 2 > n:
            break
        if n % p == 0:
            return False
        p += 1
    return True



def eratosthenes(limit):
    A = [i for i in range(2, limit+1)]
    P = []

    while True:
        prime = min(A)
        
        if prime > sqrt(limit):
            break
            
        P.append(prime)
            
        i = 0
        while i < len(A):
            if A[i] % prime == 0:
                A.pop(i)
                continue
            i += 1
            
    for a in A:
        P.append(a)
            
    return P


def permutation_with_duplicates(L):

    if L == []:
        return [[]]

    else:
        ret = []

        
        S = sorted(set(L))

        for i in S:

            data = L[:]
            data.remove(i)

            for j in permutation_with_duplicates(data):
                ret.append([i] + j)

        return ret



def make_ruiseki(x, n):
    ret = [0 for i in range(n)]
    for i in range(n):
        if i == 0:
            ret[i] = x[i]
        else:
            ret[i] = x[i] + ret[i - 1]
    return ret


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

ruiseki_a = make_ruiseki(a, n)
ruiseki_b = make_ruiseki(b, m)

ans = bisect_right(ruiseki_b, k)
for i in range(n):
    c = k - ruiseki_a[i]
    if c < 0:
        break
    index1 = bisect_right(ruiseki_b, c)
    ans = max(ans, index1 + i + 1)
print(ans)

Solution (Python):
import bisect

N , M , K = map ( int , input().strip().split(" ") ) ;
A = list ( map  ( int , input().strip().split(" ") ) ) ;
B = list ( map  ( int , input().strip().split(" ") ) ) ;

A.insert ( 0 , 0 ) ;
B.insert ( 0 , 0 ) ;

for i in range ( 1 , len ( A ) ) :
		A[i] = A[i-1] + A[i] ; 
for i in range ( 1 , len ( B ) ) :
		B[i] = B[i-1] + B[i] ; 



t = 0 ;
for i , v in enumerate ( A ) :
	if v > K : break ;
	x2 = bisect.bisect_right( B , K - v ) ; 
	t = max ( t , x2 - 1 + i ) ;

print ( t ) ;

Solution (Python):
import sys,queue,math,copy,itertools,bisect,collections,heapq

def main():
    sys.setrecursionlimit(10**7)
    INF = 10**18
    MOD = 10**9 + 7
    LI = lambda : [int(x) for x in sys.stdin.readline().split()]
    _LI = lambda : [-int(x) for x in sys.stdin.readline().split()]
    NI = lambda : int(sys.stdin.readline())
    SI = lambda : sys.stdin.readline().rstrip()
    DD = ((1,0),(0,1),(-1,0),(0,-1))

    N,M,K = LI()
    A = LI()
    B = LI()

    xa = 0
    xb = 0

    i = 0
    while xa+A[i] <= K:
        xa += A[i]
        i += 1
        if i >= N:
            break
    ans = i
    k = 0
    for j in range(i-1,-1,-1):
        if k >= M: break
        while xa + B[k] <= K:
            xa += B[k]
            k += 1
            if k >= M:
                break
        ans = max(ans,i+k)
        i -= 1
        xa -= A[i]
    if k < M:
        while xa + B[k] <= K:
            xa += B[k]
            k += 1
            if k >= M: break
    ans = max(ans,i+k)

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
n,m,k=list(map(int,input().split()))
a=list(map(int,input().split()))
b=list(map(int,input().split()))
sa=list(a)
sb=list(b)
s = 0
for i in range(n):
	s+=a[i]
	sa[i]=s

s = 0
for i in range(m):
	s+=b[i]
	sb[i]=s



ans = 0
pt1 = -1
pt2 = m-1
while pt1<n:
	s = 0
	if(pt1!=-1):
		s=sa[pt1]
	while pt2>-1 and (sb[pt2]+s)>k:
		pt2-=1
	if(pt2==-1):
		if(s<=k):
			ans = max(ans,pt1+1+pt2+1)
		
	else:
		ans = max(ans,pt1+1+pt2+1)
	pt1+=1
print(ans)

Solution (Python):
N,M,K = map(int,input().split())
A = list(map(int,input().split()))
B = list(map(int,input().split()))
A.insert(0,0)
B.insert(0,0)
cnt = 0
a = 0
for i in range(N+1):
    a = i
    if cnt + A[i] > K:
        a = i-1
        break
    cnt += A[i]
ans = a


flg = True
for i in range(M+1):
    cnt += B[i]
    if cnt > K:
        while cnt > K:
            if a < 1:
                flg = False
                break
            cnt -= A[a]
            a -= 1
    if flg == True:
        ans = max(ans,a+i)
    if flg == False:
        break
print(ans)

Solution (Python):
N, M, K = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))

tmp = 0
ans = 0
idx = 0
for i in range(N):
    if tmp + A[i] > K:
        break
    tmp += A[i]
    ans += 1
    idx += 1

idx -= 1
max_ans = ans

for i in range(M):
    if tmp + B[i] <= K:
        ans += 1
        max_ans = max(ans, max_ans)
        tmp += B[i]
        continue
    else:
        if idx >= 0:
            tmp -= A[idx]
            ans -= 1
            idx -= 1

        tmp += B[i]
        ans += 1

        if tmp <= K:
            max_ans = max(ans, max_ans)

print(max_ans)

Solution (Python):
import sys
sys.setrecursionlimit(1000000000)
import math
from math import gcd
def lcm(a, b): return a * b // gcd(a, b)
from itertools import count, permutations, chain
from functools import lru_cache
from collections import deque, defaultdict
from pprint import pprint
ii = lambda: int(input())
mis = lambda: map(int, input().split())
lmis = lambda: list(mis())
INF = float('inf')
N1097 = 10**9 + 7

def meg(f, ok, ng):
    while abs(ok-ng)>1:
        mid = (ok+ng)//2
        if f(mid):
            ok=mid
        else:
            ng=mid
    return ok

def get_inv(n, modp):
    return pow(n, modp-2, modp)

def factorials_list(n, modp):    
    fs = [1]
    for i in range(1, n+1):
        fs.append(fs[-1] * i % modp)
    return fs

def invs_list(n, fs, modp):     
    invs = [get_inv(fs[-1], modp)]
    for i in range(n, 1-1, -1):
        invs.append(invs[-1] * i % modp)
    invs.reverse()
    return invs

def comb(n, k, modp):
    num = 1
    for i in range(n, n-k, -1):
        num = num * i % modp
    den = 1
    for i in range(2, k+1):
        den = den * i % modp
    return num * get_inv(den, modp) % modp

def comb_from_list(n, k, modp, fs, invs):   
    return fs[n] * invs[n-k] * invs[k] % modp



class UnionFindEx:
    def __init__(self, size):
        
        self.roots = [-1] * size
    def getRootID(self, i):
        r = self.roots[i]
        if r < 0:   
            return i
        else:
            r = self.getRootID(r)
            self.roots[i] = r
            return r
    def getGroupSize(self, i):
        return -self.roots[self.getRootID(i)]
    def connect(self, i, j):
        r1, r2 = self.getRootID(i), self.getRootID(j)
        if r1 == r2:
            return False
        if self.getGroupSize(r1) < self.getGroupSize(r2):
            r1, r2 = r2, r1
        self.roots[r1] += self.roots[r2]    
        self.roots[r2] = r1
        return True

Yes = 'Yes'
No = 'No'


def main():
    N,M,K=mis()
    A=lmis()
    B=lmis()
    A.reverse()
    B.reverse()
    c = 0
    t = 0
    s = []
    while A:
        a = A.pop()
        if t + a <= K:
            t += a
            c += 1
            s.append(a)
        else:
            break
    
    ans = c
    while B:
        if t + B[-1] <= K:
            t += B.pop()
            c += 1
            ans = max(ans, c)
        elif s:
            t -= s.pop()
            c -= 1
        else:
            break
    print(ans)









main()

Solution (Python):
N, M, K = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))

A_total = []
B_total = []
A_total.append(0)
B_total.append(0)

tmp = 0

for i in range(N):
    tmp += A[i]
    A_total.append(tmp)

tmp = 0

for i in range(M):
    tmp += B[i]
    B_total.append(tmp)

A_count = 0
B_count = 0

for i in range(N + 1):
    if A_total[i] > K:
        break
    else:
        A_count = i

max_count = A_count

for i in range(M + 1):
    if B_total[i] > K:
        break
    else:
        B_count = i
    while A_total[A_count] + B_total[i] > K and A_count > 0:
        A_count -= 1
    if max_count < A_count + B_count:
        max_count = A_count + B_count

print(max_count)

Solution (Python):
import sys
import itertools

import time
import math
import heapq
 
sys.setrecursionlimit(10 ** 7)
 
from collections import defaultdict
 
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines




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

accA = [0] * (N + 1)
for i in range(1, N + 1):
    accA[i] = accA[i - 1] + A[i - 1]
accB = [0] * (M + 1)
for i in range(1, M + 1):
    accB[i] = accB[i - 1] + B[i - 1]


ans = 0
for i in range(N + 1):
    remains = K - accA[i]
    if remains < 0:
        break
    left = 0
    right = M + 1
    while right - left > 1:
        mid = left + (right - left) // 2
        if accB[mid] <= remains:
            left = mid
        else:
            right = mid
    j = 0
    if left >= 0:
        j = left
    ans = max(ans, i + j)
print(ans)

Solution (Python):
import bisect
N,M,K=map(int, input().split())
A=list(map(int, input().split()))
B=list(map(int, input().split()))

ruiA=[0]*N
ruiA[0]=A[0]
for i in range(1,N):
    ruiA[i]=A[i]+ruiA[i-1]


ruiB=[0]*M
ruiB[0]=B[0]
for i in range(1,M):
    ruiB[i]=B[i]+ruiB[i-1]
ans=0
for i in range(N):
    totala=ruiA[i]
    if totala>K:
        break
    res=K-totala
    idx=bisect.bisect_right(ruiB, res)
    if idx==0:
        sub=i+1
    else:
        sub=i+1+idx
    ans=max(ans, sub)

corner=bisect.bisect_right(ruiB, K)
ans=max(ans, corner)
print(ans)

Solution (Python):
N, M, K = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))

time = 0
answer = 0
i = 0
for i, b in enumerate(B):
    if time + b > K:
        i -= 1
        break
    time += b
    answer += 1

best = answer

for a in A:
    if time + a <= K:
        time += a
        answer += 1
        best = max(best, answer)
    else:
        while time + a > K:
            if i < 0:
                print(best)
                exit(0)
            time -= B[i]
            i -= 1
            answer -= 1
        time += a
        answer += 1
        best = max(best, answer)
print(best)

Solution (Python):
N,M,K = [int(i) for i in input().split()]
A = [int(i) for i in input().split()]
B = [int(i) for i in input().split()]
ans = 0
ind_a = 0
ind_b = 0
s = 0
for i in range(N):
  if s + A[i] <= K:
    s += A[i]
  else:
    ind_a = i
    break
  if i == N-1:
    ind_a = N
while ind_b < M and s + B[ind_b] <= K:
    s += B[ind_b]
    ind_b += 1  
ans = ind_a + ind_b
t = ind_a
for i in reversed(range(t)):
  s -= A[i]
  ind_a -= 1
  while ind_b < M and s + B[ind_b] <= K:
    s += B[ind_b]
    ind_b += 1
  ans = max(ans,ind_a+ind_b)
print(ans)

Solution (Python):
n, m, k = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(int, input().split()))

import bisect

alist = [0]
blist = [0]

for i in range(n):
  alist.append(alist[i]+a[i])  
for i in range(m):
  blist.append(blist[i]+b[i])

res = 0
ans = 0
for i in range(n+1):
  border = k - alist[i]
  if border < 0:
    continue
  ans = i
  ans += bisect.bisect_right(blist, border)-1
  res = max(res, ans)
  
print(res)

Solution (Python):
N, M, K = map(int,input().split())
A = list(map(int,input().split()))
B = list(map(int,input().split()))

ma = 0
mb = 0

i=0
j=0

flag = True

while ma + A[i] <= K:
  ma += A[i]
  i += 1
  if i == len(A):
    break

while mb + B[j] <= K - ma:
  mb += B[j]
  j += 1
  if j == len(B):
    flag = False
    break

ans = i + j
k = i-1
while flag and k >= 0:
  ma -= A[k]
  while mb + B[j] <= K - ma:
    mb += B[j]
    j += 1
    if j == len(B):
      flag = False
      break      
  ans = max(ans,k+j)
  k -= 1

print(ans)

Solution (Python):
def main():
  N, M, K = map(int, input().split())
  A = list(map(int, input().split()))
  B = list(map(int, input().split()))
  time = 0
  num = 0
  while True:
    if num < N and time + A[num] <= K:
      time += A[num]
      num += 1
    else:
      break
  ans = num
  ans_temp = num
  for i in range(M):
    time += B[i]
    ans_temp += 1
    while time > K:
      if num > 0:
        time -= A[num-1]
        num -= 1
        ans_temp -=1
      else:
        break
    if num == 0 and time > K:
      break
    ans = max(ans, ans_temp)
  print(ans)
  
if __name__ == "__main__":
  main()

Solution (Python):
from sys import stdin
import numpy as np
from bisect import bisect, bisect_left, bisect_right
N,M,K = [int(x) for x in stdin.readline().rstrip().split()]
A = [int(x) for x in stdin.readline().rstrip().split()]
B = [int(x) for x in stdin.readline().rstrip().split()]
A = [0] + A

cumsum_A = np.cumsum(A)
cumsum_B = np.cumsum(B)



ans = 0
for i in range(0,N+1):
    tmp = K - cumsum_A[i]
    if tmp < 0:
        continue
    ans = max(ans,bisect_right(cumsum_B,tmp)+i)
    
    
print(ans)

Solution (Python):
from itertools import accumulate
from bisect import bisect_right
N,M,K = map(int,input().split())
A = list(map(int,input().split()))
B = list(map(int,input().split()))
accumA = [0]+list(accumulate(A))
accumB = [0]+list(accumulate(B))

ans = 0
for i in range(N+1):
    cnt = i
    a = accumA[i]
    rest = K-a
    if rest > 0:
        j = bisect_right(accumB,rest)-1
        cnt += j
    if rest < 0:
        continue
    else:
        ans = max(ans,cnt)

print(ans)

Solution (Python):
def main():
    import sys
    from bisect import bisect_right
    input = sys.stdin.readline
    N, M, K = [int(x) for x in input().strip().split()]
    A = [int(x) for x in input().strip().split()]
    B = [int(x) for x in input().strip().split()]
    Ac = [0] * N
    t = 0
    for i, a in enumerate(A):
        t += a
        Ac[i] = t
    Bc = [0] * M
    t = 0
    for i, b in enumerate(B):
        t += b
        Bc[i] = t

    ans = bisect_right(Bc, K)

    for i, ac in enumerate(Ac):
        if ac > K:
            break
        ans = max(ans, i+1+bisect_right(Bc, K-ac))

    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
from itertools import accumulate
from bisect import bisect

def resolve():
    n, m, k  = map(int, input().split())
    a = list(map(int, input().split()))
    b = list(map(int, input().split()))
    aac = [0] + list(accumulate(a))
    bbc = [0] + list(accumulate(b))
    ans = 0
    for i, aa in enumerate(aac):
        if aa > k:
            break
        tmp = k - aa
        idx = bisect(bbc, tmp)
        if ans < i + idx - 1:
            ans = i + idx - 1
    print(ans)

if __name__ == "__main__":
    resolve()

Solution (Python):
from bisect import bisect_left, bisect_right

N, M, K = [int(x) for x in input().split()]
A = [int(x) for x in input().split()]
B = [int(x) for x in input().split()]

prefA = [0]
prefB = [0]
for x in A:
    prefA.append(prefA[-1] + x)
for x in B:
    prefB.append(prefB[-1] + x)
best = 0
for a, cumA in enumerate(prefA):
    if K - cumA < 0:
        break
    b = bisect_right(prefB, K - cumA)
    if b == 0:
        continue
    b -= 1
    
    assert prefB[b] <= K - prefA[a]
    best = max(best, a + b)
print(best)