#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>
#include <queue>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using namespace std;

template<class T>
constexpr T INF = ::numeric_limits<T>::max() / 32 * 15 + 208;

template <typename T>
using GPQ = priority_queue<T, vector<T>, greater<T>>;
using P = pair<int, int>;

int main() {
    int n, m;
    cin >> n >> m;
    vector<tuple<int, int, int>> t(m);
    vector<P> v;
    for (int i = 0; i < m; ++i) {
        int p, q, c;
        scanf("%d %d %d", &p, &q, &c);
        t[i] = make_tuple(p-1, q-1, c);
        v.emplace_back(p-1, c);
        v.emplace_back(q-1, c);
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    auto s = v.size();
    vector<vector<P>> G(s+n);
    auto getidx = [&](P a){ return lower_bound(v.begin(), v.end(), a)-v.begin();};
    for (auto &&i : t) {
        int p, q, c;
        tie(p, q, c) = i;
        auto x = getidx(P(p, c)), y = getidx(P(q, c));
        G[x].emplace_back(y, 0);
        G[y].emplace_back(x, 0);
        G[x].emplace_back(p+s, 1);
        G[p+s].emplace_back(x, 1);
        G[y].emplace_back(q+s, 1);
        G[q+s].emplace_back(y, 1);
    }
    vector<int> d(s+n, INF<int>);
    d[s] = 0;
    deque<P> Q;
    Q.emplace_front(0, s);
    while (!Q.empty()){
        int dist, u;
        tie(dist, u) = Q.front(); Q.pop_front();
        if(dist > d[u]) continue;
        for (auto &&e : G[u]) {
            int to, c;
            tie(to, c) = e;
            if(d[to] > d[u]+c){
                d[to] = d[u]+c;
                if(c == 0) Q.emplace_front(d[u], to);
                else Q.emplace_back(d[u]+1, to);
            }
        }
    }
    cout << (d[s+n-1] == INF<int> ? -1 : d[s+n-1]/2) << "\n";
    return 0;
}

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
const int N=1e5+2;
int n,inv[2],flip[2],pos[N],map[3][N];
struct B_I_T{
	int tr[N];
	inline void init(){
		memset(tr,0,sizeof(tr));
	}
	inline void add(int x,int v){
		for(;x<=n;x+=x&-x){
			tr[x]+=v;
		}
	}
	inline int ask(int x){
		int ans=0;
		for(;x;x-=x&-x){
			ans+=tr[x];
		}
		return ans;
	}
	inline void mod(const int x,const int y,const int v){
		if(x>y) return;
		add(x,v);
		add(y+1,-v);
	}
}ad;

inline bool conts(const int x,const int y,const int z){
	if(x<z) return y==x+1&&z==y+1;
	return x==y+1&&y==z+1;
}

inline char get_c(){
	static char buf[20000],*h,*t;
	if(h==t){
		t=(h=buf)+fread(buf,1,20000,stdin);
	}
	return h==t?EOF:*h++;
}

inline int nxi(){
	int x=0;
	char c;
	while((c=getchar())>'9'||c<'0');
	while(x=x*10+c-48,(c=getchar())>='0'&&c<='9');
	return x;
}

int main(){
#ifndef ONLINE_JUDGE
//	freopen("b.in","r",stdin);
#endif
	n=nxi();
	for(int i=0;i<3;++i){
		for(int j=1;j<=n;++j){
			map[i][j]=nxi();
		}
	}
	for(int i=1;i<=n;++i){
		int x=map[0][i],y=map[1][i],z=map[2][i],w=x>z?x:z;
		if(!conts(x,y,z)||w%3){
			puts("No");
			return 0;
		}
		if((i-w/3)&1){
			puts("No");
			return 0;
		}
		if(z!=w) inv[i&1]^=1;
		pos[w/3]=i;
	}
	for(int i=1;i<=n;i+=2){
		int p=pos[i],add=ad.ask(p);
		flip[1]=(flip[1]+(abs(p+add-i)>>1))&1;
		ad.mod(1,p,2);
	}
	ad.init();
	for(int i=2;i<=n;i+=2){
		int p=pos[i],add=ad.ask(p);
		flip[0]=(flip[0]+(abs(p+add-i)>>1))&1;
		ad.mod(1,p,2);
	}
	if((flip[0]-inv[1])&1||(flip[1]-inv[0])&1) puts("No");
	else puts("Yes");
	return 0;
}