#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <string>
#include <sstream>
#include <complex>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
using namespace std;
 
#define mod 1000000007
#define FOR(x,to) for(int x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
#define long long long
inline int rei(){int x;cin>>x;return x;}
inline long rel(){long x;cin>>x;return x;}
inline string res(){string x;cin>>x;return x;}
//------------------------------------------------------- 
class RealNumber {
public:
    using t = double;
    static t id() {
        return 0;
    }
	static t e() {
        return 1;
    }
	// * 
    static t Prod(const t& l, const t& r){
        return l * r;
    }
	// + 
	static t Plus(const t& l, const t& r){
        return l + r;
    }
	// - 
	static t Minus(const t& x){
        return -x;
    }
	// /
	static t Divide(const t& x) {
        return 1/x;
    }
	// <=
	static bool Smaller(const t& x,const t& y) {
        return x <= y;
    }
};
template< typename M >
struct Matrix{
	using T = typename M::t;
	int H;
	int W;
	vector<T> data;
    Matrix(int n_)
        : H(n_), W(n_), data(n_ * n_, M::id()) {}
    Matrix(int h_, int w_)
        : H(h_), W(w_), data(h_ * w_, M::id()) {}
	Matrix(int n_,vector<T> d_)
        : H(n_), W(n_) {data = d_;}
    Matrix(int h_, int w_, vector<T> d_)
        : H(h_), W(w_) {data = d_;}
  	void Update(int h,int w,T x){
    	data[h*W+w] = x;
  	}
  	const T Get(int h,int w){
    	return data[h*W+w];
  	}
	Matrix RowNormal(){
		vector<T> A(H*W);
		for(int i=0;i<H*W;i++){
			A[i] = data[i];
		}
		int rank = 0;
		for(int i=0;i<W;i++){
			int nonzero = rank;
			while(nonzero < H && A[nonzero*W+i] == M::id()){
				nonzero++;
			}
			if(nonzero == H){
				continue;
			}
			if(nonzero != rank){
				for(int j=i;j<W;j++){
					T temp = A[rank*W+j];
					A[rank*W+j] = A[nonzero*W+j];
					A[nonzero*W+j] = temp;
				}
			}
			{
				T d = M::Divide(A[rank*W+i]);
				for(int j=i;j<W;j++){
					A[rank*W+j] = M::Prod(A[rank*W+j],d);
				}
			}
			for(int j=0;j<H;j++){
				if(j == rank){
					continue;
				}
				T d = M::Minus(A[j*W+i]); 
				for(int k=i;k<W;k++){
					A[j*W+k] = M::Plus(A[j*W+k],M::Prod(A[rank*W+k],d));
				}
			}
			rank++;
		}	
		Matrix ans(H,W,A);
		return ans;
	}
	int Rank(){
		int ans = 0;
		vector<T> A(H*W);
		vector<bool> used(H);
		for(int i=0;i<H*W;i++){
			A[i] = data[i];
		}
		for(int i=0;i<W;i++){
			int nonzero = 0;
			while(nonzero < H && (used[nonzero] || A[nonzero*W+i] == M::id())){
				nonzero++;
			}
			if(nonzero == H){
				continue;
			}
			ans++;
			used[nonzero] = true;
			for(int j=0;j<H;j++){
				if(used[j]){
					continue;
				}
				T d = M::Minus(M::Prod(M::Divide(A[nonzero*W+i]),A[j*W+i])); 
				for(int k=i;k<W;k++){
					A[j*W+k] = M::Plus(A[j*W+k],M::Prod(A[nonzero*W+k],d));
				}
			}
		}	
		return ans;
	}
	//Mに順序が定義されている時 det Aが0でないと仮定
	vector<T> GaussianEliminationO(vector<T> b){
		int ans = 0;
		int N = H;
		vector<T> A(N*N);
		for(int i=0;i<N*N;i++){
			A[i] = data[i];
		}
		for(int i=0;i<N;i++){
			int maxj = i;
			for(int j=i+1;j<N;j++){
				if(M::Smaller(A[maxj*N+i],A[j*N+i])){
					maxj = j;
				}
			}
			if(maxj != i){
				for(int j=i;j<N;j++){
					T temp = A[i*N+j];
					A[i*N+j] = A[maxj*N+j];
					A[maxj*N+j] = temp;
				}
				{
					T temp = b[i];
					b[i] = b[maxj];
					b[maxj] = temp;
				}
			}
			{
				T d = M::Divide(A[i*N+i]);
				for(int j=i;j<N;j++){
					A[i*N+j] = M::Prod(A[i*N+j],d);
				}
				b[i] = M::Prod(b[i],d);
			}
			for(int j=0;j<N;j++){
				if(j == i){
					continue;
				}
				T d = M::Minus(A[j*N+i]); 
				for(int k=i;k<W;k++){
					A[j*N+k] = M::Plus(A[j*N+k],M::Prod(A[i*N+k],d));
				}
				b[j] = M::Plus(b[j],M::Prod(b[i],d));
			}
		}
		return b;
	}
	static Matrix I(int N){
		Matrix ans(N);
		for(int i=0;i<N;i++){
			ans.Update(i,i,M::e());
		}
		return ans;
	}
	static Matrix Plus(Matrix& A,Matrix& B){
		int h = A.H;
		int w = A.W;
		Matrix ans(h,w);
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				ans.Update(i,j,M::Plus(A.Get(i,j),B.Get(i,j)));
			}
		}
		return ans;
	}
	static Matrix Minus(Matrix& A){
		int h = A.H;
		int w = A.W;
		Matrix ans(h,w);
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				ans.Update(i,j,M::Minus(A.Get(i,j)));
			}
		}
		return ans;
	}
	static Matrix Minus(Matrix& A,Matrix& B){
		int h = A.H;
		int w = A.W;
		Matrix ans(h,w);
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				ans.Update(i,j,M::Plus(A.Get(i,j),M::Minus(B.Get(i,j))));
			}
		}
		return ans;
	}
	static Matrix Prod(Matrix& A,Matrix& B){
		int h = A.H;
		int w = B.W;
		int K = A.W;
		Matrix ans(h,w);
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				T c = M::id();
				for(int k=0;k<K;k++){
					c = M::Plus(c,M::Prod(A.Get(i,k),B.Get(k,j)));
				}
				ans.Update(i,j,c);
			}
		}
		return ans;
	}
	static Matrix Pow(Matrix A,long r){
		int n = A.H;
		vector<T> ans(n*n,M::id());
		for(int i=0;i<n;i++){
			ans[i*n+i] = M::e();
		}
		vector<T> ans2(n*n);
		vector<T> AP = A.data;
		vector<T> AP2(n*n);
		while(r){
			if(r % 2 == 1){
				for(int i=0;i<n;i++){
					for(int j=0;j<n;j++){
						T c = M::id();
						for(int k=0;k<n;k++){
							c = M::Plus(c,M::Prod(AP[i*n+k],ans[k*n+j]));
						}
						ans2[i*n+j] = c;
					}
				}
				swap(ans,ans2);
			}
			for(int i=0;i<n;i++){
				for(int j=0;j<n;j++){
					T c = M::id();
					for(int k=0;k<n;k++){
						c = M::Plus(c,M::Prod(AP[i*n+k],AP[k*n+j]));
					}
					AP2[i*n+j] = c;
				}
			}
			swap(AP,AP2);
			r /= 2;
		}
		Matrix answ(n,ans);
		return answ;
	}
};
int Distance[100][100];
int minDist[100];
int VertexToVertex[100];
bool Type[100];
bool finished[100];
void Calc(){
	while(1){
		int N = rei();
		int S = rei()-1;
		int T = rei()-1;
		if(N == 0 && S == -1 && T == -1){
			return;
		}
		for(int i=0;i<N;i++){
			Type[i] = rei() == 1;
		}
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				Distance[i][j] = rei();
			}
		}
		fill(finished,finished+N,false);
		fill(minDist,minDist+N,1000000000);
		minDist[T] = 0;
		while(1){
			int minc = 1000000000;
			int mincv = 0;
			for(int i=0;i<N;i++){
				if(!finished[i] && minDist[i] < minc){
					mincv = i;
					minc = minDist[i];
				}
			}
			finished[mincv] = true;
			if(minc == 1000000000){
				break;
			}
			for(int i=0;i<N;i++){
				if(Distance[mincv][i] != 0){
					minDist[i] = min(minDist[i],minc+Distance[mincv][i]);
				}
			}
		}
		if(!finished[S]){
			cout << "impossible" << endl;
			continue;
		}
		int n = 0;
		for(int i=0;i<N;i++){
			if(i != T && minDist[i] != 1000000000){
				VertexToVertex[n++] = i;
			}
		}
		vector<double> A(n*n);
		vector<double> B(n);
		for(int v=0;v<n;v++){
			if(Type[VertexToVertex[v]]){
				int c = 0;
				for(int i=0;i<n;i++){
					if(Distance[VertexToVertex[v]][VertexToVertex[i]] != 0 && Distance[VertexToVertex[v]][VertexToVertex[i]] + minDist[VertexToVertex[i]] == minDist[VertexToVertex[v]]){
						c++;
					}
				}
				if(Distance[VertexToVertex[v]][T] != 0 && Distance[VertexToVertex[v]][T] == minDist[VertexToVertex[v]]){
					c++;
				}
				A[v*n+v] = 1;
				double p = 1.0/c;
				for(int i=0;i<n;i++){
					if(Distance[VertexToVertex[v]][VertexToVertex[i]] != 0 && Distance[VertexToVertex[v]][VertexToVertex[i]] + minDist[VertexToVertex[i]] == minDist[VertexToVertex[v]]){
						A[v*n+i] -= p;
						B[v] += p*Distance[VertexToVertex[v]][VertexToVertex[i]];
					}
				}
				if(Distance[VertexToVertex[v]][T] != 0 && Distance[VertexToVertex[v]][T] == minDist[VertexToVertex[v]]){
					B[v] += p*Distance[VertexToVertex[v]][T];
				}
			}
			else{
				int c = 0;
				for(int i=0;i<n;i++){
					if(Distance[VertexToVertex[v]][VertexToVertex[i]] != 0){
						c++;
					}
				}
				if(Distance[VertexToVertex[v]][T]){
					c++;
				}
				A[v*n+v] = 1;
				double p = 1.0/c;
				for(int i=0;i<n;i++){
					if(Distance[VertexToVertex[v]][VertexToVertex[i]] != 0){
						A[v*n+i] -= p;
						B[v] += p*Distance[VertexToVertex[v]][VertexToVertex[i]];
					}
				}
				if(Distance[VertexToVertex[v]][T] != 0){
					B[v] += p*Distance[VertexToVertex[v]][T];
				}
			}
		}
		Matrix<RealNumber> Am(n,n,A);
		vector<double> X = Am.GaussianEliminationO(B);
		for(int i=0;i<n;i++){
			if(VertexToVertex[i] == S){
				printf("%1.10lf\n",X[i]);
			}
		}
	}
}
int main(int argc,char** argv){
	ios::sync_with_stdio(false), cin.tie(0);
	cout.tie(0); Calc(); return 0;
}


Measured memory_bytes: 3464