#include <algorithm>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <type_traits>
#include <vector>

using namespace std;

#define rep(i, n) for (int64_t i = 0; i < (n); i++)
#define irep(i, n) for (int64_t i = 0; i <= (n); i++)
#define rrep(i, n) for (int64_t i = (n)-1; i >= 0; i--)
#define rirep(i, n) for (int64_t i = n; i >= 0; i--)

struct Foo {
  explicit Foo(int v) {}
  Foo operator+(const Foo& other) const { return *this; }
  Foo operator*(const Foo& other) const { return *this; }
  Foo operator/(const Foo& other) const { return *this; }
  Foo operator-() const { return *this; }
};
bool operator==(const Foo& lh, const Foo& other) { return true; }

template <typename F>
class Matrix {
  size_t m_col;
  vector<F> m_container;

 public:
  explicit Matrix(size_t row, size_t col)
      : m_col(col), m_container(row * col, (F)0) {}
  static Matrix eye(size_t row, size_t col) {
    Matrix ret(row, col);
    for (size_t i = 0; i < row; i++) ret(i, i) = 1;
    return ret;
  }
  size_t row() const { return m_container.size() / m_col; }
  size_t col() const { return m_col; }
  const F& operator()(size_t i, size_t j) const {
    return m_container[i * col() + j];
  }
  F& operator()(size_t i, size_t j) { return m_container[i * col() + j]; }
  void swap_row(size_t i, size_t j) {
    swap_ranges(m_container.begin() + i * col(),
                m_container.begin() + (i + 1) * col(),
                m_container.begin() + j * col());
  }
  void scale_row(size_t i, F s) {
    transform(m_container.begin() + i * col(),
              m_container.begin() + (i + 1) * col(),
              m_container.begin() + i * col(),
              [&](const F& value) { return value * s; });
  }
  void add_row(size_t i, size_t j, F s) {
    transform(m_container.begin() + i * col(),
              m_container.begin() + (i + 1) * col(),
              m_container.begin() + j * col(), m_container.begin() + i * col(),
              [&](const F& v0, const F& v1) { return v0 + s * v1; });
  }
  void gauss_jordan_forward(Matrix& b) {
    Matrix &lh = *this, &rh = b;
    size_t rank = 0;
    for (size_t i = 0; i < lh.col(); i++) {
      for (size_t j = rank; j < lh.row(); j++) {
        if (!is_zero(lh(j, i))) {
          lh.swap_row(rank, j);
          rh.swap_row(rank, j);

          const F s = lh(rank, i);
          lh.scale_row(rank, (F)1 / s);
          rh.scale_row(rank, (F)1 / s);

          for (size_t j = rank + 1; j < lh.row(); j++) {
            const F s = lh(j, i);
            lh.add_row(j, rank, -s);
            rh.add_row(j, rank, -s);
          }
          rank++;
          break;
        }
      }
    }
  }
  void gauss_jordan_backward(Matrix& b) {
    Matrix &lh = *this, &rh = b;
    for (int i = lh.col() - 1; i >= 0; i--) {
      for (int j = 0; j < i; j++) {
        const F s = -lh(j, i);
        lh.add_row(j, i, s);
        rh.add_row(j, i, s);
      }
    }
  }
  size_t rank() const {
    size_t j = 0;
    for (size_t i = 0; i < row(); i++) {
      while (j < col() && is_zero((*this)(i, j))) j++;
      if (j == col()) return i;
    }
  }

 private:
  static bool is_zero(const F& v) { return v == (F)0; };
};

template <>
bool Matrix<double>::is_zero(const double& v) {
  const double EPS = 1e-9;
  return abs(v) < EPS;
}

template <typename F>
ostream& operator<<(ostream& out, const Matrix<F>& m) {
  out << "[\n";
  for (size_t i = 0; i < m.row(); i++) {
    out << " [";
    for (size_t j = 0; j < m.col(); j++)
      out << setw(16) << fixed << setprecision(9) << m(i, j) << " , ";
    out << "],\n";
  }
  out << "]\n";
  return out;
}

void solve(int n, int s, int t) {
  vector<bool> is_signed;
  rep(i, n) {
    int q;
    cin >> q;
    is_signed.push_back(q == 1);
  }

  const int INF = n * 10 + 1;
  vector<vector<int>> w(n, vector<int>(n));
  rep(i, n) rep(j, n) { cin >> w[i][j]; }

  vector<vector<int>> dist(w);
  rep(i, n) rep(j, n) {
    if (i != j && dist[i][j] == 0) {
      dist[i][j] = INF;
    }
  }
  rep(k, n) rep(i, n) rep(j, n) {
    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
  }

  if (dist[s][t] >= INF) {
    cout << "impossible\n";
  }

  Matrix<double> mat(n, n), b(n, 1);
  rep(i, n) {
    if (i == t) {
      mat(i, i) = 1;
      b(i, 0) = 0;
      continue;
    }

    if (dist[i][t] >= INF) {
      rep(j, n) {
        mat(i, j) = 0;
        b(i, 0) = 0;
      }
    } else {
      vector<int> neighbor;
      rep(j, n) {
        if (j != i && w[i][j] != 0) {
          if (dist[i][t] == w[i][j] + dist[j][t] || !is_signed[i]) {
            neighbor.push_back(j);
          }
        }
      }

      int s = neighbor.size();
      mat(i, i) = 1;
      for (int idx : neighbor) {
        mat(i, idx) = -1.0 / s;
        b(i, 0) += (double)w[i][idx] / s;
      }
    }
  }

  mat.gauss_jordan_forward(b);
  mat.gauss_jordan_backward(b);

  cout << fixed << setprecision(9) << b(s, 0) << "\n";
}

int main() {
  int n, s, t;
  cin >> n >> s >> t;
  while (n != 0 || s != 0 || t != 0) {
    s--;
    t--;
    solve(n, s, t);
    cin >> n >> s >> t;
  }
  return 0;
}


Measured memory_bytes: 3368