/* -----------------------
Autor: Tomasz Boguslawski
-------------------------- */
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<iomanip>
#include<string>
#include<sstream>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include <fstream>
#include<math.h>

#define FOR(x, b, e) for(long x = b; x <= (e); x++)
#define FORD(x, b, e) for(long x = b; x >= (e); x--)
#define VAR(v, n) __typeof(n) v = (n)
#define ALL(c) (c).begin(), (c).end()
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define DEBUG if (debug)
#define MIN(a,b) ((a>b)?b:a)
#define MAX(a,b) ((a>b)?a:b)
#define LL long long

using namespace std;

LL total;

void addMoves(LL ileDodac)
{
    //cout << "Dodaje: " << ileDodac << "\n";
    total=(total+ileDodac)%1000000007;
}

class Node
{
    public:
    long nr; long nr1; long nr2;
    long typ; // 0 - zwykly; 1-zakresowy lewy; 2-zakresowy prawy
    Node* left; Node* right;
    Node() { left=NULL; right=NULL; typ=0; nr=0; nr1=0; nr2=0; };
    void display(long wciecie)
    {
        FOR(i,1,wciecie) cout << " ";
        if (typ==0) cout << nr << "\n";
        else if (typ==1) cout << "[L] " << nr1 << ".." << nr2 << "\n";
        else if (typ==2) cout << "[P] " << nr1 << ".." << nr2 << "\n";
        if (left==NULL && right==NULL) return;
        if (left==NULL) { FOR(i,1,wciecie+2) cout << " "; cout << "-\n"; }
        else {
            //cout << "left:\n";
            left->display(wciecie+2);
        }
        if (right==NULL) { FOR(i,1,wciecie+2) cout << " "; cout << "-\n"; }
        else {
            //cout << "right:\n";
            right->display(wciecie+2);
        }
    }

    LL ileWZakresie()
    {
        return (nr2-nr1+1);
    }

    void wyprostujSieWLewo()
    {
        // robi z siebie lewego zakresowca;
        if (typ==0)
        {
            // prostowanie zwyklego wierzcholka
            if (left!=NULL) left->wyprostujSieWLewo();
            if (right!=NULL) right->wyprostujSieWPrawo();
            // teraz trzeba przerzuciæ wszystko z prawej na lewa:
            if (right!=NULL)
            {
                addMoves(right->ileWZakresie());
                //newRoot=new Node();
                typ=1;
                if (left==NULL) nr1=nr; else nr1=left->nr1;
                nr2=right->nr2;
                right=NULL; left=NULL;
            } else
            {
                typ=1;
                // po prawej nic nie ma
                if (left==NULL)
                {
                    // i po lewej nic nie ma
                    nr1=nr; nr2=nr;
                }
                else
                {
                    // po lewej jest zakresowiec:
                    nr1=left->nr1;
                    nr2=nr;
                    left=NULL;
                }
            }
        }
        else if (typ==1)
        {
            // prostowanie lewego zakresu - ktory moze miec lewe dziecko
            if (left==NULL) return; // nic sie nie zmienia
            left->wyprostujSieWLewo();
            nr1=left->nr1;
            left=NULL;
        }
        else
        {
            // prostowanie prawego zakresu w lewo - czy to w ogole jest mozliwe???
            cout << "ERROR1\n"; return;
        }
    }

    void wyprostujSieWPrawo()
    {
        // robi z siebie prawego zakresowca;
        if (typ==0)
        {
            // prostowanie zwyklego wierzcholka
            if (left!=NULL) left->wyprostujSieWLewo();
            if (right!=NULL) right->wyprostujSieWPrawo();
            // teraz trzeba przerzuciæ wszystko z lewej na prawa:
            if (left!=NULL)
            {
                addMoves(left->ileWZakresie());
                //newRoot=new Node();
                typ=2;
                if (right==NULL) nr2=nr; else nr2=right->nr2;
                nr1=left->nr1;
                left=NULL; right=NULL;
            } else
            {
                typ=2;
                // po lewej nic nie ma
                if (right==NULL)
                {
                    // i po prawej nic nie ma
                    nr1=nr; nr2=nr;
                }
                else
                {
                    // po prawej jest zakresowiec:
                    nr2=right->nr2;
                    nr1=nr;
                    right=NULL;
                }
            }
        }
        else if (typ==1)
        {
            // prostowanie prawgo zakresu - ktory moze miec prawe dziecko
            if (right==NULL) return; // nic sie nie zmienia
            right->wyprostujSieWPrawo();
            nr2=right->nr2;
            right=NULL;
        }
        else
        {
            // prostowanie lewego zakresu w prawo - czy to w ogole jest mozliwe???
            cout << "ERROR2\n"; return;
        }
    }

