#include <iostream>
#include <vector>
#include <queue>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;

#define EPS (1e-8)
#define MAX_V 102
#define INF 999999999

typedef vector<double> vec;
typedef vector<vec> mat;
typedef pair<double,int> P;

struct edge{
  int to, cap;
  double cost;
  int rev;
};

int V;
vector<edge> G[MAX_V];
double dist[MAX_V], h[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, double cost){
  G[from].push_back((edge){to, cap, cost, G[to].size()});
  G[to].push_back((edge){from, 0, -cost, G[from].size() - 1});
}

double min_cost_flow(int s, int g, int f){
  double res = 0;
  fill(h, h + V, 0);

  while(f > 0){
    priority_queue<P, vector<P>, greater<P> > que;
    fill(dist , dist + V , INF);
    dist[s] = 0;
    que.push(P(0, s));

    while(!que.empty()){
      P p = que.top(); que.pop();
      int v = p.second;
      if(dist[v] < p.first) continue;
      for(int i = 0; i < G[v].size(); i++){
        edge &e = G[v][i];
        if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to] + EPS){
          dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
          prevv[e.to] = v;
          preve[e.to] = i;
          que.push(P(dist[e.to], e.to));
        }
      }
    }

    if(dist[g] == INF){
      return -1;
    }
    for(int v = 0; v < V; v++){
      h[v] += dist[v];
    }

    int d = f;
    for(int v = g; v != s; v = prevv[v]){
      d = min(d, G[prevv[v]][preve[v]].cap);
    }
    f -= d;
    res += d * h[g];
    for(int v = g; v != s; v = prevv[v]){
      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}

// Ax=bを解く. Aは正方行列
// 解がないか, 一意でない場合は長さ0の配列を返す
vec gauss_jordan(const mat &A, const vec &b){
  int n = A.size();
  mat B(n, vec(n + 1));

  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      B[i][j] = A[i][j];
    }
  }

  for(int i = 0; i < n; i++){
    B[i][n] = b[i];
  }

  for(int i = 0; i < n; i++){
    int pivot = i;
    for(int j = i; j < n; j++){
      if(abs(B[j][i]) > abs(B[pivot][i])){
        pivot = j;
      }
    }
    swap(B[i], B[pivot]);

    if(abs(B[i][i]) < EPS) return vec();

    for(int j = i + 1; j <= n; j++){
      B[i][j] /= B[i][i];
    }
    for(int j = 0; j < n; j++){
      if(i != j){
        for(int k = i + 1; k <= n; k++){
          B[j][k] -= B[j][i] * B[i][k];
        }
      }
    }
  }

  vec x(n);
  for(int i = 0; i < n; i++){
    x[i] = B[i][n];
  }
  return x;
}

int main(){
  int T;
  cin >> T;

  while(T--){
    int N, S, T;
    double F;
    cin >> N >> S >> T >> F;

    V = N;
    for(int i = 0; i < MAX_V; i++){
      G[i].clear();
    }

    mat a(N, vec(N));
    vec c(N);

    for(int i = 0; i < N; i++){
      for(int j = 0; j < N; j++){
        cin >> a[i][j];
      }
      cin >> c[i];
    }

    vec x = gauss_jordan(a, c);

    for(int i = 0; i < N; i++){
      int m;
      cin >> m;

      int to[N], cap[N];

      for(int j = 0; j < m; j++) cin >> to[j];
      for(int j = 0; j < m; j++) cin >> cap[j];
      for(int j = 0; j < m; j++)
        add_edge(i, to[j], cap[j], fabs(x[i] - x[to[j]]));
    }

    double ans = min_cost_flow(S, T, F);

    if(ans == -1){
      cout << "impossible" << endl;
    }
    else{
      cout << fixed << setprecision(10) << ans << endl;
    }
  }
}

Measured memory_bytes: 2088