#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define INF 1001001001
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mp make_pair
#define pii pair<int,int>
#define ll long long
#define vi vector<int>
#define SZ(x) ((int)((x).size()))
#define fi first
#define se second
#define wez(n) int (n); scanf("%d",&(n));
#define wez2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
#define wez3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
inline void pisz(int n) { printf("%d\n",n); }
template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR(i,SZ(t))s<<t[i]<<" ";return s; }
#define DBG(vari) cerr<<"["<<__LINE__<<"] "<<#vari<<" = "<<(vari)<<endl;
#define ALL(t) t.begin(),t.end()
#define FOREACH(i,t) for (__typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define TESTS wez(testow)while(testow--)
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define REPD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
#define REMAX(a,b) (a)=max((a),(b));
#define REMIN(a,b) (a)=min((a),(b));
#define IOS ios_base::sync_with_stdio(0);

constexpr int N = 204;
namespace scc {
int n,       // input
ind[N],    // temp
lowlink[N],  // temp
onstack[N],  // temp
last,        // temp
n2,          // output
t[N];        // output
vi adj[N],   // input
st;          // temp

void go (int v) {
   ind[v] = lowlink[v] = ++last;
   st.pb(v);
   onstack[v] = 1;
   FOREACH(w,adj[v]) {
      if (!ind[*w]) {
         go(*w);
         lowlink[v] = min(lowlink[v], lowlink[*w]);
      } else if (onstack[*w]) {
         lowlink[v] = min(lowlink[v], lowlink[*w]);
      }
   }
   if (lowlink[v] == ind[v]) { // v is a root node
      ++n2;
      for (int w = -1; w != v; ) {
         w = st.back();
         st.pop_back();
         onstack[w] = 0;
         t[w] = n2;
      }
   }
}

void scc() {
   last = n2 = 0;
   FORI(i,n) ind[i] = onstack[i] = 0;
   FORI(i,n) if (!ind[i]) go(i);
   FORI(i,n) t[i] = n2 + 1 - t[i]; // zeby byl zwykly porzadek topologiczny
}

int sz[N];

};

vector<bool> sito (int m) { // m = max_inclusive
   vector<bool> pr(m+1,1);
   pr[0] = pr[1] = 0;
   for (int x = 2; x*x <= m; ++x) if (pr[x]) for (int y = x*x; y <= m; y += x) pr[y] = 0;
   return pr;
}

vi listaPierwszych (int m) { // m = max_inclusive
   vector<bool> pr = sito(m);
   vi ans;
   FORI(i,m) if (pr[i]) ans.pb(i);
   return ans;
}
ll egcd(ll a, ll b, ll &x, ll &y) {
	if (b == 0) {
		x = 1;
		y = 0;
		return a;
	}
	ll d = egcd(b, a%b, y, x);
	y = a - x*(a/b) - y;
	x = b - x;
	return d;
}

ll inverse(ll a, ll p) {
   ll x,y;
   egcd(a%p + p, p, x, y);
   return x%p;
}
// rozwiazuje uklad kongruencji
// x = a (mod m)
// x = b (mod n)
// zwraca res, gdzie x = res (mod nww(m,n))
// zle => rzuca wyjątek 0 (trzeba obudować w try { ... } catch (int _) {...})
ll CRT(ll a, ll m, ll b, ll n) {
	b = (b+n-(a%n))%n;
	ll d = __gcd(m,n);
	if (b%d != 0) {DBG("zle");exit(1);} //throw 0;
	ll old_m = m;
	m/=d; b/=d; n/=d;
	return ((b*inverse(m,n))%n)*old_m + a;
}

ll nww(ll a, ll b) {
   return a/__gcd(a,b)*b;
}

// nic ciekawego: rozwiazuje wiekszy uklad kongruencji
ll rozwiaz(vector<pair<ll,ll> > cong) {
   //DBG(cong);
   //exit(1);
	FORI(i,SZ(cong)-1) {
		cong[0].fi = CRT(cong[0].fi, cong[0].se, cong[i].fi, cong[i].se);
		cong[0].se = nww(cong[0].se, cong[i].se);

	}
	return cong[0].fi;
}

typedef bitset<N> bs;
bs adj[N], adjtr[N];
bs initial, fin;
bs image[N*N], backimage[N*N];
char temp[N];

int sl[N];
bool important[N];