    void oczyscLewaStrone()
    {
        // typ 0 - czyscimy; typ 1- niemozliwe wywolanie; typ 2 - ma czysto po lewej
        if (typ==0)
        {
            if (left==NULL)
            {
                // prosta zamiana na zakresowca:
                typ=2; nr1=nr; nr2=nr;
                return;
            }
            left->wyprostujSieWLewo();
            addMoves(left->ileWZakresie());
            typ=2;
            nr1=left->nr1; nr2=nr; left=NULL;
            // jesli po prawej jest zakres, to trzeba sie z nim polaczyc:
            if (right!=NULL)
            {
                if (right->typ==2)
                {
                    nr2=right->nr2;
                    right=right->right;
                }
            }
        }
    }


    void oczyscPrawaStrone()
    {
        if (typ==0)
        {
            if (right==NULL)
            {
                // prosta zamiana na zakresowca:
                typ=1; nr1=nr; nr2=nr;
                return;
            }
            right->wyprostujSieWPrawo();
            addMoves(right->ileWZakresie());
            typ=1;
            nr1=nr; nr2=right->nr2; right=NULL;
            // jesli po lewej jest zakres, to trzeba sie z nim polaczyc:
            if (left!=NULL)
            {
                if (left->typ==1)
                {
                    nr1=left->nr1;
                    left=left->left;
                }
            }
        }
    }

    void wydobadzZLewegoZakresowcaDziecka(long q)
    {
        // po lewej jest zakresowiec, ktory zawiera q
        long ileObrotow=left->nr2-q+1; addMoves(ileObrotow);
        long mojNr=nr;
        nr=q;
        if ((right==NULL) || (right->typ==0))
        {
            Node* newRight=new Node(); newRight->typ=2; newRight->nr1=q+1; newRight->nr2=mojNr; newRight->right=right;
            right=newRight;
        }
        else
        {
            right->nr1=q+1;
        }
        if (left->nr1==q)
        {
            // caly zakres poszedl na obroty
            left=left->left;
        }
        else
        {
            left->nr2=q-1;
        }
    }


    void wydobadzZLewegoZakresowca(long q)
    {
        // jestem lewo-zakresowiec, ktory zawiera q
        long ileObrotow=nr2-q; addMoves(ileObrotow);
        nr=q; typ=0; // zamieniam sie na zwykly wezel
        if (q!=nr2)
        {
            // obroty w prawo
            right=new Node(); right->typ=2; right->nr1=q+1; right->nr2=nr2;
        }
        if (q!=nr1)
        {
            Node* newLeft=new Node(); newLeft->typ=1; newLeft->nr1=nr1; newLeft->nr2=q-1; newLeft->left=left;
            left=newLeft;
        }
    }


    void wydobadzZPrawegoZakresowca(long q)
    {
        // jestem prawo-zakresowiec, ktory zawiera q
        long ileObrotow=q-nr1; addMoves(ileObrotow);
        nr=q; typ=0; // zamieniam sie na zwykly wezel
        if (q!=nr1)
        {
            // obroty w lewo
            left=new Node(); left->typ=1; left->nr1=nr1; left->nr2=q-1;
        }
        if (q!=nr2)
        {
            Node* newRight=new Node(); newRight->typ=2; newRight->nr1=q+1; newRight->nr2=nr2; newRight->right=right;
            right=newRight;
        }
    }


    void wydobadzZPrawegoZakresowcaDziecka(long q)
    {
        // po prawej jest zakresowiec, ktory zawiera q
        long ileObrotow=q-right->nr1+1; addMoves(ileObrotow);
        long mojNr=nr;
        nr=q;
        if ((left==NULL) || (left->typ==0))
        {
            Node* newLeft=new Node(); newLeft->typ=1; newLeft->nr1=mojNr; newLeft->nr2=q-1; newLeft->left=left;
            left=newLeft;
        }
        else
        {
            left->nr2=q-1;
        }
        if (right->nr2==q)
        {
            // caly zakres poszedl na obroty
            right=right->right;
        }
        else
        {
            right->nr1=q+1;
        }
    }

