#include using namespace std; // #define LOCAL // 提出時はコメントアウト #define DEBUG_ typedef long long ll; const double EPS = 1e-9; const ll INF = ((1LL<<62)-(1LL<<31)); typedef vector vecl; typedef pair pairl; template using uset = unordered_set; template using mapv = map>; template using umap = unordered_map; #define ALL(v) v.begin(), v.end() #define REP(i, x, n) for(int i = x; i < n; i++) #define rep(i, n) REP(i, 0, n) #define sz(x) (ll)x.size() ll llceil(ll a,ll b) { return (a+b-1)/b; } template inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; } template inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; } template vector> genarr(ll n, ll m, T init) { return vector>(n,vector(m,init)); } ///// DEBUG #define DUMPOUT cerr #define repi(itr, ds) for (auto itr = ds.begin(); itr != ds.end(); itr++) templateistream&operator>>(istream&is,vector&vec){for(T&x:vec)is>>x;return is;} templateostream&operator<<(ostream&os,pair&pair_var){os<<"("<ostream&operator<<(ostream&os,const vector&vec){os<<"{";for(int i=0;iostream&operator<<(ostream&os,map&map_var){os<<"{";repi(itr,map_var){os<<*itr;itr++;if(itr!=map_var.end())os<<", ";itr--;} os<<"}";return os;} templateostream&operator<<(ostream&os,set&set_var){os<<"{";repi(itr,set_var){os<<*itr;itr++;if(itr!=set_var.end())os<<", ";itr--;} os<<"}";return os;} void dump_func(){DUMPOUT<void dump_func(Head&&head,Tail&&...tail){DUMPOUT<0){DUMPOUT<<", ";} dump_func(std::move(tail)...);} #ifndef LOCAL #undef DEBUG_ #endif #ifdef DEBUG_ #define DEB #define dump(...) \ DUMPOUT << " " << string(#__VA_ARGS__) << ": " \ << "[" << to_string(__LINE__) << ":" << __FUNCTION__ << "]" \ << endl \ << " ", \ dump_func(__VA_ARGS__) #else #define DEB if (false) #define dump(...) #endif ////////// #pragma GCC target("avx2") #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") // @param m `1 <= m` // @return x mod m constexpr long long safe_mod(long long x, long long m) { x %= m; if (x < 0) x += m; return x; } // @param b `1 <= b` // @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g constexpr std::pair inv_gcd(long long a, long long b) { a = safe_mod(a, b); if (a == 0) return {b, 0}; // Contracts: // [1] s - m0 * a = 0 (mod b) // [2] t - m1 * a = 0 (mod b) // [3] s * |m1| + t * |m0| <= b long long s = b, t = a; long long m0 = 0, m1 = 1; while (t) { long long u = s / t; s -= t * u; m0 -= m1 * u; // |m1 * u| <= |m1| * s <= b // [3]: // (s - t * u) * |m1| + t * |m0 - m1 * u| // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u) // = s * |m1| + t * |m0| <= b auto tmp = s; s = t; t = tmp; tmp = m0; m0 = m1; m1 = tmp; } // by [3]: |m0| <= b/g // by g != b: |m0| < b/g if (m0 < 0) m0 += b / s; return {s, m0}; } // 中国剰余: x ≡ y (mod z)の時、{y,z}を返す // 解が存在しない場合はy=0を返す std::pair crt(const std::vector& r, const std::vector& m) { assert(r.size() == m.size()); int n = int(r.size()); // Contracts: 0 <= r0 < m0 long long r0 = 0, m0 = 1; for (int i = 0; i < n; i++) { assert(1 <= m[i]); long long r1 = safe_mod(r[i], m[i]), m1 = m[i]; if (m0 < m1) { std::swap(r0, r1); std::swap(m0, m1); } if (m0 % m1 == 0) { if (r0 % m1 != r1) return {0, 0}; continue; } // assume: m0 > m1, lcm(m0, m1) >= 2 * max(m0, m1) // (r0, m0), (r1, m1) -> (r2, m2 = lcm(m0, m1)); // r2 % m0 = r0 // r2 % m1 = r1 // -> (r0 + x*m0) % m1 = r1 // -> x*u0*g % (u1*g) = (r1 - r0) (u0*g = m0, u1*g = m1) // -> x = (r1 - r0) / g * inv(u0) (mod u1) // im = inv(u0) (mod u1) (0 <= im < u1) long long g, im; std::tie(g, im) = inv_gcd(m0, m1); long long u1 = (m1 / g); // |r1 - r0| < (m0 + m1) <= lcm(m0, m1) if ((r1 - r0) % g) return {0, 0}; // u1 * u1 <= m1 * m1 / g / g <= m0 * m1 / g = lcm(m0, m1) long long x = (r1 - r0) / g % u1 * im % u1; // |r0| + |m0 * x| // < m0 + m0 * (u1 - 1) // = m0 + m0 * m1 / g - m0 // = lcm(m0, m1) r0 += x * m0; m0 *= u1; // -> lcm(m0, m1) if (r0 < 0) r0 += m0; } return {r0, m0}; } int main() { #ifdef LOCAL ifstream in("../../Atcoder/input.txt"); cin.rdbuf(in.rdbuf()); #endif ll N,K; cin>>N>>K; vecl P(N); iota(ALL(P),0LL); rep(i,K) { ll x,y; cin>>x>>y; swap(P[--x],P[--y]); } vecl to(N); // to[x]: xの位置はどこに行くか vector history(N); rep(i,N) { history[i].push_back(i), history[i].push_back(P[i]); to[P[i]] = i; } { vecl Q; Q = P; rep(j,N) { vecl R(N); rep(i,N) { R[to[i]] = Q[i]; history[to[i]].push_back(Q[i]); } Q = R; } } vecl window(N,0LL); vector pos(N,vecl(N,-1)); rep(i,N) { vecl seen(N,false); rep(j,sz(history[i])) { ll x = history[i][j]; if (seen[x]) { window[i] = j; break; } pos[i][x] = j; seen[x] = true; } } vecl A(N); ll Q; cin>>Q; rep(q,Q) { vecl X,W; bool ok = true; rep(i,N) { cin>>A[i]; X.push_back(pos[i][--A[i]]); W.push_back(window[i]); if (X[sz(X)-1] == -1) { ok = false; break; } } if (!ok) { cout << -1 << endl; continue; } auto [y,z] = crt(X,W); if (y == 0 && z == 0) cout << -1 << endl; else if (y == 0) cout << z << endl; else cout << y << endl; } return 0; }