#include <bits/stdc++.h>

#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2")

#define all(v) v.begin(), v.end()
#define rep(i, n) for (int i = 0; i < n; i++)
#define cin(v) for (auto& vi : v) { cin >> vi; }
#define cout(v) for (auto& vi : v) { cout << vi << ' '; } cout << '\n';
//#define int long long

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double db;

const int INF = 1e9 + 7;
const int MOD = 998244353;
const int MOD2 = 1e9 + 737373;
const ll LINF = 1e18 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

struct segment_tree {
    int n;
    vector <ll> tree;

    segment_tree(int n_) {
        n = n_;
        tree.resize(4 * n, 0);
    }

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

    segment_tree(vector<ll>& a) {
        n = (int) a.size();
        tree.resize(4 * n, 0);
        build(0, 0, n, a);
    }

    ll query(int v, int l, int r, int ql, int qr) {
        if (qr <= l || r <= ql) {
            return -LINF;
        }
        if (ql <= l && r <= qr) {
            return tree[v];
        }
        int mid = (l + r) / 2;
        return max(query(2 * v + 1, l, mid, ql, qr), query(2 * v + 2, mid, r, ql, qr));
    }

    ll query(int l, int r) {
        return query(0, 0, n, l, r);
    }

    void update(int v, int l, int r, int id, ll val) {
        if (r - l == 1) {
            tree[v] += val;
            return;
        }
        int mid = (l + r) / 2;
        if (id < mid) {
            update(2 * v + 1, l, mid, id, val);
        }
        else {
            update(2 * v + 2, mid, r, id, val);
        }
        tree[v] = max(tree[2 * v + 1],  tree[2 * v + 2]);
    }

    void update(int id, ll val) {
        update(0, 0, n, id, val);
    }
};

int n, m;

ll binpow(ll x, ll y, ll mod) {
    if (y == 0) return 1;
    if (y % 2 == 0) return binpow(x * x % mod, y / 2, mod);
    return binpow(x, y - 1, mod) * x % mod;
}

vector <int> g[1000073];
char used[1000073];
int p[1000073];
int sz[1000073];

void dfs(int v) {
    if (used[v]) return;
    used[v] = 1;
    sz[v] = 1;
    for (int to : g[v]) {
        if (!used[to]) {
            dfs(to);
            sz[v] += sz[to];
        }
    }
}

int upchange[1000073];
int downchange[1000073];

ll dp[5073][5073];

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout << fixed << setprecision(10);
    bool pminus = 1, g56 = 1, g78 = 1, g910 = 1;
    cin >> n;
    vector <pair <int, int> > line(n);
    vector <ll> A(n), B(n);
    vector <pair <int, int> > border(n);
    vector <int> plan(n);
    rep(i, n) {
        cin >> A[i] >> B[i];
        line[i] = {A[i], B[i]};
        if (B[i] > 0) {
            g56 = 0;
        }
        if (B[i] < 0) {
            g78 = 0;
        }
        if (i && B[i] < B[i - 1]) {
            g910 = 0;
        }
    }
    rep(i, n) {
        cin >> plan[i];
        if (plan[i] != -1) {
            pminus = 0;
        }
    }
    rep(i, n) {
        border[i] = {0, i};
    }
    fill(upchange, upchange + n, INF);
    int down = 0, up = n - 1;
    int minpep = 0;
    for (int i = 0; i < n; i++) {
        if (plan[i] != -1) {
            downchange[plan[i]] = i + 1;
            upchange[plan[i] - 1] = min(upchange[plan[i] - 1], i);
            minpep = max(minpep, plan[i]);
        }
    }
    for (int i = n - 2; i >= 0; i--) {
        upchange[i] = min(upchange[i], upchange[i + 1]);
    }
    for (int i = 0; i < n; i++) {
        border[i].first = max(border[i].first, downchange[i]);
        if (i > 0) {
            border[i].first = max(border[i].first, border[i - 1].first);
        }
        border[i].second = min(border[i].second, upchange[i]);
    }
    // rep(i, n) {
    //     cout << border[i].first << ' ' << border[i].second << '\n';
    // }
    vector <ll> pref(n + 1, 0);
    for (int i = 0; i < n; i++) {
        pref[i + 1] = pref[i] + A[i];
    }
    //cout(pref);
    vector <ll> minus_linf(n + 1, -LINF);

    if (n <= 5000) {
        rep(i, n + 1) {
            fill(dp[i], dp[i] + n, -LINF);
        }
        vector <segment_tree> segtrees(n + 1, segment_tree(minus_linf));
        dp[0][0] = 0;
        segtrees[0].update(0, LINF);
        for (int i = 1; i <= n; i++) {
            for (int j = border[i - 1].first; j <= border[i - 1].second; j++) {
                ll mx = segtrees[i - 1].query(0, j + 1);
                if (mx != LINF) {
                    ll old = dp[i][j];
                    dp[i][j] = max(dp[i][j], mx + B[i - 1] * j);
                    segtrees[i].update(j, dp[i][j] - old);
                }
            }
        }
        // rep(i, n + 1) {
        //     rep(j, n) {
        //         cout << dp[i][j] + pref[i] << ' ';
        //     }
        //     cout << '\n';
        // }
        ll ans = -LINF;
        for (int i = minpep; i <= n; i++) {
            for (int j = 0; j < n; j++) {
                ans = max(ans, dp[i][j] + pref[i]);
            }
        }
        cout << ans << '\n';
    }
    return 0;
}