#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>

using namespace std;

const int MAX_V = 100;
const int INF = 10000000;
const double EPS = 1e-8;
const int N = 100;
const int M = 1000;

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

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

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


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;
}

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 t, int f){
  double res = 0.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[t] == INF) return -1;
    for(int v=0;v<V;v++) h[v] += dist[v];
    int d = f;
    for(int v=t;v!=s;v=prevv[v]) d = min(d, G[prevv[v]][preve[v]].cap);
    f -= d;
    res += d * h[t];
    for(int v=t;v!=s;v=prevv[v]){
      edge &e = G[prevv[v]][preve[v]];
      e.cap -= d;
      G[v][e.rev].cap += d;
    }
  }
  return res;
}

void init(int n){
  V = n;
  for(int i=0;i<n;i++) G[i].clear();
}

main(){
  int T;
  cin >> T;
  for(int tc=1;tc<=T;tc++){
    int n, s, t, F;
    cin >> n >> s >> t >> F;
    init(n);
    mat A;
    vec b;
    vector<int> to[MAX_V];
    vector<int> cap[MAX_V];
    for(int i=0;i<n;i++){
      double in;
      vec a;
      for(int j=0;j<n;j++){
        cin >> in;
        a.push_back(in);
      }
      A.push_back(a);
      cin >> in;
      b.push_back(in);
    }
    for(int i=0;i<n;i++){
      int m;
      cin >> m;
      for(int j=0;j<m;j++){
        int in;
        cin >> in;
        to[i].push_back(in);
      }
      for(int j=0;j<m;j++){
        int in;
        cin >> in;
        cap[i].push_back(in);
      }
    }
    vec c = gauss_jordan(A, b);
    for(int i=0;i<n;i++){
      for(int j=0;j<to[i].size();j++){
        add_edge(i, to[i][j], cap[i][j], abs(c[i] - c[to[i][j]]));
      }
    }
    double ans = min_cost_flow(s, t, F);
    if(ans < 0.1) printf("impossible\n");
    else printf("%.10f\n", ans);
  }
}

Measured memory_bytes: 2156