    void przerobNaLewyZakresSiegajacyDo(long q)
    {
        // to jest wolane tylko w lewo
        if (typ==0) oczyscPrawaStrone();
        // teraz juz na pewno jestem typu 1
        if ((nr1<=q)&&(q<=nr2)) return; // jest OK, juz siegam do q
        left->przerobNaLewyZakresSiegajacyDo(q);
        // polacz sie:
        nr1=left->nr1; left=left->left;
    }

    void przerobNaPrawyZakresSiegajacyDo(long q)
    {
        // to jest wolane tylko w prawo
        if (typ==0) oczyscLewaStrone();
        // teraz juz na pewno jestem typu 2
        if ((nr1<=q)&&(q<=nr2)) return; // jest OK, juz siegam do q
        right->przerobNaPrawyZakresSiegajacyDo(q);
        // polacz sie:
        nr2=right->nr2; right=right->right;
    }

    void dajNaGore(long q)
    {
        // modyfikuje drzewo tak, zeby na gorze znalazlo sie q
        if (typ==0)
        {
            if (nr==q) return; // od razu jest na gorze
            if (q<nr)
            {
                // q jest w lewym poddrzewie
                left->przerobNaLewyZakresSiegajacyDo(q);
                // i teraz sprytny obrot: left jest lewo-zakresowcem teraz zawierajacym q
                this->wydobadzZLewegoZakresowcaDziecka(q);
            }
            else
            {
                // q jest w prawym poddrzewie
                right->przerobNaPrawyZakresSiegajacyDo(q);
                // i teraz sprytny obrot: right jest prawo-zakresowcem teraz zawierajacym q
                this->wydobadzZPrawegoZakresowcaDziecka(q);
            }
        }
        else if (typ==1)
        {
            if ((nr1<=q)&&(q<=nr2))
            {
                // q jest w moim zakresie
            }
            else
            {
                left->przerobNaLewyZakresSiegajacyDo(q);
                // polacz sie:
                nr1=left->nr1;
                left=left->left;
            }
            // **************** jestem lewozakresowcem i zawieram q
            this->wydobadzZLewegoZakresowca(q);

        }
        else if (typ==2)
        {
            if ((nr1<=q)&&(q<=nr2))
            {
                // q jest w moim zakresie
            }
            else
            {
                right->przerobNaPrawyZakresSiegajacyDo(q);
                // polacz sie:
                nr2=right->nr2;
                right=right->right;
            }
            // **************** jestem prawozakresowcem i zawieram q
            this->wydobadzZPrawegoZakresowca(q);
        }
    }
};

long n;
Node* root1;
Node* root2;

Node* nodes[500001];

Node* wczytajBST()
{
    Node* root=NULL;
    FOR(i,1,n) { nodes[i]=new Node(); nodes[i]->nr=i; nodes[i]->typ=0; };
    long par;
    FOR(i,1,n)
    {
        cin >> par;
        if (par!=-1)
        {
            if (par<i) nodes[par]->right=nodes[i];
            else nodes[par]->left=nodes[i];
        }
        else root=nodes[i];
    }
    return root;
};

void przerabiaj(Node* root1, Node* root2)
{
    //cout << "Przerabiam wezel: typ=" << root1->typ << " nr=" << root1->nr << "\n";
    root1->dajNaGore(root2->nr);
    //cout << "Po przerobce: " << total << "\n";
    //root1->display(0);
    if (root2->left!=NULL) przerabiaj(root1->left, root2->left);
    if (root2->right!=NULL) przerabiaj(root1->right, root2->right);
}

/// MAIN
int main(int argc, char* argv[])
{
    // magic formula, which makes streams work faster:
	ios_base::sync_with_stdio(0);
	cin >> n; total=0;
	root1=wczytajBST();
	root2=wczytajBST();

    przerabiaj(root1, root2);

    cout << total << "\n";

    return 0;
};