vi primepows;
vector<pii> seqs, toCheck[1000];
int val[1000];

void go (int i) {
   if (i == SZ(primepows)) {
      // udalo sie
      //DBG("super");
      // rozwiaz kongruencje
      //try {
      vector<pair<ll,ll>> cong;
      FOR(j,SZ(primepows)) cong.pb(mp(val[j], primepows[j]));
      cout << rozwiaz(cong);
      exit(0);
      //} catch (int _) {DBG("lol")}
   } else {
      //DBG(i)
      for (val[i] = 0; val[i] < primepows[i]; ++val[i]) {
         // czy ok?
         bool ok = 1;
         for (const pii &p: seqs) { //toCheck[i]) {
            // czy sensowny
            bool sensowny = 1;
            REP(j,i+1,SZ(primepows)-1) if (p.se % primepows[j] == 0) sensowny = 0;
            if (!sensowny) continue;

            bool zle = 1;
            REP(j,0,i) if (p.se % primepows[j] == 0) {
               if ((val[j] - p.fi) % primepows[j] != 0) {
                  zle=0; break;
               }
            }
            if (zle) {ok = 0; break;}
         }
         if (ok) go(i+1);
      }
   }
}


int main () {
   wez3(n,b,r);
   REP(i,b,n-1) fin[i] = 1;
   FOR(i,n) {
      scanf("%s", temp);
      FOR(j,n) {
         if (temp[j] == '1') adj[i][j] = adjtr[j][i] = 1;
      }
   }
   while (r--) {
      wez(x)
      initial[x-1] = 1;
   }
   image[0] = initial;
   if (!(image[0] & fin).any()) {
      pisz(0);
      return 0;
   }
   REP(k,1,n*n) {
      FOR(i,n) if (image[k-1][i]) image[k] |= adj[i];
      if (!(image[k] & fin).any()) {
         pisz(k);
         return 0;
      }
   }

   // algorytm Sawy
   scc::n = n;
   FOR(i,n) FOR(j,n) if (adj[i][j]) scc::adj[i+1].pb(j+1);
   scc::scc();
   FOR(i,n) scc::sz[scc::t[i+1]]++;
   //DBG(scc::n2)

   FOR(i,n) if (scc::sz[scc::t[i+1]] > 1) {
      bs reach;
      reach[i] = 1;
      sl[i] = 0;
      do {
         ++sl[i];
         bs nxt;
         FOR(j,n) if (reach[j]) nxt |= adj[j];
         reach = move(nxt);
      } while (!reach[i]);
   }
   FOR(i,n) if (sl[i] > 0) {
      important[i] = 1;
      FOR(j,n) if (scc::t[i+1] == scc::t[j+1]) if (sl[j] > sl[i]) important[i] = 0;
   }
   backimage[0] = fin;
   REP(k,1,n*n) {
      FOR(i,n) if (backimage[k-1][i]) backimage[k] |= adjtr[i];
   }

   FOR(i,n) if (important[i]) if (image[n-1][i]) {
      REP(cp,n*n-n-sl[i],n*n-n-1) if (backimage[cp][i]) {
         seqs.pb(mp(cp + n-1, sl[i]));
      }
   }
   for (pii &p : seqs) {
      p.fi %= p.se;
   }
   //DBG(seqs)
   if (seqs.empty()) {
      printf("-1"); return 0;
   }

   // odciecie
   for (const pii &p: seqs) {
      vector<bool> ok(p.se, 1);
      for (const pii &q: seqs) {
         if (p.se % q.se == 0) {
            for (int c = q.fi; c < p.se; c += q.se) {
               ok[c] = 0;
            }
         }
      }
      if (ok == vector<bool>(p.se, 0)) {
         DBG("odcinam")
         pisz(-1); return 0;
      }
   }
   DBG("tu");
   DBG(seqs);

   vi prs = listaPierwszych(200);
   for (int pr : prs) {
      int pwpr = 1, maxPw = 0;
      REP(pw,1,7) {
         pwpr *= pr;
         for (const pii &p: seqs) {
            if (p.se % pwpr == 0) maxPw = pw;
         }
      }
      if (maxPw > 0) {
         pwpr = 1;
         FOR(u,maxPw) pwpr *= pr;
         primepows.pb(pwpr);
      }
   }
   random_shuffle(ALL(primepows));
   DBG("tu");
go(0);



   pisz(-1);
}
