#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <cmath>
using namespace std;

#define all(x) x.begin(), x.end()
#define sz(x) static_cast<lng>(x.size())

using lng = long long;

struct LinearFunc {
	lng K, B;
	LinearFunc(lng k = 0, lng b = -1e18) : K(k), B(b) {}
	lng operator()(lng X) {
		return K * X + B;
	}
};

vector<lng> coords;
struct LCT;

vector<pair<LCT*, LinearFunc>> changes;

struct LCT{
	int left, right;
	LinearFunc f;
	LCT* lv, * rv;
	LCT(int l = 0, int r = 1) : left(l), right(r), f(), lv(nullptr), rv(nullptr) {
		if (l + 1 != r) {
			int m = (l + r) / 2;
			lv = new LCT(l, m);
			rv = new LCT(m, r);
		}
	}
	lng get(lng X) {
		if (left + 1 == right) {
			return f(coords[X]);
		}
		if (X < lv->right) {
			return max(f(coords[X]), lv->get(X));
		}
		return max(f(coords[X]), rv->get(X));
	}
	void update(LinearFunc g) {
		int mid = (left + right) / 2;
		if (f(coords[mid]) < g(coords[mid])) {
			changes.emplace_back(this, f);
			LinearFunc tmp = f;
			f = g;
			g = tmp;
		}
		if (left + 1 == right) {
			return;
		}
		if (f(coords[left]) < g(coords[left])) {
			lv->update(g);
		}
		else {
			rv->update(g);
		}
	}
};

vector<lng> a, pref;
vector<vector<LinearFunc>> queries;
LCT* tree;
lng T;

void add_query(int v, int l, int r, int ql, int qr, LinearFunc f) {
	if (ql <= l && r <= qr) {
		queries[v].push_back(f);
		return;
	}
	if (qr <= l || r <= ql) {
		return;
	}
	int m = (l + r) / 2;
	add_query(2 * v + 1, l, m, ql, qr, f);
	add_query(2 * v + 2, m, r, ql, qr, f);
}


lng search_max1(int v, int l, int r) {
	size_t old_size = sz(changes);
	for (LinearFunc f : queries[v]) {
		tree->update(f);
	}
	if (l + 1 == r) {
		int pos = lower_bound(all(coords), a[l]) - coords.begin();
		return (tree->get(pos) + T + a[l] * l - pref[l]) / a[l];
	}
	int m = (l + r) / 2;
	lng res = max(search_max1(2 * v + 1, l, m), search_max1(2 * v + 2, m, r));
	while (sz(changes) > old_size) {
		changes.back().first->f = changes.back().second;
		changes.pop_back();
	}
	return res;
}

lng search_max2(int v, int l, int r) {
	size_t old_size = sz(changes);
	for (LinearFunc f : queries[v]) {
		tree->update(f);
	}
	if (l + 1 == r) {
		int pos = lower_bound(all(coords), a[l]) - coords.begin();
		return (tree->get(pos) + T - a[l] * l + pref[l + 1]) / a[l]; 
	}
	int m = (l + r) / 2;
	lng res = max(search_max2(2 * v + 1, l, m), search_max2(2 * v + 2, m, r));
	while (sz(changes) > old_size) {
		changes.back().first->f = changes.back().second;
		changes.pop_back();
	}
	return res;
}

void solve() {
	lng m, n; cin >> n >> m >> T;
	a.resize(n), pref.assign(n + 1, 0);
	for (lng& i : a) {
		cin >> i;
		coords.push_back(i);
	}
	sort(all(coords));
	coords.erase(unique(all(coords)), coords.end());
	partial_sum(all(a), pref.begin() + 1);
	vector<bool> used(n, false);
	for (int i = 0; i < m; i++) {
		int x; cin >> x; --x;
		used[x] = true;
	}
	lng ans = 0;
	int r = -1;
	queries.assign(4 * n, vector<LinearFunc>(0));
	tree = new LCT(0, sz(coords));
	for (int i = 0; i < n; i++) {
		while (r + 1 < n && pref[r + 1] - pref[i] <= T) {
			r++;
		}
		if (used[i]) {
			add_query(0, 0, n, i, r + 1, LinearFunc(-i, pref[i]));
		}
	}
	ans = max(ans, search_max1(0, 0, n));
	queries.assign(4 * n, vector<LinearFunc>(0));
	int l = n;
	for (int i = n - 1; i >= 0; i--) {
		while (l - 1 >= 0 && pref[i + 1] - pref[l] <= T) {
			l--;
		}
		if (used[i]) {
			add_query(0, 0, n, l + 1, i + 1, LinearFunc(i, -pref[i + 1]));
		}
	}
	ans = max(ans, search_max2(0, 0, n));
	cout << ans << '\n';
}

int main() {
	cin.tie(nullptr)->sync_with_stdio(false);
	int t = 1;
	// cin >> t;
	while (t--) {
		solve();
	}
	return 0;
}
