#include <bits/stdc++.h>

using namespace std;

#define rep(i,n) REP(i,0,n)
#define REP(i,s,e) for(int i=(s); i<(int)(e); i++)
#define repr(i, n) REPR(i, n, 0)
#define REPR(i, s, e) for(int i=(int)(s-1); i>=(int)(e); i--)
#define pb push_back
#define all(r) r.begin(),r.end()
#define rall(r) r.rbegin(),r.rend()
#define fi first
#define se second

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int INF = 1e9;
const ll MOD = 1e9 + 7;
double EPS = 1e-8;

// #define DEBUG_MODE
#ifdef DEBUG_MODE
#define dump(x) cout << #x << " : " << x << endl
#define LINE cout << "line : " << __LINE__ << endl
#define dumpV(v) cout << #v << " : ["; for(auto& t : v) cout << t << ", "; cout<<"]" << endl
#define STOP assert(false)
#else
#define dump(x) ;
#define LINE     ;
#define dumpV(v);
#define STOP     ;
#endif
#define mp make_pair

namespace std{
  template<class S,class T>
  ostream &operator <<(ostream& out,const pair<S,T>& a){
    out<<'('<<a.fi<<", "<<a.se<<')';
    return out;
  }
}



const int MAX_N = 5;
const int MAX_H = 20;
const int MAX_W = 20;
const int MAX_HW = MAX_H * MAX_W;


// vertex => y, x, mask | 20 * 20 * 2^5
// edge => (x, y, t)^2 | (400*40)^2

int dist[MAX_HW][1 << MAX_N];

int times[MAX_HW][MAX_HW];

bool isBomb[MAX_HW];

auto isOutOfRange = [](int h, int w, int H, int W) {
    return h < 0 || h >= H || w < 0 || w >= W;
};


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int W, H, N;
    cin >> W >> H >> N;
    int sx, sy;
    cin >> sx >> sy;
    --sx; --sy;
    vector<vector<int>> paths(N);
    rep(i, N) {
        int sz;
        cin >> sz;
        paths[i].resize(sz-1);
        rep(j, sz) {
            int x, y;
            cin >> x >> y;
            --x; --y;
            if (j + 1 == sz) isBomb[y * W + x] = true;
            else paths[i][j] = (y * W + x);
        }
    }
    int HW = H * W;
    {
        rep(i, HW) rep(j, HW) times[i][j] = (i == j ? 0 : INF);
        rep(y, H) rep(x, W) if (!isBomb[y * W + x]) {
            REP(dy, -1, 2) REP(dx, -1, 2)  if(dx|dy) {
                int nx = x + dx, ny = y + dy;
                if (isOutOfRange(ny, nx, H, W) || isBomb[ny * W + nx]) continue;
                times[y * W + x][ny * W + nx] = 1;
            }
        }
        rep(k, HW) rep(i, HW) rep(j, HW) times[i][j] = min(times[i][j], times[i][k] + times[k][j]);
    }
    rep(i, MAX_HW) rep(j, 1 << MAX_N) dist[i][j] = INF;
    using P = pair<int, pii>;
    priority_queue<P, vector<P>, greater<P> > q;
    {
        int mask = 0;
        int S = sy * W + sx;
        rep(i, N) {
            if (S == paths[i][0]) mask |= (1 << i);
        }
        dist[S][mask] = 0;
        q.push({0, {S, mask}});
    }

    {
        while (!q.empty()) {
            auto p = q.top(); q.pop();
            auto yx = p.se.fi, mask = p.se.se, t = p.fi;
            if (dist[yx][mask] < t) continue;
            dump(p);
            rep(i, N) if ((mask & (1 << i)) == 0) {
                int nmask = mask | (1<<i);
                REP(j, t, paths[i].size()) {
                    auto nyx = paths[i][j];
                    int dt = j - t;
                    dump(mp(i, j));
                    dump(times[yx][nyx]);
                    if(times[yx][nyx] <= dt && j < dist[nyx][nmask]) {
                        dist[nyx][nmask] = j;
                        q.push({j, {nyx, nmask}});
                    }
                }
            }
        }
    };
    int ans = INF;
    rep(i, HW) ans = min(ans, dist[i][(1<<N)-1]);
    cout << (ans == INF ? -1 : ans) << '\n';
    return 0;
}
