#include<bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
#define eps 1e-6
#define eq(x,y) (fabs((x)-(y)) < eps)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int>pii;
const int mod = 998244353;
long double PI = acosl(-1);
const ll infl = 1e18+100;
const int inf = 2e9+100;
const int nmax = 2e5+5;
const int MAXLG = log2(nmax)+1;
//mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
//typedef tree< int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ost;

/// treap, 0 indexing
struct node
{
    int prior, size;
    ll val, sum, lazy, rev;
    node *l, *r;
    node(ll v = 0){
        val = sum = v;
        lazy = 0;
        rev = 0;
        prior = rand();
        size = 1;
        l = r = NULL;
    }
} *rootod, *rootev, *rutstod, *rutstev;

typedef node* pnode;

int sz(pnode t){
    return t ? t -> size : 0;
}
void upd_sz(pnode t)
{
    if(t) t -> size = sz(t ->l) + 1 + sz(t -> r);
}
void push(pnode t)
{
    if(!t)
        return;
    if(t->lazy)
    {
        t -> val += t -> lazy;
        t -> sum += t -> lazy * sz(t);
        if(t -> l)
            t -> l -> lazy += t -> lazy;
        if(t -> r)
            t -> r -> lazy += t -> lazy;
        t -> lazy = 0;
    }
    if(t->rev)
    {
        swap(t->l,t->r);
        if(t -> l)
            t -> l -> rev ^= t -> rev;
        if(t -> r)
            t -> r -> rev ^= t -> rev;
        t -> rev = 0;
    }
}
void combine(pnode t)
{
// Note: This function should reset datas of t first (MUST!!)
// Then update datas from l and r.
    if(!t)
        return;
    push(t -> l);
    push(t -> r);

    t -> sum = t -> val; // Reset

    if(t -> l)
        t -> sum += t -> l -> sum;
    if(t -> r)
        t -> sum += t -> r -> sum;
}

void split(pnode t, pnode &l, pnode &r, int pos, int add = 0){
    if(!t) return void(l = r = NULL);
    push(t);
    int curr = sz(t -> l) + add;
    if(curr <= pos)
        split(t -> r, t -> r, r, pos, curr + 1), l = t;
    else
        split(t -> l, l, t -> l, pos, add), r = t;
    upd_sz(t);
    combine(t);
}
void merge(pnode &t, pnode l, pnode r)
{
    push(l), push(r);
    if(!l || !r)
        t = l ? l : r;
    else if(l -> prior > r -> prior)
        merge(l -> r, l -> r, r), t=l;
    else merge(r -> l, l, r -> l), t = r;
    upd_sz(t);
    combine(t);
}

ll query(pnode t, int l, int r)
{
    pnode L, mid, R;
    split(t, L, mid, l - 1);
    split(mid, t, R, r - l);
    ll ans = t -> sum;
    merge(mid, L, t);
    merge(t, mid, R);
    return ans;
}
void update(pnode t, int l, int r, ll v)
{
    pnode L, mid, R;
    split(t, L, mid, l - 1);
    split(mid, t, R, r - l);
    t -> lazy += v;
    merge(mid, L, t);
    merge(t, mid, R);
}
void insert(pnode &t, int pos, ll v)
{
    pnode L, R, tmp, y = new node(v);
    split(t, L, R, pos - 1);
    merge(tmp, L, y);
    merge(t, tmp, R);
}
void Del(pnode &t, int pos)
{
    pnode L, R, mid;
    split(t, L, mid, pos - 1);
    split(mid, t, R, 0);
    pnode tmp = t;
    merge(t, L, R);
    free(tmp);
}
void cycshift(pnode &t, int l, int r)   ///right
{
    int val = query(t, r, r);
    Del(t, r);
    insert(t, l, val);
}
void Reverse(pnode t, int l, int r)
{
    pnode L, mid, R;
    split(t, L, mid, l - 1);
    split(mid, t, R, r - l);
    t -> rev ^= 1;
    merge(mid, L, t);
    merge(t, mid, R);
}

void NA(){
    cout<<"No";
    exit(0);
}

int bit[2][nmax];

void upd(int idx, int limit, int val, int typ){
    while(idx<=limit) bit[typ][idx]+=val, idx += (idx&-idx);
}

int kuery(int idx, int typ){
    int ret = 0;
    while(idx) ret+=bit[typ][idx], idx -= (idx&-idx);
    return ret;
}

