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

#pragma region Macros
using ll = long long;
#define int ll
using pii = pair<int, int>;
using tiii = tuple<int, int, int>;
template<class T = ll> using V = vector<T>;
template<class T = ll> using VV = V<V<T>>;
#define IOS\
    ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);
#define FOR(i,l,r) for(ll i=(l);i<(r);++i)
#define REP(i,n) FOR(i,0,n)
#define REPS(i,n) FOR(i,1,n+1)
#define RFOR(i,l,r) for(ll i=(l);i>=(r);--i)
#define RREP(i,n) RFOR(i,n-1,0)
#define RREPS(i,n) RFOR(i,n,1)
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define SORT(name) sort(name.begin(), name.end())
#define RSORT(name)\
    SORT(name);\
    reverse(all(name));
#define ZERO(p) memset(p, 0, sizeof(p))
#define MINUS(p) memset(p, -1, sizeof(p))
inline void Yes(bool b = true) {cout << (b ? "Yes" : "No") << '\n';}
inline void YES(bool b = true) {cout << (b ? "YES" : "NO") << '\n';}
template <class T> inline void print(T x){ cout << x << '\n';}
template<typename T1,typename T2> inline void chmin(T1 &a, T2 b){ if(a > b) a = b; }
template<typename T1,typename T2> inline void chmax(T1 &a, T2 b){ if(a < b) a = b; }

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const double DINF = std::numeric_limits<double>::infinity();
#pragma endregion

#if 1
#  define DBG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#  define DBG(fmt, ...)
#endif

template< typename T >
class CumulativeSum
{
public:
    CumulativeSum() {}
    CumulativeSum(int sz) : m_Data(sz, T(0)) {};

    void Init(int sz) { m_Data.assign(sz, T(0)); }

    // k に x を加える O(1)
    void Add(int k, T x) {
        assert(static_cast<int>(m_Data.size()) >= k);
        if(static_cast<int>(m_Data.size()) <= k) { m_Data.push_back(x); }
        else { m_Data[k] = (m_Data[k] + x); }
    }

    // 累積和の構築 O(m_Data.size())
    void Build() {
        for(int i = 1; i < static_cast<int>(m_Data.size()); i++) {
            m_Data[i] = (m_Data[i] + m_Data[i - 1]);
        }
    }

    // 区間 [0, k] の和を返す O(1)
    // 閉区間なので k が含まれることに注意
    T Query(int k) {
        if(k < 0) { return T(0); }
        return (m_Data[min(k, static_cast<int>(m_Data.size()) - 1)]);
    }

    // 区間 [l, h] の和を返す O(1)
    // 閉区間なので k が含まれることに注意
    T Query(int l, int h) {
        return (this->Query(h) - this->Query(l-1));
    }
private:
    vector< T > m_Data;
};

// v の [lb, ub) の範囲に val があるか探す
// あるならそのインデックスを返す。なければ -1 を返す
// 同じ数が複数ある場合どのインデックスを返すかは不定
// ほかの bin_search を使って範囲を絞ること
static inline ll bin_search1(const vector<ll>& v, ll lb, ll ub, ll val) {
    while(lb < ub) {
        ll mid = (lb + ub) / 2;
        if(v[mid] == val) { return mid; }
        else if(val < v[mid]) { ub = mid; }
        else { lb = mid + 1; }
    }
    return -1;
}

// v の [lb, ub) の範囲で val 以上の要素が初めて出てくるインデックスを返す
// なければ -1 を返す
// -1 を返すとこ以外 std::lower_bound と同じ
// 同じ数が複数ある場合は一番小さいインデックスを返す
static inline ll bin_search2(const vector<ll>& v, ll lb, ll ub, ll val) {
    lb--; ub--;
    while(ub - lb > 1) {
        ll mid = (lb + ub) / 2;
        if(v[mid] >= val) { ub = mid; }
        else { lb = mid; }
    }
    // この時点で lb + 1 = ub
    return (v[ub] >= val) ? ub : -1;
}

