Problem: G: Koi no Junretsu Run! Run! Run! --Love Permutation, Run run run! -

story

Big Junretsu Ranran Randebu ♪ Hello, Hoshizora Ran Nya! My favorite data structure is Starry Sky Tree Nya!

Ran recently enrolled in the Department of Physics, but apparently he has to do programming there as well. Orchids, I like the theory of algorithms and data structures, but I'm not very good at implementing them ... Mostly, orchids are humans, but why do I have to study the language of machines! ??

However, if you don't do the task, you have to do it without getting credit. It seems that the issue that came out this time is related to the permutation run. If you can't see the author thinking about this problem with a single title, it's a little cold. Anyway, if you are good at programming and help me, I'll get excited! Then the problem is, let's go!

problem

If the sequence a of length K satisfies 1 \ leq a_i \ leq K (1 \ leq i \ leq K) and a_i \ neq a_j (1 \ leq i <j \ leq K), then a is a permutation of length K. It is said that.

Here, permutation pattern matching is defined as follows. A text permutation q matches a pattern permutation p means that there is a (not necessarily continuous) subsequence of q of the same length as p, such that the relative order matches p. Strictly speaking, when the length of q is N and the length of p is M, the fact that q matches p is a subscript string 1 \ leq i_1 <... <i_M \ leq N that satisfies a certain condition. Is to exist. The condition is that p_x <p_y (1 \ leq x <y \ leq M), and only then q_ {i_x} <q_ {i_y}. For example, a permutation (3, 4, 2, 1, 5) matches a permutation (2, 1, 3). This is because the subscript strings (1, 4, 5) satisfy the above conditions.

In addition, define a permutation run. A permutation run is a maximal continuous subsequence that is monotonically increasing or monotonically decreasing. That is, run is a continuous subsequence a_l, ...,, a_r (l <r), a_i <a_ {i + 1} (l \ leq i <r) (a_i> a_ {i + 1} (l) It means that there is no run consisting of continuous intervals that satisfy \ leq i <r)) and truly include this interval. For example, a permutation (3, 4, 2, 1, 5) has three runs: (3, 4), (4, 2, 1), (1, 5).

Given a text permutation q of length N and a pattern permutation p of length M. Here, q is guaranteed to always have exactly three runs. Determine if q matches p.

Input format

The input is given in the following format.


N
q_1 ... q_N
M
p_1 ... p_M


All inputs consist of integers. The first line is given the length N of the permutation q, which is the text. The second line that follows is given N integers separated by blanks, and the i (1 \ leq i \ leq N) th integer represents the i-th element q_i of q. The third row is given the length M of the permutation p, which is the pattern. In the following 4th line, M integers are given separated by blanks, and the j (1 \ leq j \ leq M) th integer represents the jth element p_j of p.

Constraint

* 4 \ leq N \ leq 10 ^ 5
* 1 \ leq M \ leq N
* q and p are permutations of length N and M, respectively.
* q has exactly 3 runs.



Output format

Print "Yes" if permutation q matches permutation p, otherwise "No" on one line.

Input example 1


Five
3 4 2 1 5
3
one two Three


Output example 1


Yes

Input example 2


Five
3 5 4 1 2
3
one two Three


Output example 2


No





Example

Input

5
3 4 2 1 5
3
1 2 3


Output

Yes

Solution (in CPP):

Solution:
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef pair<int, int> pii;
const int UP = 1, DOWN = 0;
const int INF = 1 << 30;
int N, M;

vector<int> inv(vector<int> &a) {
    int sz = a.size();
    vector<int> ret(sz);
    for(int i=0; i<sz; i++) ret[i] = sz - a[i] + 1;
    return ret;
}

int calcrun(vector<int> &a) {
    int n = a.size();
    if(n == 1) return 1;
    else {
        int ret = 1;
        bool prev = (a[0] < a[1]);
        for(int i=2; i<n; i++) {
            ret += (prev != (a[i-1] < a[i]));
            prev = (a[i-1] < a[i]);
        }
        return ret;
    }
}

vector<int> getLis(vector<int> &p) {
    int n = p.size();
    vector<int> temp(n, INF);
    for(int i=0; i<n; i++) {
        int idx = lower_bound(temp.begin(), temp.end(), p[i]) - temp.begin();
        temp[ idx ] = p[i];
    }
    return temp;
}