int main(){
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

    int n;
    cin>>n;
    vector<vector<int> >v(3, vector<int>(n));
    for(auto &z : v)
        for(int &x : z)
            cin>>x;

    vector<int>nums(n);
    vector<int>stet(n, -1);
    for(int i=0; i<n; i++){
        if(nums[i] or stet[i]!=-1) NA();
        int bro = max( {v[0][i], v[1][i], v[2][i]} );
        if(bro%3!=0) NA();
        if(v[0][i]==bro){
            if(v[1][i]==bro-1 and v[2][i]==bro-2){
                nums[i] = bro/3, stet[i] = 1;
            }
            else NA();
        }
        else if(v[2][i]==bro){
            if(v[1][i]==bro-1 and v[0][i]==bro-2){
                nums[i] = bro/3, stet[i] = 0;
            }
            else NA();
        }
        else NA();
    }
    for(int i=0; i<n; i++){
        if(nums[i]%2!=(i+1)%2) NA();
    }
//    cout<<"etodurr -- "<<endl;

    vector<int>koi(n+1);
    for(int i=0; i<n; i++){
        int x = nums[i];
        upd(x, n+1, 1, x%2);
        koi[x] = (x+1)/2 - kuery(x, x%2);
    }

    for(int i=0; i<n; i+=2){
        insert(rutstod, i/2, 0);
    }
    for(int i=1; i<n; i+=2){
        insert(rutstev, i/2, 0);
    }
    for(int i=0; i<n; i+=2){
        insert(rootod, i/2, i+1);
    }
    for(int i=1; i<n; i+=2){
        insert(rootev, i/2, i+1);
    }

    for(int i=0; i<n-3; i++){

        int boshbe = nums[i], dorkar = stet[i];
        int curstet;
        if(i%2==0){
            if(query(rootod, 0, 0)==boshbe){
                curstet = query(rutstod, 0, 0)%2;
                if(curstet!=dorkar){
                    Reverse(rootev, 0, 1);
                    Reverse(rutstev, 0, 1);
                }
            }
            else if(query(rootod, 1, 1)==boshbe){
                curstet = query(rutstod, 1, 1)%2;
                update(rutstev, 0, 0, 1);
                update(rutstod, 0, 0, 1);
                Reverse(rutstod, 0, 1);
                Reverse(rootod, 0, 1);

                if(curstet==dorkar){
                    Reverse(rootev, 0, 1);
                    Reverse(rutstev, 0, 1);
                }
            }
            else{
                int pos = koi[boshbe];
                assert(query(rootod, pos, pos)==boshbe);
                curstet = query(rutstod, pos, pos)%2;
                update(rutstev, 0, pos-1, 1);
                update(rutstod, 0, pos-1, 1);
                cycshift(rootod, 0, pos);
                cycshift(rutstod, 0, pos);

                if( (pos % 2)^curstet != dorkar ){
                    Reverse(rootev, 0, 1);
                    Reverse(rutstev, 0, 1);
                }
            }
            Del(rootod, 0);
            Del(rutstod, 0);
        }
        else{
            if(query(rootev, 0, 0)==boshbe){
                curstet = query(rutstev, 0, 0)%2;
                if(curstet!=dorkar){
                    Reverse(rootod, 0, 1);
                    Reverse(rutstod, 0, 1);
                }
            }
            else if(query(rootev, 1, 1)==boshbe){
                curstet = query(rutstev, 1, 1)%2;
                update(rutstev, 0, 0, 1);
                update(rutstod, 0, 0, 1);
                Reverse(rutstev, 0, 1);
                Reverse(rootev, 0, 1);

                if(curstet==dorkar){
                    Reverse(rootod, 0, 1);
                    Reverse(rutstod, 0, 1);
                }
            }
            else{
                int pos = koi[boshbe];
                assert(query(rootev, pos, pos)==boshbe);
                curstet = query(rutstev, pos, pos)%2;
                update(rutstev, 0, pos-1, 1);
                update(rutstod, 0, pos-1, 1);
                cycshift(rootev, 0, pos);
                cycshift(rutstev, 0, pos);

                if( (pos % 2)^curstet != dorkar ){
                    Reverse(rootod, 0, 1);
                    Reverse(rutstod, 0, 1);
                }
            }
            Del(rootev, 0);
            Del(rutstev, 0);
        }

    }
    if((n-2)%2==0){
        if(nums[n-2]!=query(rootod, 0, 0)) NA();
    }
    else{
        if(nums[n-2]!=query(rootev, 0, 0)) NA();
    }
//    cout<<"wtff "<<endl;

    int X,Y,xstet,ystet;
    if((n-1)%2==0){
        X = query(rootod, 0, 0), Y = query(rootod, 1, 1);
        xstet = query(rutstod, 0, 0)%2, ystet = query(rutstod, 1, 1)%2;
        if(stet[n-2]!=query(rutstev,0,0)%2){
            swap(X,Y), swap(xstet, ystet);
            xstet^=1, ystet^=1;
        }
    }
    else{
        X = query(rootev, 0, 0), Y = query(rootev, 1, 1);
        xstet = query(rutstev, 0, 0)%2, ystet = query(rutstev, 1, 1)%2;
        if(stet[n-2]!=query(rutstod,0,0)%2){
            swap(X,Y), swap(xstet, ystet);
            xstet^=1, ystet^=1;
        }
    }

//    cout<<"etodur "<<endl;

    if(X!=nums[n-3] or Y!=nums[n-1]){
        NA();
    }
    xstet^=stet[n-3], ystet^=stet[n-1];


    if((xstet^ystet)==0) cout<<"Yes";
    else NA();

}
/*

*/


Measured memory_bytes: 17912