// [lb, ub) の範囲で val を超える要素が初めて出てくるインデックスを返す
// なければ -1 を返す
// -1 を返すとこ以外 std::upper_bound と同じ
// 同じ数が複数ある場合は一番小さいインデックスを返す
static inline ll bin_search3(const vector<ll>& v, ll lb, ll ub, ll val) {
    lb--; ub--;
    while(ub - lb > 1) {
        ll mid = (lb + ub) / 2;
        if(v[mid] > val) { ub = mid; }
        else { lb = mid; }
    }
    // この時点で lb + 1 = ub
    return (v[ub] > val) ? ub : -1;
}

// [lb, ub) の範囲で val 以下の要素で最大のもののインデックスを返す
// なければ -1 を返す
// 同じ数が複数ある場合は一番小さいインデックスを返す
static inline ll bin_search4(const vector<ll>& v, ll lb, ll ub, ll val) {
    lb--; ub--;
    while(ub - lb > 1) {
        ll mid = (lb + ub) / 2;
        if(v[mid] >= val) { ub = mid; }
        else { lb = mid; }
    }
    // この時点で lb + 1 = ub
    if(v[ub] <= val) { return ub; }
    if(lb < 0 || v[lb] > val) { return -1; }
    return lb;
}

// [lb, ub) の範囲で val 未満の要素で最大のもののインデックスを返す
// なければ -1 を返す
// 同じ数が複数ある場合は一番大きいインデックスを返す
static inline ll bin_search5(const vector<ll>& v, ll lb, ll ub, ll val) {
    lb--; ub--;
    while(ub - lb > 1) {
        ll mid = (lb + ub) / 2;
        if(v[mid] >= val) { ub = mid; }
        else { lb = mid; }
    }
    // この時点で lb + 1 = ub
    if(v[ub] < val) { return ub; }
    if(lb < 0 || v[lb] >= val) { return -1; }
    return lb;
}

const int MOD = 1000000007;
const int MAX_N = 100010;

int N, M, K;
V<> A, B;

CumulativeSum<int> csa, csb;

// 残りが k の時に読める本の数
int func1(int k) {
    if(k <= 0) { return 0; }
    if(B[0] > k) { return 0; }
    int lb = 0, ub = M - 1;
    while(ub - lb > 1) {
        int mid = (lb + ub) / 2;
        int val = csb.Query(mid);
        if(val <= k) { lb = mid; }
        else { ub = mid; }
    }
    if(csb.Query(ub) <= k) { return ub + 1; }
    if(csb.Query(lb) <= k) { return lb + 1; }
    return 0;
}
int func2(int k) {
    if(k <= 0) { return 0; }
    if(A[0] > k) { return 0; }
    int lb = 0, ub = N - 1;
    while(ub - lb > 1) {
        int mid = (lb + ub) / 2;
        int val = csa.Query(mid);
        if(val <= k) { lb = mid; }
        else { ub = mid; }
    }
    if(csa.Query(ub) <= k) { return ub + 1; }
    if(csa.Query(lb) <= k) { return lb + 1; }
    return 0;
}

signed main() {
    IOS;
    cin >> N >> M >> K;
    A.resize(N);
    B.resize(M);
    csa.Init(N); csb.Init(M);
    REP(i, N) {
        cin >> A[i];
        csa.Add(i, A[i]);
    }
    REP(i, M) {
        cin >> B[i];
        csb.Add(i, B[i]);
    }
    csa.Build();
    csb.Build();

    int ans = 0;
    REP(i, N) {
        int suma = csa.Query(i);
        if(suma > K) { continue; }
        int res = func1(K - suma);
        chmax(ans, (i + 1) + res);
    }
    REP(i, M) {
        int sumb = csb.Query(i);
        if(sumb > K) { continue; }
        int res = func2(K - sumb);
        chmax(ans, (i + 1) + res);
    }
    print(ans);

    return 0;
}


Measured memory_bytes: 9496