#include <bits/stdc++.h>

using namespace std;
using ll = long long;

#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) (int) (x).size()

vector<int> sol(vector<int>a ) {
    int n = sz(a);
    vector<int> used(n),ans(n);
    int lst = -1;
    for (int j = 0; j < n; j++) {
        bool f = false;
        for (int i = 0; i < n; i++) {
            if (a[i]!=lst&&!used[i]) {
                lst=a[i];
                ans[i] = j+1;
                used[i]=1;
                f=1;
                break;
            }
        }
        if (!f) {
            for (int i = 0; i< n;i++) {
                if (!used[i]) {
                    ans[i] = j + 1;
                    used[i]=1;break;
                }
            }
        }
    }
    return ans;
}

vector<int> kek(vector<int> a){
    vector<int>ans(sz(a));
    for (int j = 0; j < sz(a);j ++) ans[a[j] - 1] = j;
    return ans;
}

const ll inf = 1e18;

struct node {
    ll sm, len, push_add, push_set, mn;
};

node pushed(node v) {
    if (v.push_set != -inf) return {v.push_set * v.len, v.len, 0, -inf, v.push_set};
    v.sm += v.len* v.push_add;
    v.mn += v.push_add;
    return v;
}

node operator+(node a, node b) {
    return {a.sm + b.sm, a.len + b.len, 0, -inf, min(a.mn, b.mn)};
}

struct segtree {
    int n;
    vector<node> t;
    vector<int> a;
    segtree() = default;
    segtree(int n_, vector<int> a_) {
        n = n_;
        a = a_;
        t.resize(4 * n);
        build(1, 0, n);
    }

    void build(int v, int tl, int tr) {
        if (tl + 1 == tr) {
            t[v] = {a[tl], 1, 0, -inf, a[tl]};
            return;
        }
        int tm = (tl + tr) >> 1;
        build(v << 1, tl, tm);
        build(v << 1 | 1, tm, tr);
        t[v] = t[v << 1] + t[v << 1 | 1];
    }

    void push(int v) {
        if (t[v].push_set != -inf) {
            t[v].sm = t[v].len * t[v].push_set;
            t[v].mn = t[v].push_set;
            t[v << 1].push_set = t[v].push_set;
            t[v << 1 | 1].push_set = t[v].push_set;
        }
        else if (t[v].push_add != 0) {
            t[v].sm += t[v].len * t[v].push_add;
            t[v].mn += t[v].push_add;
            t[v << 1].push_add += t[v].push_add;
            t[v << 1 | 1].push_add += t[v].push_add;
        }
        t[v].push_set = -inf; 
        t[v].push_add = 0;
    }

    void pull(int v) {
        t[v] = pushed(t[v << 1]) + pushed(t[v << 1 | 1]);
    }

    void update_add(int v, int tl, int tr, int l, int r, ll x) {
        if (l <= tl && tr <= r) {
            if (t[v].push_set != -inf) t[v].push_set+= x;
            else t[v].push_add += x;
            return;
        }
        if (tr <= l || tl >= r) return;
        int tm = (tl + tr) >> 1;
        push(v);
        update_add(v << 1, tl, tm, l, r, x);
        update_add(v << 1 | 1, tm, tr, l, r, x);
        pull(v);
        // cout << v << ' ' << tl << ' ' << tr << ' ' << x << ' ' << t[v].sm << endl;
    }

    void update_set(int v, int tl, int tr, int l, int r, ll x) {
        if (l <= tl && tr <= r) {
            t[v].push_set = x; 
            return;
        }
        if (tr <= l || tl >= r) return;
        int tm = (tl + tr) >> 1;
        push(v);
        update_set(v << 1, tl, tm, l, r, x);
        update_set(v << 1 | 1, tm, tr, l, r, x);
        pull(v);
    }

    int find_first(int v, int tl, int tr, int p) {
        if (tl > p || pushed(t[v]).mn >= 0) return -1;
        if (tl + 1 == tr) return tl;
        int tm = (tl + tr) >> 1;
        push(v);
        int rsr =find_first(v <<1, tl, tm, p);
        return (rsr == -1?find_first(v<<1|1, tm, tr, p) : rsr);
    }

    node get(int v, int tl, int tr, int l, int r) {
        if (l <= tl && tr <= r) return pushed(t[v]);
        if (tr <= l || tl >= r) return {0, 0, 0};
        int tm = (tl + tr) >> 1;
        push(v);
        return get(v << 1,tl, tm, l,r ) + get(v << 1 | 1, tm, tr, l, r);
    }
};

ll sol(vector<ll> a, vector<ll> b, int cnt0, int lim, bool full) {
    if (a.empty()) return 0;
    vector<pair<int, int>> blocks;
    if (cnt0 > 0) blocks = {{cnt0, 0ll}};
    // vector<ll> dlts(cnt0, 0ll);
    ll ans= -inf, sma= 0, addit = 0, sm_dlt = 0, cnt_dlt = cnt0;
    if (!full) ans = 0;
    for (int j = 0; j < sz(a); j++) {
        int totlen = 0;
        while (!blocks.empty() && blocks.back().second + addit + b[j] < 0) {
            totlen += blocks.back().first;
            sm_dlt -= blocks.back().first * (blocks.back().second + addit); 
            blocks.pop_back();
        }
        sm_dlt += b[j] * (cnt_dlt - totlen);
        addit += b[j];
        if(cnt_dlt + 1 <= lim) {
            cnt_dlt++; totlen++;
        }
        blocks.pb({totlen, -addit});
        // for (auto &u : dlts) u = max(0ll, u + b[j]);
        // if (sz(dlts) + 1 <= lim) dlts.pb(0);
        sma += a[j];
        if (!full || j == sz(a) - 1) {
            ans= max(ans, sma + sm_dlt);
        }
    }
    // cout << ans << " ans\n";
    return ans;
}

void solve() {
    int n; cin >> n;
    vector<ll> a(n), b(n);
    for(int i = 0; i < n; i++) cin >> a[i] >> b[i];
    vector<int> p(n);
    for (auto&u: p) cin >> u;
    ll ans = 0, took = 0, lst = 0;
    for (int j = 0; j < n; j++) {
        if(p[j] != -1) {
            vector<ll> a2,b2;
            for(int i = took; i < p[j]; i++) {
                a2.pb(a[i] +b[i] * 1ll*lst);
                b2.pb(b[i]);
            }
            ans += sol(a2, b2, min(took, (ll)j) - lst, j - lst, 1);
            lst = j + 1;
            took = p[j];
        }
    }

    vector<ll> a2, b2;
    for (int j = took; j < n; j++) {
        a2.pb(a[j] + b[j] * lst);
        b2.pb(b[j]);
    }
    ans+= sol(a2, b2, took - lst, n - 1 - lst, 0);
    cout << ans<<'\n';
}

signed main() {
    int t = 1;
    #ifdef LOCAL
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
        // cin >> t;
    #else 
        cin.tie(0)->sync_with_stdio(false);
    #endif 

    while (t--) solve();

    return 0;
}