#include <bits/stdc++.h>
using namespace std;
const long long INF =
    sizeof(long long) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const long long MOD = (long long)(1e9) + 7;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
using Index = long long;
using Flow = long long;
using Cost = double;
const Flow kInfCapacity = INF;
const Cost kInfCost = INF;
struct MinimumCostMaximumFlow {
  struct Edge {
    Index s, d;
    Flow capacity;
    Cost cost;
  };
  using Edges = vector<Edge>;
  using Graph = vector<Edges>;
  Graph g;
  void init(Index n) { g.assign(n, Edges()); }
  void addArc(Index i, Index j, Flow capacity = kInfCapacity,
              Cost cost = Cost()) {
    Edge e, f;
    e.d = j, f.d = i;
    e.capacity = capacity, f.capacity = 0;
    e.cost = cost, f.cost = -cost;
    g[i].push_back(e);
    g[j].push_back(f);
    g[i].back().s = (Index)g[j].size() - 1;
    g[j].back().s = (Index)g[i].size() - 1;
  }
  void addEdge(Index i, Index j, Flow capacity = kInfCapacity,
               Cost cost = Cost()) {
    addArc(i, j, capacity, cost);
    addArc(j, i, capacity, cost);
  }
  pair<Cost, Flow> minimumCostMaximumFlow(Index s, Index t,
                                          Flow f = kInfCapacity,
                                          bool useSPFA = false) {
    long long n = g.size();
    vector<Cost> dist(n);
    vector<Index> prev(n);
    vector<Index> prev_edge(n);
    pair<Cost, Flow> total = make_pair(0, 0);
    vector<Cost> potential(n);
    while (f > 0) {
      fill(dist.begin(), dist.end(), kInfCost);
      if (useSPFA || total.second == 0) {
        deque<Index> q;
        q.push_back(s);
        dist[s] = 0;
        vector<bool> inqueue(n);
        while (!q.empty()) {
          Index i = q.front();
          q.pop_front();
          inqueue[i] = false;
          for (Index ei = 0; ei < g[i].size(); ei++) {
            const Edge &e = g[i][ei];
            Index j = e.d;
            Cost d = dist[i] + e.cost;
            if (e.capacity > 0 && d < dist[j]) {
              if (!inqueue[j]) {
                inqueue[j] = true;
                q.push_back(j);
              }
              dist[j] = d;
              prev[j] = i;
              prev_edge[j] = ei;
            }
          }
        }
      } else {
        vector<bool> vis(n);
        priority_queue<pair<Cost, Index> > q;
        q.push(make_pair(-0, s));
        dist[s] = 0;
        while (!q.empty()) {
          Index i = q.top().second;
          q.pop();
          if (vis[i]) continue;
          vis[i] = true;
          for (Index ei = 0; ei < (Index)g[i].size(); ei++) {
            const Edge &e = g[i][ei];
            if (e.capacity <= 0) continue;
            Index j = e.d;
            Cost d = dist[i] + e.cost + potential[i] - potential[j];
            if (dist[j] > d) {
              dist[j] = d;
              prev[j] = i;
              prev_edge[j] = ei;
              q.push(make_pair(-d, j));
            }
          }
        }
      }
      if (dist[t] == kInfCost) break;
      if (!useSPFA)
        for (Index i = 0; i < n; i++) potential[i] += dist[i];
      Flow d = f;
      Cost distt = 0;
      for (Index v = t; v != s;) {
        Index u = prev[v];
        const Edge &e = g[u][prev_edge[v]];
        d = min(d, e.capacity);
        distt += e.cost;
        v = u;
      }
      f -= d;
      total.first += d * distt;
      total.second += d;
      for (Index v = t; v != s; v = prev[v]) {
        Edge &e = g[prev[v]][prev_edge[v]];
        e.capacity -= d;
        g[e.d][e.s].capacity += d;
      }
    }
    return total;
  }
};
using Num = double;
using Vec = vector<Num>;
using Mat = vector<Vec>;
Vec gaussianElimination(Mat A, Vec b) {
  const long long n = A.size(), m = A[0].size();
  long long pi = 0, pj = 0;
  while (pi < n && pj < m) {
    for (long long i = pi + 1; i < n; i++)
      if (abs(A[i][pj]) > abs(A[pi][pj])) A[i].swap(A[pi]), swap(b[i], b[pi]);
    if (abs(A[pi][pj]) > 0) {
      Num d = A[pi][pj];
      for (long long j = 0; j < m; j++) A[pi][j] /= d;
      b[pi] /= d;
      for (long long i = pi + 1; i < n; i++) {
        Num k = A[i][pj];
        for (long long j = 0; j < m; j++) A[i][j] -= k * A[pi][j];
        b[i] -= k * b[pi];
      }
      pi++;
    }
    pj++;
  }
  for (long long i = pi; i < n; i++)
    if (abs(b[i]) > 0) return Vec();
  if (pi < m || pj < m) return Vec();
  for (long long j = m - 1; j >= 0; j--)
    for (long long i = 0; i < j; i++) b[i] -= b[j] * A[i][j];
  return b;
}
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  long long T;
  cin >> T;
  cout << fixed << setprecision(10);
  while (T--) {
    long long N, s, t, F;
    cin >> N >> s >> t >> F;
    MinimumCostMaximumFlow mcf;
    mcf.init(N + N);
    Mat a(N, Vec(N));
    Vec c(N);
    for (long long i = (0); i < (N); i++)
      for (long long j = (0); j < (N + 1); j++) {
        if (j == N)
          cin >> c[i];
        else
          cin >> a[i][j];
      }
    Vec x = gaussianElimination(a, c);
    ;
    for (long long i = (0); i < (N); i++) {
      long long M;
      cin >> M;
      vector<long long> d(M);
      for (long long j = (0); j < (M); j++) {
        cin >> d[j];
      }
      vector<long long> f(M);
      for (long long j = (0); j < (M); j++) {
        cin >> f[j];
      }
      for (long long j = (0); j < (M); j++) {
        mcf.addArc(N + i, d[j], f[j], abs(x[i] - x[d[j]]));
      }
      mcf.addArc(i, N + i, INF, 0);
    }
    auto res = mcf.minimumCostMaximumFlow(s, N + t, F);
    if (res.second != F)
      cout << "impossible" << endl;
    else
      cout << res.first << endl;
  }
  return 0;
}