int getLisSize(vector<int> p) {
    return lower_bound(p.begin(), p.end(), INF) - p.begin();
}

vector<pii> makevec(vector<int> &a, int r, bool needsort = false) {
    int n = a.size();
    vector<pii> ret;
    ret.push_back(pii(a[0], r));
    for(int i=1; i<n-1; i++) {
        if((a[i-1] < a[i]) != (a[i] < a[i+1])) {
            r++;
            ret.push_back(pii(a[i], -r));
        }
        else ret.push_back(pii(a[i], r));
    }
    ret.push_back(pii(a[n-1], r));
    if(needsort) sort(ret.begin(), ret.end(), greater<pii>());
    return ret;
}

// pattern, q
bool checkvecTwo(vector<pii> &a, vector<pii> &b, int mode) {
    int n = a.size(), m = b.size();
    int arr[] = {3, 2}, val = arr[mode];
    vector<int> s, t, x, y;
    for(int i=0; i<n; i++) {
        if(abs(a[i].second) < val) s.push_back(a[i].first);
        else if(a[i].second != -val) x.push_back(n - a[i].first + 1);
    }
    for(int i=0; i<m; i++) {
        if(abs(b[i].second) < val) t.push_back(b[i].first);
        else if(b[i].second != -val) y.push_back(m - b[i].first + 1);
    }
    int ns = getLisSize( getLis(s) );
    int nt = getLisSize( getLis(t) );
    int nx = getLisSize( getLis(x) );
    int ny = getLisSize( getLis(y) );
    return nt >= ns && ny >= nx;
}

// pattern, q
bool checkvecThree(vector<pii> &a, vector<pii> &b) {
    int n = a.size(), m = b.size(), cur = 0;
    vector<int> vp, vq;
    for(int i=0; i<n; i++) {
        vp.push_back(a[i].first);
        int type = a[i].second;
        while(1) {
            bool ok = false;
            if(b[cur].second == type) ok = true;
            if(type < 0 && b[cur].second > 0) {
                int t = type * (-1);
                if(b[cur].second == t || b[cur].second == t-1) ok = true;
            }
            if(b[cur].second < 0 && type > 0) {
                int t = b[cur].second * (-1);
                if(type == t || type == t-1) ok = true;
            }
            if(ok) {
                vq.push_back(b[cur].first);
                cur++; break;
            }
            if(++cur >= m) return false;
        }
    }
    return true;
}

bool solve_1(vector<int> &p, vector<int> &q) {
    int n = getLisSize( getLis(p) );
    int m = getLisSize( getLis(q) );
    return m >= n;
}

bool solve_2(vector<int> &p, vector<int> &q) {
    vector<pii> vp, vq;
    if(q[0] > q[1]) {
        vp = makevec(p, 2), vq = makevec(q, 1);
        return checkvecTwo(vp, vq, 0);
    }
    else {
        vp = makevec(p, 1), vq = makevec(q, 1);
        return checkvecTwo(vp, vq, 1);
    }
}

bool solve_3(vector<int> &p, vector<int> &q) {
    if(q[0] > q[1]) return false;
    vector<pii> vp, vq;
    vp = makevec(p, 1, true); vq = makevec(q, 1, true);
    return checkvecThree(vp, vq);
}

int main() {
    cin >> N;
    vector<int> q(N);
    for(int i=0; i<N; i++) scanf("%d", &q[i]);

    cin >> M;
    vector<int> pat(M);
    for(int i=0; i<M; i++) scanf("%d", &pat[i]);

    if(M > 1 && pat[0] > pat[1]) {
        q   = inv(q  );
        pat = inv(pat);
    }

    int RUN = calcrun(pat);
    if      (RUN == 1)  cout << (solve_1(pat, q) ? "Yes" : "No") << endl;
    else if (RUN == 2)  cout << (solve_2(pat, q) ? "Yes" : "No") << endl;
    else if (RUN == 3)  cout << (solve_3(pat, q) ? "Yes" : "No") << endl;
    else                cout << "No" << endl;
    return 0;
}