#include <bits/stdc++.h>

using namespace std;

#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define int ll

using ll = long long;
using ld = long double;
using pii = pair<int, int>;

const int inf = 2e9, INF = 1e18;

struct SegTree {
    vector<int> tree;
    vector<int> p;

    void build(int v, int l, int r, vector<int> &a) {
        if (l + 1 == r) {
            tree[v] = a[l];
            return;
        }
        int mid = (r + l) / 2;
        build(2 * v + 1, l, mid, a);
        build(2 * v + 2, mid, r, a);
        tree[v] = (tree[2 * v + 1] + tree[2 * v + 2]);
    }

    SegTree(int n, vector<int> a = {}) {
        tree.resize(4 * n);
        p.resize(4 * n);
        if (!a.empty())
            build(0, 0, n, a);
    }

    void push(int v, int l, int r) {
        tree[2 * v + 1] += p[v];
        tree[2 * v + 2] += p[v];
        p[2 * v + 1] += p[v];
        p[2 * v + 2] += p[v];
        p[v] = 0;
    }

    void upd(int lq, int rq, int x, int v = 0, int l = 0, int r = 0) {
        if (r == 0) r = tree.size() / 4;
        if (l >= rq || lq >= r) return;
        if (lq <= l && r <= rq) {
            tree[v] += x;
            p[v] += x;
            return;
        }
        int mid = (r + l) / 2;
        upd(lq, rq, x, 2 * v + 1, l, mid);
        upd(lq, rq, x, 2 * v + 2, mid, r);
        tree[v] = (tree[2 * v + 1] + tree[2 * v + 2]);
    }

    int get(int lq, int rq, int v = 0, int l = 0, int r = 0) {
        if (r == 0) r = tree.size() / 4;
        if (l >= rq || lq >= r) return -inf;
        if (lq <= l && r <= rq) return tree[v];
        push(v, l, r);
        int mid = (r + l) / 2;
        return max(get(lq, rq, 2 * v + 1, l, mid), get(lq, rq, 2 * v + 2, mid, r));
    }
};


void solve() {
    int n;
    cin >> n;
    vector<pii> a(n);
    for (auto &[x, y]: a) cin >> x >> y;
    int ans = -0;
    vector<int> pref(n + 1);
    for (int i = 0; i < n; i++) {
        pref[i + 1] = pref[i] + a[i].second;
    }
    int now = 0;
    vector<int> k = pref;
    sort(all(k));
    int cur = 0;
    vector<int> dp = {a[0].first};
    ans = max(ans, *max_element(all(dp)));
    vector<int> p(n);
    for (auto &x: p) cin >> x;
    vector<pii> b(n + 1, {0, n});
    for (int i = 0; i < n; i++) {
        if (p[i] != -1) {
            b[p[i] - 1].second = i;
            for (int j = p[i]; j < n; j++) b[j].first = max(b[j].first, i);
        }
    }
    for (int i = 1; i < n; i++) {
        vector<int> dp1(i + 1, -INF);
        for (int j = 0; j < dp.size(); j++) {
            // dp1[j + 1] = max(dp1[j + 1], dp[j] + a[i].first + a[i].second * (j + 1));
            dp1[j] = max(dp1[j], dp[j] + a[i].first + a[i].second * (j));
        }
        swap(dp, dp1);
        int b1 = a[i].second;
        for (int i = 1; i < dp.size(); i++) {
            dp[i] = max(dp[i], dp[i - 1] + b1);
        }
        for (int j = 0; j < b[i].first && j < dp.size(); j++) dp[j] = -INF;
        // fill(dp.begin(), dp.begin() + min(b[i].first, (int) dp.size()), -INF);
        for (int j = b[i].second + 1; j < dp.size(); j++) dp[j] = -INF;
        // fill(dp.begin() + min(b[i].second, (int) dp.size()), dp.end(), -INF);
        ans = max(ans, *max_element(all(dp)));
    }
    cout << ans;
}

int32_t main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int tt = 1;
    // cin >> tt;
    while (tt--) {
        solve();
    }
}
