/*
* Problem :: 1976 / 여행 가자
*
* Kind :: Union Find
*
* Insight
* - 여행 중, 어느 도시를 중복해서 많이 들리는 것은 상관없다
* 여행경로안의 도시들끼리 서로 연결되어 있기만 하면 된다
* + 연결... 서로 중복되지 않음...
* 각 도시들을 원소로 생각하면...
* # Disjoint Set!!!
* Union Find!!!
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <algorithm>
using namespace std;
#define endl '\n'
// Set up : Global Variables
int P[200+1], R[200+1];
// Set up : Functions Declaration
int find(int x);
void merge(int x, int y);
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; cin >> N;
int M; cin >> M;
for (int i=1; i<=N; i++) { P[i] = i, R[i] = 1; }
for (int i=1; i<=N; i++) {
for (int j=1; j<=N; j++) {
bool isConn; cin >> isConn;
// Process
if (isConn) { /* 도시 i 와 j 가 연결되어있다면 */
/* 도시 i 가 속한 집합과 도시 j 가 속한 집합을 합침 */
if (find(i) != find(j)) {
merge(i, j);
}
}
}
}
// Set up: Input
int C[M];
for (int i=0; i<M; i++)
cin >> C[i];
// Process
bool isPossible = true;
for (int i=0; i<M-1; i++) {
/* 여행경로에서 인접한 도시들간의 집합이 서로 다르다면 */
if (find(C[i]) != find(C[i+1])) {
isPossible = false; /* 여행 불가 */
break;
}
}
// Control : Output
cout << ((isPossible) ? "YES" : "NO") << endl;
}
// Helper Functions
int find(int x)
/* 도시 x 의 대표도시를 반환하는 함수 */
{
if (P[x] == x) return x;
return P[x] = find(P[x]);
}
void merge(int x, int y)
/* 도시 x 가 속한 집합과 도시 y 가 속한 집합을 합치는 함수 */
{
x = find(x), y = find(y);
if (x == y) return;
if (R[x] < R[y]) swap(x, y);
P[y] = x;
if (R[x] == R[y]) R[x]++;
}