Problem:
H: ジャンプパーティ
問題
とあるダンスホールで $N$ 人の参加するダンスパーティーが行われる。
そのダンスホールは縦方向に $H$ 個、横方向に $W$ 個のグリッドに分けられており、
左上を $(0,0)$、上から $r$ マス、左から $c$ マス目のグリッドの座標を $(r,c)$ と表す。
$i$ 番目の参加者の初期位置は $(R_i, C_i)$ であり、$(i,j)$ のグリッドには $(r_{ij}, c_{ij})$ が書かれている。
各参加者は、無限に続く音楽に合わせて次のように同時に移動を行う。
その時にいる座標が $(i,j)$ のとき、$(r_{ij}, c_{ij})$ へジャンプで移動する。
それぞれのグリッドは狭く、2 人以上の参加者が同時に同じグリッドに移動すると衝突してしまう。ただし、空中で衝突することは無いとする。
これを聞いたあなたは、ジャンプ後に 2 人以上の参加者が衝突してしまわないかと心配になった。
そこで、衝突が起こる可能性があるか、あるならば何回目のジャンプの後に衝突が起こるかを求めることにした。
制約
$1 \le H,W \le 500$
$0 \le N \le H \times W$
$0 \le r_{ij} < H \ (0 \le i < H, 0 \le j < W)$
$0 \le c_{ij} < W \ (0 \le i < H, 0 \le j < W)$
$0 \le R_i < H \ (0 \le i < N)$
$0 \le C_i < W \ (0 \le i < N)$
参加者の初期位置は相異なる
入力形式
入力は以下の形式で与えられる。
$H \ W \ N$
$r_{00} \ c_{00} \ \cdots \ r_{0 \ W-1} \ c_{0 \ W-1}$
$\vdots$
$r_{H-1 \ 0} \ c_{H-1 \ 0} \ \cdots \ r_{H-1 \ W-1} \ c_{H-1 \ W-1}$
$R_0 \ C_0$
$\vdots$
$R_{N-1} \ C_{N-1}$
この問題では入力ファイルが非常に大きくなることがあることに注意せよ。
C++ なら
このページ
を参考にすると良いかもしれない。
出力
衝突が起こる場合は何回目のジャンプの後に起こるかを 1 行で出力せよ。
そうでない場合は -1 を出力せよ。
また、末尾に改行を出力せよ。
サンプル
サンプル入力 1
2 2 2
1 0 0 1
0 0 1 0
0 0
0 1
サンプル出力 1
-1
サンプル入力 2
2 2 2
1 0 0 1
0 0 1 0
0 0
1 1
サンプル出力 2
1

Submitted solutions:

code_snippet: // AOJ #2812
// Jump Party 2025.2.5

#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

int main(){
    int H = Cin(), W = Cin(), N = Cin();
    int total = H * W;
    
    vector<int> nextPos(total);
    for (int i = 0; i < H; i++){
        for (int j = 0; j < W; j++){
            int nr = Cin(), nc = Cin();
            int from = i * W + j;
            int to = nr * W + nc;
            nextPos[from] = to;
        }
    }
    
    // 初期位置（セル番号）を読み込む
    vector<int> initPos;
    initPos.reserve(N);
    for (int i = 0; i < N; i++){
        int r = Cin(), c = Cin();
        initPos.push_back(r * W + c);
    }
    
    // 参加者が 0 人または 1 人の場合は衝突は起こらない
    if (N <= 1) {
        Cout(-1);
        return 0;
    }
    
    // ダブリングの前計算
    // 最大のジャンプ回数はグリッドの大きさを上限にすれば十分
    int maxT = total; 
    int LOG = 0;
    while ((1 << LOG) <= maxT) LOG++;
    
    // dp[k][i] = セル i から 2^k 回ジャンプしたときのセル番号
    vector<vector<int>> dp(LOG, vector<int>(total));
    for (int i = 0; i < total; i++){
        dp[0][i] = nextPos[i];
    }
    for (int k = 1; k < LOG; k++){
        for (int i = 0; i < total; i++){
            dp[k][i] = dp[k-1][ dp[k-1][i] ];
        }
    }
    
    // 関数：start から t 回ジャンプした先のセル番号を返す
    auto jump = [&](int start, int t) -> int {
        int pos = start;
        for (int k = 0; k < LOG; k++){
            if (t & (1 << k)) pos = dp[k][pos];
        }
        return pos;
    };
    
    // 「t 回ジャンプ後に衝突が起こるか」をチェックする関数
    auto check = [&](int t) -> bool {
        vector<int> freq(total, 0);
        for (int pos : initPos) {
            int finalPos = jump(pos, t);
            freq[finalPos]++;
            if (freq[finalPos] >= 2)
                return true;
        }
        return false;
    };
    
    int lo = 1, hi = maxT + 1;
    int ans = -1;
    while (lo < hi) {
        int mid = lo + (hi - lo) / 2;
        if (check(mid)) ans = mid, hi = mid;
        else lo = mid + 1;
    }
    Cout(ans == -1? -1: ans);
    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 23644
final_rank: 3

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
//using uLL = unsigned __int128;
using str = string;
template <typename T> 
using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using pq = priority_queue<T>;
template <typename T>
using vec = vector<T>;
using pll = pair<long long, long long>;
using pii = pair<int, int>;
using vvvl = vector<vector<vector<ll>>>;
using vvl = vector<vector<ll>>;
using vi = vector<int>;
using vl = vector<ll>;
#define vvvm  vector<vector<vector<mint>>>
#define vvm  vector<vector<mint>>
#define vm  vector<mint>
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;
template <typename T>
using uset = unordered_set<T>;
#define rep(i, s, f) for(long long i = s; i <= f; i++)
#define rep1(i, s, f) for(long long i = s; i <= f; i++)
#define per(i, s, f) for(long long i = s; i >= f; i--)
#define per1(i, s, f) for(long long i = s; i >= f; i--)
#define eb(a) emplace_back(a)
#define pb(a) push_back(a)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define ins(x, l, r) (l <= x && x <= r)
#define ENDL '\n'
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）
template <typename T>
int LB(vector<T> &A, T x) {
    return lower_bound(A.begin(), A.end(), x) - A.begin();
}

template <typename T>
int UB(vector<T> &A, T x) {
    return upper_bound(A.begin(), A.end(), x) - A.begin();
}
template <typename T>
void UNIQUE(vector<T> &A, int indexed) {
    sort(A.begin() + indexed, A.end());
    A.erase(unique(A.begin() + indexed, A.end()), A.end());
}

template <typename T>
vector<T> erase(vector<T>& A, T& x) {
	vector<T> res;
	for(T a : A) if(a != x) res.emplace_back(a);
	return res;
}
string split(string& S, int l, int r) {
	return S.substr(l, r - l + 1);
}

int msb(long long a) {
    if(a == 0) return -1;
    return 64 - int(__builtin_clzll(a));
}
template<class T>
void chmin(T &a, T b) {
    if(a > b) a = b;
}
template<class T>
void chmax(T &a, T b) {
    if(a < b) a = b;
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll extgcd (ll a, ll b,  ll &x, ll &y) {
    if(b == 0) { x = 1;y = 0;return a;}
    ll d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
template <typename T>
T CEIL(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
    else return a / b;
}
template <typename T>
T FLOOR(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
    else return a/b - 1;
}
ll SQRT(ll a) {
    ll l = 0;
    ll r = 3037000499LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize "trapv" //お祈り。変数同士の演算でのみ感知。代入や、 a *= 10000 では感知しない。
const ll big = 1001001001;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // 座標平面において、(番兵) → ↓ ← ↑  ※ 右から時計回り 注 : グリッド or 座標で上下は反転する。
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
//const ll mod = 998244353;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using P = pair<short, short>;
using vvp = vec<vec<P>>;
using vp = vec<P>;
void solve() {
	ll H, W, N;
	cin >> H >> W >> N;
	vvp table(H+1, vp(W+1));
	rep(i,1,H) rep(j,1,W) {
		cin >> table[i][j].first >> table[i][j].second;
		table[i][j].first++, table[i][j].second++;
	}
	vl R(N+1), C(N+1);
	rep(i,1,N) {
		cin >> R[i] >> C[i];
		R[i]++, C[i]++;
	}

	const int M = 17;
	vec<vvp> dabu(M+1, vvp(H+1, vp(W+1)));
	rep(i,1,H)rep(j,1,W) {
		dabu[0][i][j] = table[i][j];
	}



	rep(p, 1, M) rep(i,1,H) rep(j,1,W) {
		auto[pi, pj] = dabu[p-1][i][j];
		dabu[p][i][j] = dabu[p-1][pi][pj];
	}



	auto jump = [&](int i, int j, ll step) {
		if(step==0) return P(i, j);
		rep(p, 0, M) {
			if(step >> p & 1) {
				auto [ni, nj] = dabu[p][i][j];
				i = ni;
				j = nj;
			}
		}
		return P(i, j);
	};

	auto out = [&](ll step) {
		set<P> cnt;
		rep(i,1,N) {
			auto nex = jump(R[i], C[i], step);
			if(cnt.count(nex)) return true;
			else cnt.insert(nex);
		}
		return false;
	};


	ll li = 0;
	ll ri = 250001;

	while(li < ri) {//xxxxxxooooooo
		ll mid = (li + ri)>>1;
		if(out(mid)) {
			ri = mid;
		}
		else {
			li = mid + 1;
		}
	}


	if(out(li)) {
		cout << li << endl;
	}
	else {
		cout << -1 << endl;
	}






	
    

    
    

}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 1440
memory_kb: 37740
final_rank: 14

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
//using uLL = unsigned __int128;
using str = string;
template <typename T> 
using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using pq = priority_queue<T>;
template <typename T>
using vec = vector<T>;
using pll = pair<long long, long long>;
using pii = pair<int, int>;
using vvvl = vector<vector<vector<ll>>>;
using vvl = vector<vector<ll>>;
using vi = vector<int>;
using vl = vector<ll>;
#define vvvm  vector<vector<vector<mint>>>
#define vvm  vector<vector<mint>>
#define vm  vector<mint>
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;
template <typename T>
using uset = unordered_set<T>;
#define rep(i, s, f) for(long long i = s; i <= f; i++)
#define rep1(i, s, f) for(long long i = s; i <= f; i++)
#define per(i, s, f) for(long long i = s; i >= f; i--)
#define per1(i, s, f) for(long long i = s; i >= f; i--)
#define eb(a) emplace_back(a)
#define pb(a) push_back(a)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define ins(x, l, r) (l <= x && x <= r)
#define ENDL '\n'
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）
template <typename T>
int LB(vector<T> &A, T x) {
    return lower_bound(A.begin(), A.end(), x) - A.begin();
}

template <typename T>
int UB(vector<T> &A, T x) {
    return upper_bound(A.begin(), A.end(), x) - A.begin();
}
template <typename T>
void UNIQUE(vector<T> &A, int indexed) {
    sort(A.begin() + indexed, A.end());
    A.erase(unique(A.begin() + indexed, A.end()), A.end());
}

template <typename T>
vector<T> erase(vector<T>& A, T& x) {
	vector<T> res;
	for(T a : A) if(a != x) res.emplace_back(a);
	return res;
}
string split(string& S, int l, int r) {
	return S.substr(l, r - l + 1);
}

int msb(long long a) {
    if(a == 0) return -1;
    return 64 - int(__builtin_clzll(a));
}
template<class T>
void chmin(T &a, T b) {
    if(a > b) a = b;
}
template<class T>
void chmax(T &a, T b) {
    if(a < b) a = b;
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll extgcd (ll a, ll b,  ll &x, ll &y) {
    if(b == 0) { x = 1;y = 0;return a;}
    ll d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
template <typename T>
T CEIL(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
    else return a / b;
}
template <typename T>
T FLOOR(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
    else return a/b - 1;
}
ll SQRT(ll a) {
    ll l = 0;
    ll r = 3037000499LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize "trapv" //お祈り。変数同士の演算でのみ感知。代入や、 a *= 10000 では感知しない。
const ll big = 1001001001;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // 座標平面において、(番兵) → ↓ ← ↑  ※ 右から時計回り 注 : グリッド or 座標で上下は反転する。
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
//const ll mod = 998244353;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using P = pair<short, short>;
using vvp = vec<vec<P>>;
using vp = vec<P>;
void solve() {
	ll H, W, N;
	cin >> H >> W >> N;
	vvp table(H+1, vp(W+1));
	rep(i,1,H) rep(j,1,W) {
		cin >> table[i][j].first >> table[i][j].second;
		table[i][j].first++, table[i][j].second++;
	}
	vl R(N+1), C(N+1);
	rep(i,1,N) {
		cin >> R[i] >> C[i];
		R[i]++, C[i]++;
	}

	const int M = 17;
	vec<vvp> dabu(M+1, vvp(H+1, vp(W+1)));
	rep(i,1,H)rep(j,1,W) {
		dabu[0][i][j] = table[i][j];
	}



	rep(p, 1, M) rep(i,1,H) rep(j,1,W) {
		auto[pi, pj] = dabu[p-1][i][j];
		dabu[p][i][j] = dabu[p-1][pi][pj];
	}



	auto jump = [&](int i, int j, ll step) {
		if(step==0) return P(i, j);
		rep(p, 0, M) {
			if(step >> p & 1) {
				auto [ni, nj] = dabu[p][i][j];
				i = ni;
				j = nj;
			}
		}
		return P(i, j);
	};

	auto out = [&](ll step) {
		set<P> cnt;
		rep(i,1,N) {
			auto nex = jump(R[i], C[i], step);
			if(cnt.count(nex)) return true;
			else cnt.insert(nex);
		}
		return false;
	};


	ll li = 0;
	ll ri = 500001;

	while(li < ri) {//xxxxxxooooooo
		ll mid = (li + ri)>>1;
		if(out(mid)) {
			ri = mid;
		}
		else {
			li = mid + 1;
		}
	}


	if(out(li)) {
		cout << li << endl;
	}
	else {
		cout << -1 << endl;
	}






	
    

    
    

}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 1340
memory_kb: 37836
final_rank: 12

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
//using uLL = unsigned __int128;
using str = string;
template <typename T> 
using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using pq = priority_queue<T>;
template <typename T>
using vec = vector<T>;
using pll = pair<long long, long long>;
using pii = pair<int, int>;
using vvvl = vector<vector<vector<ll>>>;
using vvl = vector<vector<ll>>;
using vi = vector<int>;
using vl = vector<ll>;
#define vvvm  vector<vector<vector<mint>>>
#define vvm  vector<vector<mint>>
#define vm  vector<mint>
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;
template <typename T>
using uset = unordered_set<T>;
#define rep(i, s, f) for(long long i = s; i <= f; i++)
#define rep1(i, s, f) for(long long i = s; i <= f; i++)
#define per(i, s, f) for(long long i = s; i >= f; i--)
#define per1(i, s, f) for(long long i = s; i >= f; i--)
#define eb(a) emplace_back(a)
#define pb(a) push_back(a)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define ins(x, l, r) (l <= x && x <= r)
#define ENDL '\n'
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）
template <typename T>
int LB(vector<T> &A, T x) {
    return lower_bound(A.begin(), A.end(), x) - A.begin();
}

template <typename T>
int UB(vector<T> &A, T x) {
    return upper_bound(A.begin(), A.end(), x) - A.begin();
}
template <typename T>
void UNIQUE(vector<T> &A, int indexed) {
    sort(A.begin() + indexed, A.end());
    A.erase(unique(A.begin() + indexed, A.end()), A.end());
}

template <typename T>
vector<T> erase(vector<T>& A, T& x) {
	vector<T> res;
	for(T a : A) if(a != x) res.emplace_back(a);
	return res;
}
string split(string& S, int l, int r) {
	return S.substr(l, r - l + 1);
}

int msb(long long a) {
    if(a == 0) return -1;
    return 64 - int(__builtin_clzll(a));
}
template<class T>
void chmin(T &a, T b) {
    if(a > b) a = b;
}
template<class T>
void chmax(T &a, T b) {
    if(a < b) a = b;
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll extgcd (ll a, ll b,  ll &x, ll &y) {
    if(b == 0) { x = 1;y = 0;return a;}
    ll d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
template <typename T>
T CEIL(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
    else return a / b;
}
template <typename T>
T FLOOR(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
    else return a/b - 1;
}
ll SQRT(ll a) {
    ll l = 0;
    ll r = 3037000499LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize "trapv" //お祈り。変数同士の演算でのみ感知。代入や、 a *= 10000 では感知しない。
const ll big = 1001001001;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // 座標平面において、(番兵) → ↓ ← ↑  ※ 右から時計回り 注 : グリッド or 座標で上下は反転する。
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
//const ll mod = 998244353;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using P = pair<short, short>;
using vvp = vec<vec<P>>;
using vp = vec<P>;
void solve() {
	ll H, W, N;
	cin >> H >> W >> N;
	vvp table(H+1, vp(W+1));
	rep(i,1,H) rep(j,1,W) {
		cin >> table[i][j].first >> table[i][j].second;
		table[i][j].first++, table[i][j].second++;
	}
	vl R(N+1), C(N+1);
	rep(i,1,N) {
		cin >> R[i] >> C[i];
		R[i]++, C[i]++;
	}

	const int M = 17;
	vec<vvp> dabu(M+1, vvp(H+1, vp(W+1)));
	rep(i,1,H)rep(j,1,W) {
		dabu[0][i][j] = table[i][j];
	}



	rep(p, 1, M) rep(i,1,H) rep(j,1,W) {
		auto[pi, pj] = dabu[p-1][i][j];
		dabu[p][i][j] = dabu[p-1][pi][pj];
	}



	auto jump = [&](int i, int j, ll step) {
		if(step==0) return P(i, j);
		rep(p, 0, M) {
			if(step >> p & 1) {
				auto [ni, nj] = dabu[p][i][j];
				i = ni;
				j = nj;
			}
		}
		return P(i, j);
	};

	auto out = [&](ll step) {
		set<P> cnt;
		rep(i,1,N) {
			auto nex = jump(R[i], C[i], step);
			if(cnt.count(nex)) return true;
			else cnt.insert(nex);
		}
		return false;
	};


	ll li = 0;
	ll ri = 2500001;

	while(li < ri) {//xxxxxxooooooo
		ll mid = (li + ri)>>1;
		if(out(mid)) {
			ri = mid;
		}
		else {
			li = mid + 1;
		}
	}


	if(out(li)) {
		cout << li << endl;
	}
	else {
		cout << -1 << endl;
	}






	
    

    
    

}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
    return 0;
}
accuracy: 0.9705882352941176
time_ms: 1510
memory_kb: 37720
final_rank: 19

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
//using uLL = unsigned __int128;
using str = string;
template <typename T> 
using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using pq = priority_queue<T>;
template <typename T>
using vec = vector<T>;
using pll = pair<long long, long long>;
using pii = pair<int, int>;
using vvvl = vector<vector<vector<ll>>>;
using vvl = vector<vector<ll>>;
using vi = vector<int>;
using vl = vector<ll>;
#define vvvm  vector<vector<vector<mint>>>
#define vvm  vector<vector<mint>>
#define vm  vector<mint>
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;
template <typename T>
using uset = unordered_set<T>;
#define rep(i, s, f) for(long long i = s; i <= f; i++)
#define rep1(i, s, f) for(long long i = s; i <= f; i++)
#define per(i, s, f) for(long long i = s; i >= f; i--)
#define per1(i, s, f) for(long long i = s; i >= f; i--)
#define eb(a) emplace_back(a)
#define pb(a) push_back(a)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define ins(x, l, r) (l <= x && x <= r)
#define ENDL '\n'
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）
template <typename T>
int LB(vector<T> &A, T x) {
    return lower_bound(A.begin(), A.end(), x) - A.begin();
}

template <typename T>
int UB(vector<T> &A, T x) {
    return upper_bound(A.begin(), A.end(), x) - A.begin();
}
template <typename T>
void UNIQUE(vector<T> &A, int indexed) {
    sort(A.begin() + indexed, A.end());
    A.erase(unique(A.begin() + indexed, A.end()), A.end());
}

template <typename T>
vector<T> erase(vector<T>& A, T& x) {
	vector<T> res;
	for(T a : A) if(a != x) res.emplace_back(a);
	return res;
}
string split(string& S, int l, int r) {
	return S.substr(l, r - l + 1);
}

int msb(long long a) {
    if(a == 0) return -1;
    return 64 - int(__builtin_clzll(a));
}
template<class T>
void chmin(T &a, T b) {
    if(a > b) a = b;
}
template<class T>
void chmax(T &a, T b) {
    if(a < b) a = b;
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll extgcd (ll a, ll b,  ll &x, ll &y) {
    if(b == 0) { x = 1;y = 0;return a;}
    ll d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
template <typename T>
T CEIL(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
    else return a / b;
}
template <typename T>
T FLOOR(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
    else return a/b - 1;
}
ll SQRT(ll a) {
    ll l = 0;
    ll r = 3037000499LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize "trapv" //お祈り。変数同士の演算でのみ感知。代入や、 a *= 10000 では感知しない。
const ll big = 1001001001;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // 座標平面において、(番兵) → ↓ ← ↑  ※ 右から時計回り 注 : グリッド or 座標で上下は反転する。
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
//const ll mod = 998244353;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using P = pair<short, short>;
using vvp = vec<vec<P>>;
using vp = vec<P>;
void solve() {
	ll H, W, N;
	cin >> H >> W >> N;
	vvp table(H+1, vp(W+1));
	rep(i,1,H) rep(j,1,W) {
		cin >> table[i][j].first >> table[i][j].second;
		table[i][j].first++, table[i][j].second++;
	}
	vl R(N+1), C(N+1);
	rep(i,1,N) {
		cin >> R[i] >> C[i];
		R[i]++, C[i]++;
	}

	const int M = 17;
	vec<vvp> dabu(M+1, vvp(H+1, vp(W+1)));
	rep(i,1,H)rep(j,1,W) {
		dabu[0][i][j] = table[i][j];
	}



	rep(p, 1, M) rep(i,1,H) rep(j,1,W) {
		auto[pi, pj] = dabu[p-1][i][j];
		dabu[p][i][j] = dabu[p-1][pi][pj];
	}



	auto jump = [&](int i, int j, ll step) {
		if(step==0) return P(i, j);
		rep(p, 0, M) {
			if(step >> p & 1) {
				auto [ni, nj] = dabu[p][i][j];
				i = ni;
				j = nj;
			}
		}
		return P(i, j);
	};

	auto out = [&](ll step) {
		set<P> cnt;
		rep(i,1,N) {
			auto nex = jump(R[i], C[i], step);
			if(cnt.count(nex)) return true;
			else cnt.insert(nex);
		}
		return false;
	};


	ll li = 0;
	ll ri = 1000000;

	while(li < ri) {//xxxxxxooooooo
		ll mid = (li + ri)>>1;
		if(out(mid)) {
			ri = mid;
		}
		else {
			li = mid + 1;
		}
	}


	if(out(li)) {
		cout << li << endl;
	}
	else {
		cout << -1 << endl;
	}






	
    

    
    

}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 1310
memory_kb: 37836
final_rank: 11

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
//using uLL = unsigned __int128;
using str = string;
template <typename T> 
using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using pq = priority_queue<T>;
template <typename T>
using vec = vector<T>;
using pll = pair<long long, long long>;
using pii = pair<int, int>;
using vvvl = vector<vector<vector<ll>>>;
using vvl = vector<vector<ll>>;
using vi = vector<int>;
using vl = vector<ll>;
#define vvvm  vector<vector<vector<mint>>>
#define vvm  vector<vector<mint>>
#define vm  vector<mint>
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;
template <typename T>
using uset = unordered_set<T>;
#define rep(i, s, f) for(long long i = s; i <= f; i++)
#define rep1(i, s, f) for(long long i = s; i <= f; i++)
#define per(i, s, f) for(long long i = s; i >= f; i--)
#define per1(i, s, f) for(long long i = s; i >= f; i--)
#define eb(a) emplace_back(a)
#define pb(a) push_back(a)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define ins(x, l, r) (l <= x && x <= r)
#define ENDL '\n'
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）
template <typename T>
int LB(vector<T> &A, T x) {
    return lower_bound(A.begin(), A.end(), x) - A.begin();
}

template <typename T>
int UB(vector<T> &A, T x) {
    return upper_bound(A.begin(), A.end(), x) - A.begin();
}
template <typename T>
void UNIQUE(vector<T> &A, int indexed) {
    sort(A.begin() + indexed, A.end());
    A.erase(unique(A.begin() + indexed, A.end()), A.end());
}

template <typename T>
vector<T> erase(vector<T>& A, T& x) {
	vector<T> res;
	for(T a : A) if(a != x) res.emplace_back(a);
	return res;
}
string split(string& S, int l, int r) {
	return S.substr(l, r - l + 1);
}

int msb(long long a) {
    if(a == 0) return -1;
    return 64 - int(__builtin_clzll(a));
}
template<class T>
void chmin(T &a, T b) {
    if(a > b) a = b;
}
template<class T>
void chmax(T &a, T b) {
    if(a < b) a = b;
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll extgcd (ll a, ll b,  ll &x, ll &y) {
    if(b == 0) { x = 1;y = 0;return a;}
    ll d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
template <typename T>
T CEIL(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
    else return a / b;
}
template <typename T>
T FLOOR(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
    else return a/b - 1;
}
ll SQRT(ll a) {
    ll l = 0;
    ll r = 3037000499LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize "trapv" //お祈り。変数同士の演算でのみ感知。代入や、 a *= 10000 では感知しない。
const ll big = 1001001001;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // 座標平面において、(番兵) → ↓ ← ↑  ※ 右から時計回り 注 : グリッド or 座標で上下は反転する。
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
//const ll mod = 998244353;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using P = pair<short, short>;
using vvp = vec<vec<P>>;
using vp = vec<P>;
void solve() {
	ll H, W, N;
	cin >> H >> W >> N;
	vvp table(H+1, vp(W+1));
	rep(i,1,H) rep(j,1,W) {
		cin >> table[i][j].first >> table[i][j].second;
		table[i][j].first++, table[i][j].second++;
	}
	vl R(N+1), C(N+1);
	rep(i,1,N) {
		cin >> R[i] >> C[i];
		R[i]++, C[i]++;
	}

	const int M = 18;
	vec<vvp> dabu(M+1, vvp(H+1, vp(W+1)));
	rep(i,1,H)rep(j,1,W) {
		dabu[0][i][j] = table[i][j];
	}



	rep(p, 1, M) rep(i,1,H) rep(j,1,W) {
		auto[pi, pj] = dabu[p-1][i][j];
		dabu[p][i][j] = dabu[p-1][pi][pj];
	}



	auto jump = [&](int i, int j, ll step) {
		if(step==0) return P(i, j);
		rep(p, 0, M) {
			if(step >> p & 1) {
				auto [ni, nj] = dabu[p][i][j];
				i = ni;
				j = nj;
			}
		}
		return P(i, j);
	};

	auto out = [&](ll step) {
		set<P> cnt;
		rep(i,1,N) {
			auto nex = jump(R[i], C[i], step);
			if(cnt.count(nex)) return true;
			else cnt.insert(nex);
		}
		return false;
	};


	ll li = 0;
	ll ri = 1000000;

	while(li < ri) {//xxxxxxooooooo
		ll mid = (li + ri)>>1;
		if(out(mid)) {
			ri = mid;
		}
		else {
			li = mid + 1;
		}
	}


	if(out(li)) {
		cout << li << endl;
	}
	else {
		cout << -1 << endl;
	}






	
    

    
    

}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 1340
memory_kb: 38720
final_rank: 13

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
//using uLL = unsigned __int128;
using str = string;
template <typename T> 
using pqg = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using pq = priority_queue<T>;
template <typename T>
using vec = vector<T>;
using pll = pair<long long, long long>;
using pii = pair<int, int>;
using vvvl = vector<vector<vector<ll>>>;
using vvl = vector<vector<ll>>;
using vi = vector<int>;
using vl = vector<ll>;
#define vvvm  vector<vector<vector<mint>>>
#define vvm  vector<vector<mint>>
#define vm  vector<mint>
template <typename T1, typename T2>
using umap = unordered_map<T1, T2>;
template <typename T>
using uset = unordered_set<T>;
#define rep(i, s, f) for(long long i = s; i <= f; i++)
#define rep1(i, s, f) for(long long i = s; i <= f; i++)
#define per(i, s, f) for(long long i = s; i >= f; i--)
#define per1(i, s, f) for(long long i = s; i >= f; i--)
#define eb(a) emplace_back(a)
#define pb(a) push_back(a)
#define all0(x) (x).begin() ,(x).end()
#define all(x) (x).begin() + 1, (x).end()
#define ins(x, l, r) (l <= x && x <= r)
#define ENDL '\n'
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//これが本当の組み込み関数ってね（笑）
template <typename T>
int LB(vector<T> &A, T x) {
    return lower_bound(A.begin(), A.end(), x) - A.begin();
}

template <typename T>
int UB(vector<T> &A, T x) {
    return upper_bound(A.begin(), A.end(), x) - A.begin();
}
template <typename T>
void UNIQUE(vector<T> &A, int indexed) {
    sort(A.begin() + indexed, A.end());
    A.erase(unique(A.begin() + indexed, A.end()), A.end());
}

template <typename T>
vector<T> erase(vector<T>& A, T& x) {
	vector<T> res;
	for(T a : A) if(a != x) res.emplace_back(a);
	return res;
}
string split(string& S, int l, int r) {
	return S.substr(l, r - l + 1);
}

int msb(long long a) {
    if(a == 0) return -1;
    return 64 - int(__builtin_clzll(a));
}
template<class T>
void chmin(T &a, T b) {
    if(a > b) a = b;
}
template<class T>
void chmax(T &a, T b) {
    if(a < b) a = b;
}
//////////////////////////////////////////////////////////////////////
//数学系
///////////////////////////////////////////////////////////////////////
ll extgcd (ll a, ll b,  ll &x, ll &y) {
    if(b == 0) { x = 1;y = 0;return a;}
    ll d = extgcd(b, a%b, y, x);
    y -= a/b * x;
    return d;
}
template <typename T>
T CEIL(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b + 1;
    else return a / b;
}
template <typename T>
T FLOOR(T a, T b) {
    assert(b != 0);
    if(a % b == 0) return a / b;
    if((a <= 0 && b < 0) || (a >= 0 && b > 0)) return a/b;
    else return a/b - 1;
}
ll SQRT(ll a) {
    ll l = 0;
    ll r = 3037000499LL;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(mid * mid <= a) l = mid;
        else r = mid - 1;
    }
    return l;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//グローバル変数を置くところ
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize "trapv" //お祈り。変数同士の演算でのみ感知。代入や、 a *= 10000 では感知しない。
const ll big = 1001001001;
vl dx{0, 1, 0, -1, 0, 1, 1, -1, -1};  // 座標平面において、(番兵) → ↓ ← ↑  ※ 右から時計回り 注 : グリッド or 座標で上下は反転する。
vl dy{0, 0, -1, 0, 1, 1, -1, -1, 1};
//const ll mod = 1000000007;
//const ll mod = 998244353;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using P = pair<short, short>;
using vvp = vec<vec<P>>;
using vp = vec<P>;
void solve() {
	ll H, W, N;
	cin >> H >> W >> N;
	vvp table(H+1, vp(W+1));
	rep(i,1,H) rep(j,1,W) {
		cin >> table[i][j].first >> table[i][j].second;
		table[i][j].first++, table[i][j].second++;
	}
	vl R(N+1), C(N+1);
	rep(i,1,N) {
		cin >> R[i] >> C[i];
		R[i]++, C[i]++;
	}

	const int M = 20;
	vec<vvp> dabu(M+1, vvp(H+1, vp(W+1)));
	rep(i,1,H)rep(j,1,W) {
		dabu[0][i][j] = table[i][j];
	}



	rep(p, 1, M) rep(i,1,H) rep(j,1,W) {
		auto[pi, pj] = dabu[p-1][i][j];
		dabu[p][i][j] = dabu[p-1][pi][pj];
	}



	auto jump = [&](int i, int j, ll step) {
		if(step==0) return P(i, j);
		rep(p, 0, M) {
			if(step >> p & 1) {
				auto [ni, nj] = dabu[p][i][j];
				i = ni;
				j = nj;
			}
		}
		return P(i, j);
	};

	auto out = [&](ll step) {
		set<P> cnt;
		rep(i,1,N) {
			auto nex = jump(R[i], C[i], step);
			if(cnt.count(nex)) return true;
			else cnt.insert(nex);
		}
		return false;
	};


	ll li = 0;
	ll ri = 10000000;

	while(li < ri) {//xxxxxxooooooo
		ll mid = (li + ri)>>1;
		if(out(mid)) {
			ri = mid;
		}
		else {
			li = mid + 1;
		}
	}


	if(out(li)) {
		cout << li << endl;
	}
	else {
		cout << -1 << endl;
	}






	
    

    
    

}



int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);
    ll T = 1;
    //cin >> T;
    rep(i, 1, T) {
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 1740
memory_kb: 40616
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

//高速化 
struct ponjuice{ponjuice(){cin.tie(0);ios::sync_with_stdio(0);cout<<fixed<<setprecision(20);}}PonJuice;
//#define endl '\n' //インタラクティブ問題の時は消す

//型
using ll = long long;
using ld = long double;
template<class T>using vc = vector<T>; template<class T>using vvc = vc<vc<T>>; template<class T>using vvvc = vvc<vc<T>>;
using vi = vc<int>;  using vvi = vvc<int>;  using vvvi = vvvc<int>;
using vl = vc<ll>;   using vvl = vvc<ll>;   using vvvl = vvvc<ll>;
using pi = pair<int, int>;  using pl = pair<ll, ll>;
using ull = unsigned ll;
template<class T>using priq = priority_queue<T>;
template<class T>using priqg = priority_queue<T, vc<T>, greater<T>>;

// for文
#define overload4(a, b, c, d, e, ...) e
#define rep1(n)             for(ll i = 0; i < n; i++)
#define rep2(i, n)          for(ll i = 0; i < n; i++)
#define rep3(i, a, b)       for(ll i = a; i < b; i++)
#define rep4(i, a, b, step) for(ll i = a; i < b; i+= step)
#define rep(...) overload4(__VA_ARGS__, rep4, rep3, rep2, rep1)(__VA_ARGS__)
#define per1(n)             for(ll i = n-1; i >= 0; i--)
#define per2(i, n)          for(ll i = n-1; i >= 0; i--)
#define per3(i, a, b)       for(ll i = b-1; i >= a; i--)
#define per4(i, a, b, step) for(ll i = b-1; i >= a; i-= step)
#define per(...) overload4(__VA_ARGS__, per4, per3, per2, per1)(__VA_ARGS__)
#define fore1(a)       for(auto&& i : a)	
#define fore2(i,a)     for(auto&& i : a)
#define fore3(x,y,a)   for(auto&& [x, y] : a)
#define fore4(x,y,z,a) for(auto&& [x, y, z] : a)
#define fore(...) overload4(__VA_ARGS__, fore4, fore3, fore2, fore1)(__VA_ARGS__)

//関数
#define mp make_pair
#define mt make_tuple
#define a first
#define b second
#define pb emplace_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define si(x) (ll)(x).size()
template<class S, class T>inline bool chmax(S& a, T b){return a < b && ( a = b , true);}
template<class S, class T>inline bool chmin(S& a, T b){return a > b && ( a = b , true);}
template<class T>void uniq(vc<T>&a){sort(all(a));a.erase(unique(all(a)),a.end());}
template<class T>vc<T> operator++(vc<T>&v,signed){auto res = v;fore(e,v)e++;return res;}
template<class T>vc<T> operator--(vc<T>&v,signed){auto res = v;fore(e,v)e--;return res;}
template<class T>vc<T> operator++(vc<T>&v){fore(e,v)e++;return v;}
template<class T>vc<T> operator--(vc<T>&v){fore(e,v)e--;return v;}

//入出力(operator)
template<class S,class T>istream&operator>>(istream&is,pair<S,T>&a){is>>a.a>>a.b;return is;}
template<class T>istream&operator>>(istream&is,vc<T>&a){fore(e,a)is>>e;return is;}

template<class S,class T>ostream&operator<<(ostream&os,pair<S,T>&a){return os<<a.a<<" "<<a.b;}
template<class T>ostream&operator<<(ostream&os,set<T>&a){fore(it,a){os<<it<<" ";}return os;}
template<class T>ostream&operator<<(ostream&os,multiset<T>&a){fore(it,a){os<<it<<" ";}return os;}
template<class S,class T>ostream&operator<<(ostream&os,map<S,T>&a){fore(x,y,a){os<<x<<" "<<y<<"\n";}return os;}
template<class T>ostream&operator<<(ostream&os,unordered_set<T>&a){fore(it,a){os<<it<<" ";}return os;}
template<class S,class T>ostream&operator<<(ostream&os,unordered_map<S,T>&a){fore(x,y,a){os<<x<<" "<<y<<"\n";}return os;}
template<class T>ostream&operator<<(ostream&os,vc<T>&a){fore(e,a)os<<e<<" ";return os;}
template<class T>ostream&operator<<(ostream&os,vvc<T>&a){fore(e,a)os<<e<<"\n";return os;}

//入出力(関数)
vi readvi(ll n){vi a(n);cin>>a;return a;}
vl readvl(ll n){vl a(n);cin>>a;return a;}
vvi readg(ll n,ll m,bool bidirected=true){vvi g(n);rep(i,m){ll a,b;cin>>a>>b;a--;b--;g[a].pb(b);if(bidirected)g[b].pb(a);}return g;}
vvc<pi>readgc(ll n,ll m,bool bidirected=true){vvc<pi> g(n);rep(i,m){ll a,b,c;cin>>a>>b>>c;a--;b--;g[a].pb(b,c);if(bidirected)g[b].pb(a,c);}return g;}
vvi readt(ll n,bool bidirected=true){return readg(n,n-1,bidirected);}
vvc<pi> readtc(ll n,bool bidirected=true){return readgc(n,n-1,bidirected);}

inline void yes(){cout << "Yes\n";}
inline void no(){cout << "No\n";}
inline void yesno(bool y = true){if(y)yes();else no();}

//定数
constexpr ll mod = 998244353;
constexpr ll minf=-(1<<29);
constexpr ll inf=(1<<29);
constexpr ll MINF=-(1LL<<60);
constexpr ll INF=(1LL<<60);
constexpr ld EPS = 1e-8;
const ld PI = acosl(-1);
#define equals(a, b) (abs((a) - (b)) < EPS)
const int dx[4] ={-1, 0, 1, 0};
const int dy[4] ={ 0, 1, 0,-1};
const int dx8[8] ={-1,-1,-1, 0, 1, 1, 1, 0};
const int dy8[8] ={-1, 0, 1, 1, 1, 0,-1,-1};

void solve();
int main() {
	int t = 1;
    // cin >>t;
    while(t--)solve();
}

int h, w, n;
int id(int i, int j){
    return i * w + j;
}

void solve(){
    cin >> h >> w >> n;
    vi to(h * w);
    vvi g(h * w);
    rep(i,h){
        rep(j,w){
            int x, y;
            cin >> x >> y;
            to[id(i, j)] = id(x, y);
            g[id(x, y)].emplace_back(id(i, j));
        }
    }

    vi d(h * w , inf);
    vi par(h * w , -1);
    vi r(h * w , -1);
    vi r2(h * w);
    rep(i, h * w) r2[i] = i;
    vi loop(h * w, inf);

    rep(i, h*w){
        if(d[i] == inf){
            int nw = i;
            d[nw] = inf - 1;

            while(d[to[nw]] == inf){
                d[to[nw]] = d[nw] - 1;
                nw = to[nw];
            }
            while(loop[to[nw]] == inf){
                nw = to[nw];
                loop[nw] = 0;
            }
            loop[nw] = 0;


            queue<int> q;
            q.push(nw);
            par[nw] = nw;
            r[nw] = d[to[nw]] - d[nw] + 1;
            d[nw] = 0;

            while(q.size()){
                int p = q.front();
                q.pop();
                rep(j, si(g[p])){
                    if(chmin(d[g[p][j]], d[p] + 1)){
                        par[g[p][j]] = par[p];
                        r[g[p][j]] = r[p];
                        if(chmin(loop[g[p][j]], loop[p] + 1)){
                            r2[g[p][j]] = r2[p];
                        }
                        q.push(g[p][j]);
                    }
                }
            }
        }
    }

    vi x(n);
    vi ex(h * w);
    map<pair<int, int>, int> mns;
    rep(i,n){
        int a, b;
        cin >> a >> b;
        x[i] = id(a, b);
        ex[x[i]] = 1;
        if(mns.find({par[x[i]], d[x[i]] % r[x[i]]}) == mns.end()){
            mns[{par[x[i]], d[x[i]] % r[x[i]]}] = loop[x[i]];
        }
        chmin(mns[{par[x[i]], d[x[i]] % r[x[i]]}], loop[x[i]]);
    }

    ll ans = inf;
    rep(i, n){
        if(mns[{par[x[i]], d[x[i]] % r[x[i]]}] != loop[x[i]]){
            chmin(ans, loop[x[i]]);
        }
    }
    

    set<pair<int,int>> mn2;
    rep(i,n){
        if(mn2.find({r2[x[i]], loop[x[i]]}) != mn2.end()){
            chmin(ans, loop[x[i]]);
        }
        else{
            mn2.insert({r2[x[i]], loop[x[i]]});
        }
    }


    auto dfs = [&](auto&&dfs, int p)->set<int> {
        set<int> nw;
        if(ex[p]) nw.insert(loop[p]);
        for(auto to : g[p]){
            if(loop[to] != loop[p] + 1) continue;
            set<int> nx = dfs(dfs, to);
            if(nw.size() < nx.size()) nw.swap(nx);
            for(auto v : nx){
                if(nw.count(v)){
                    chmin(ans, v - loop[p]);
                }else{
                    nw.insert(v);
                }
            }
        }
        return nw;
    };


    rep(i,h * w){
        if(loop[i] == 0){
            dfs(dfs, i);
        }
    }

    cout << (ans == inf ? -1 : ans) << endl;
}
accuracy: 1
time_ms: 300
memory_kb: 51860
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

typedef long long ll;

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)

template <typename T> bool chmin(T &a, const T &b) {
	if (a <= b) return false;
	a = b;
	return true;
}

template <typename T> bool chmax(T &a, const T &b) {
	if (a >= b) return false;
	a = b;
	return true;
}

template <typename T> T max(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
	return ret;
}

template <typename T> T min(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
	return ret;
}

template <typename T> T sum(vector<T> &a){
	T ret = 0;
	for (int i=0; i<(int)a.size(); i++) ret += a[i];
	return ret;
}
int main(){
	    cin.tie(nullptr);
    ios::sync_with_stdio(false);
	
	int h, w, n; cin >> h >> w >> n;
	vector gx(h, vector<int>(w));
	vector gy(h, vector<int>(w));
	rep(i,0,h){
		rep(j,0,w){
			int r, c; cin >> r >> c;
			gx[i][j] = r;
			gy[i][j] = c;
		}
	}

	vector dbx(20, vector(h, vector<int>(w)));
	vector dby(20, vector(h, vector<int>(w)));
	rep(i,0,h) rep(j,0,w){
		dbx[0][i][j] = gx[i][j];
		dby[0][i][j] = gy[i][j];
	}

	rep(num,0,19){
		rep(i,0,h){
			rep(j,0,w){
				int x = dbx[num][i][j];
				int y = dby[num][i][j];
				dbx[num+1][i][j] = dbx[num][x][y];
				dby[num+1][i][j] = dby[num][x][y];
			}
		}
	}

	vector<int> rx(n), ry(n);
	rep(i,0,n){
		cin >> rx[i] >> ry[i];
	}

	auto check = [&](int t) -> bool {
		vector<int> mx(n), my(n);
		mx = rx;
		my = ry;
		rep(num,0,20){
			if (t >> num & 1){
				rep(i,0,n){
					int x = dbx[num][mx[i]][my[i]];
					int y = dby[num][mx[i]][my[i]];
					mx[i] = x;
					my[i] = y;
				}
			}
		}
		vector nums(h, vector<int>(w));
		rep(i,0,n){
			nums[mx[i]][my[i]]++;
			if (nums[mx[i]][my[i]] >= 2) return true;
		}
		return false;
	};

	int ub = 299999;
	int lb = 0;
	while (ub - lb > 1){
		int t = (ub + lb) / 2;
		if (check(t)) ub = t;
		else lb = t;
	}

	if (lb > 288888){
		cout << -1 << '\n';
	}else{
		cout << ub << '\n';
	}
}
accuracy: 1
time_ms: 150
memory_kb: 49828
final_rank: 6

code_snippet: #pragma region //comavius::competitive library

#pragma region //inclusion and optimization
#include <bits/stdc++.h>
#ifdef IS_TEST
static const bool IS_TEST_ENVIROMENT = true;
#else
static const bool IS_TEST_ENVIROMENT = false;
#endif
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma endregion //inclusion and optimization

namespace comavius::competitive { //typedefs

    #pragma region //long long
        typedef int ll;
        typedef std::vector<ll> vll;
        typedef std::vector<vll> vvll;
        typedef std::vector<vvll> vvvll;
        typedef std::map<ll, ll> mll;
        typedef std::map<ll, mll> mmll;
        typedef std::pair<ll, ll> pll;
        typedef std::vector<pll> vpll;
    #pragma endregion //long long

    #pragma region //long double
        typedef long double ld;
        typedef std::vector<ld> vld;
        typedef std::vector<vld> vvld;
        typedef std::vector<vvld> vvvld;
    #pragma endregion //long double

    #pragma region //std::string
    typedef std::string str;
    typedef std::vector<str> vstr;
    typedef std::vector<vstr> vvstr;
    typedef std::vector<vvstr> vvvstr;
    #pragma endregion //std::string

    #pragma region //bool
        typedef std::vector<bool> vb;
        typedef std::vector<vb> vvb;
        typedef std::vector<vvb> vvvb;
    #pragma endregion //bool

    #pragma region //char
        typedef std::vector<char> vc;
        typedef std::vector<vc> vvc;
        typedef std::vector<vvc> vvvc;
    #pragma endregion //char

    #pragma region //container of std
        #pragma region //std::vector
            template <typename T>
            using vec = std::vector<T>;
            template <typename T>
            using vec2 = std::vector<std::vector<T>>;
            template <typename T>
            using vec3 = std::vector<std::vector<std::vector<T>>>;
            template <typename T>
            using vec4 = std::vector<std::vector<std::vector<std::vector<T>>>>;
            template <typename T>
            using vec5 = std::vector<std::vector<std::vector<std::vector<std::vector<T>>>>>;
            template <typename T>
            using vec6 = std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T>>>>>>;
            template <typename T>
            using vec7 = std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<std::vector<T>>>>>>>;
        #pragma endregion //std::vector
    #pragma endregion //container of std

} // namespace comavius::competitive typedefs


#pragma region //Read macro
    #define GET_1_ARG(TYPE, ARG); TYPE ARG; std::cin >> ARG;
    #define GET_2_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_1_ARG(TYPE, __VA_ARGS__)
    #define GET_3_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_2_ARG(TYPE, __VA_ARGS__)
    #define GET_4_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_3_ARG(TYPE, __VA_ARGS__)
    #define GET_5_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_4_ARG(TYPE, __VA_ARGS__)
    #define GET_6_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_5_ARG(TYPE, __VA_ARGS__)
    #define GET_7_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_6_ARG(TYPE, __VA_ARGS__)
    #define GET_8_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_7_ARG(TYPE, __VA_ARGS__)
    #define GET_9_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_8_ARG(TYPE, __VA_ARGS__)
    #define GET_10_ARG(TYPE, ARG, ...) GET_1_ARG(TYPE, ARG) GET_9_ARG(TYPE, __VA_ARGS__)

    #define GET_MACRO(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,NAME,...) NAME
    #define read(TYPE, ...) GET_MACRO(__VA_ARGS__, GET_10_ARG, GET_9_ARG, GET_8_ARG, GET_7_ARG, GET_6_ARG, GET_5_ARG, GET_4_ARG, GET_3_ARG, GET_2_ARG, GET_1_ARG)(TYPE, __VA_ARGS__)

    #define readv(TYPE, NAME, SIZE) std::vector<TYPE> NAME(SIZE); for (long long i = 0; i < SIZE; i++) std::cin >> NAME[i];
    #define readvv(TYPE, NAME, H, W) std::vector<std::vector<TYPE>> NAME(H, std::vector<TYPE>(W)); for (long long i = 0; i < H; i++) for (long long j = 0; j < W; j++) std::cin >> NAME[i][j];
#pragma endregion //Read macro

#pragma region //Other macro
    #define rep(i, n) for (ll i = 0; i < n; i++)
    #define reps(i, start, goal, diff) for (ll i = start; i != goal; i += diff)
    #define all(a) a.begin(), a.end()
//    #define chmax(a, b) a = std::max(a, b)
//    #define chmin(a, b) a = std::min(a, b)
#pragma endregion //Other macro

#pragma region //namespace expansion
    using namespace std;
    using namespace comavius::competitive;
#pragma endregion //namespace expansion

#pragma endregion //comavius::competitive library



#pragma region // fundamental structures

using vvpll = vector<vpll>;

int main() {
    int h, w, n;
    scanf("%d", &h);
    scanf("%d", &w);
    scanf("%d", &n);
    ll hw = h * w;
    vvll next(hw, vll(30));
    rep(i, h) {
        rep(j, w) {
            int r, c;
            scanf("%d", &r);
            scanf("%d", &c);
            next[i*w+j][0] = r*w+c;
        }
    }
    vll start;
    rep(i, n) {
            int r, c;
            scanf("%d", &r);
            scanf("%d", &c);
        start.push_back(r*w+c);
    }
    rep(i, 29) {
        rep(j, hw) {
            ll nx = next[next[j][i]][i];
            next[j][i+1] = nx;
        }
    }
    ll l = 0, r = 1ll<<28;
    while (r - l > 1) {
        ll mid = (l+r) / 2;
        vb visited(hw, false);
        bool ok = true;
        for (auto s : start) {
            ll dest = s;
            rep(i, 29) {
                if (mid & (1ll << i)) {
                    dest = next[dest][i];
                }
            }
            if (visited[dest]) {
                ok = false;
                break;
            }
            visited[dest] = true;
        }
        if (ok) {
            l = mid;
        }
        else {
            r = mid;
        }
    }
    if (r == 1ll<<28) {
        cout << "-1" << endl;
    }
    else {
        cout << r << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 920
memory_kb: 41200
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;

typedef long long ll;

#define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++)
#define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--)

template <typename T> bool chmin(T &a, const T &b) {
	if (a <= b) return false;
	a = b;
	return true;
}

template <typename T> bool chmax(T &a, const T &b) {
	if (a >= b) return false;
	a = b;
	return true;
}

template <typename T> T max(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]);
	return ret;
}

template <typename T> T min(vector<T> &a){
	assert(!a.empty());
	T ret = a[0];
	for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]);
	return ret;
}

template <typename T> T sum(vector<T> &a){
	T ret = 0;
	for (int i=0; i<(int)a.size(); i++) ret += a[i];
	return ret;
}
int main(){
	int h, w, n; cin >> h >> w >> n;
	vector gx(h, vector<int>(w));
	vector gy(h, vector<int>(w));
	rep(i,0,h){
		rep(j,0,w){
			int r, c; cin >> r >> c;
			gx[i][j] = r;
			gy[i][j] = c;
		}
	}

	vector dbx(20, vector(h, vector<int>(w)));
	vector dby(20, vector(h, vector<int>(w)));
	rep(i,0,h) rep(j,0,w){
		dbx[0][i][j] = gx[i][j];
		dby[0][i][j] = gy[i][j];
	}

	rep(num,0,19){
		rep(i,0,h){
			rep(j,0,w){
				int x = gx[i][j];
				int y = gy[i][j];
				dbx[num+1][i][j] = dbx[num][x][y];
				dby[num+1][i][j] = dby[num][x][y];
			}
		}
	}

	vector<int> rx(n), ry(n);
	rep(i,0,n){
		cin >> rx[i] >> ry[i];
	}

	auto check = [&](int t) -> bool {
		vector<int> mx(n), my(n);
		mx = rx;
		my = ry;
		rep(num,0,20){
			if (t >> num & 1){
				rep(i,0,n){
					int x = dbx[num][mx[i]][my[i]];
					int y = dby[num][mx[i]][my[i]];
					mx[i] = x;
					my[i] = y;
				}
			}
		}
		vector nums(h, vector<int>(w));
		rep(i,0,n){
			nums[mx[i]][my[i]]++;
			if (nums[mx[i]][my[i]] >= 2) return true;
		}
		return false;
	};

	int ub = 299999;
	int lb = 0;
	while (ub - lb > 1){
		int t = (ub + lb) / 2;
		if (check(t)) ub = t;
		else lb = t;
	}

	if (lb > 288888){
		cout << -1 << '\n';
	}else{
		cout << ub << '\n';
	}
}
accuracy: 0.5
time_ms: 220
memory_kb: 49808
final_rank: 20

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 2812.cc: H: ジャンプパーティ
 */

#include<cstdio>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_H = 500;
const int MAX_W = 500;
const int MAX_HW = MAX_H * MAX_W;
const int BN = 18;

/* typedef */

/* global variables */

int ps[MAX_HW][BN], ss[MAX_HW];
bool fs[MAX_HW];

/* subroutines */

bool check(int hw, int n, int k) {
  fill(fs, fs + hw, false);
  for (int i = 0; i < n; i++) {
    int u = ss[i];
    for (int i = 0; i < BN; i++)
      if ((k >> i) & 1) u = ps[u][i];
    if (fs[u]) return true;
    fs[u] = true;
  }
  return false;
}

/* main */

int main() {
  int h, w, n;
  scanf("%d%d%d", &h, &w, &n);
  int hw = h * w;

  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      int r, c;
      scanf("%d%d", &r, &c);
      ps[i * w + j][0] = r * w + c;
    }

  for (int i = 0; i < BN - 1; i++)
    for (int u = 0; u < hw; u++)
      ps[u][i + 1] = ps[ps[u][i]][i];

  for (int i = 0; i < n; i++) {
    int r, c;
    scanf("%d%d", &r, &c);
    ss[i] = r * w + c;
  }

  int k0 = 0, k1 = hw + 1;
  while (k0 + 1 < k1) {
    int k = (k0 + k1) / 2;
    if (check(hw, n, k)) k1 = k;
    else k0 = k;
  }

  printf("%d\n", (k1 > hw) ? -1 : k1);
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 21728
final_rank: 1

code_snippet: #include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
//#pragma GCC target("avx2")
#pragma GCC optimize("unroll-loops")
using namespace std;
//#include<boost/multiprecision/cpp_int.hpp>
//#include<boost/multiprecision/cpp_dec_float.hpp>
//namespace mp=boost::multiprecision;
//#define mulint mp::cpp_int
//#define mulfloat mp::cpp_dec_float_100
struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}} __init;
#define INF (1<<30)
#define LINF (lint)(1LL<<56)
#define endl "\n"
#define rep(i,n) for(lint (i)=0;(i)<(n);(i)++)
#define reprev(i,n) for(lint (i)=(n-1);(i)>=0;(i)--)
#define flc(x) __builtin_popcountll(x)
#define pint pair<int,int>
#define pdouble pair<double,double>
#define plint pair<lint,lint>
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define vec vector<lint>
#define nep(x) next_permutation(all(x))
typedef long long lint;
int dx[8]={1,1,0,-1,-1,-1,0,1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
const int MAX_N=4e5+5;
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return 1;}return 0;}
//vector<int> bucket[MAX_N/1000];
constexpr int MOD=1000000007;
//constexpr int MOD=998244353;
/*#include<atcoder/all>
using namespace atcoder;
typedef __int128_t llint;*/

struct doubling{
    vector<vector<lint>> to,sum;
    doubling(vector<lint> in,int log){
        to.resize(log);
        rep(i,log) to[i].resize(in.size());
        rep(i,in.size()) to[0][i]=in[i];
        for(int i=1;i<log;i++) rep(j,in.size()) to[i][j]=to[i-1][to[i-1][j]];
        sum.resize(log);
        rep(i,log) sum[i].resize(in.size());
        rep(i,in.size()) sum[0][i]=i;
        for(int i=1;i<log;i++) rep(j,in.size()) sum[i][j]=sum[i-1][j]+sum[i-1][to[i-1][j]];
    }
    doubling(vector<lint> in,vector<lint> in2, int log){//dsumでin2の値を使うようにする
        to.resize(log);
        rep(i,log) to[i].resize(in.size());
        rep(i,in.size()) to[0][i]=in[i];
        for(int i=1;i<log;i++) rep(j,in.size()) to[i][j]=to[i-1][to[i-1][j]];
        sum.resize(log);
        rep(i,log) sum[i].resize(in.size());
        rep(i,in.size()) sum[0][i]=in2[i];
        for(int i=1;i<log;i++) rep(j,in.size()) sum[i][j]=sum[i-1][j]+sum[i-1][to[i-1][j]];
    }
    lint dest(lint now,lint k){//nowのk個先
        rep(i,to.size()){
            if(k&(1LL<<i)) now=to[i][now];
        }
        return now;
    }
    lint dsum(lint now,lint k){//Σ[i=0..k-1]
        lint res=0;
        rep(i,to.size()){
            if(k&(1LL<<i)) res+=sum[i][now],now=to[i][now];
        }
        return res;
    }
};

int main(void){
    int H,W,N;
    cin >> H >> W >> N;
    vector<lint> nxt(H*W);
    rep(i,H) rep(j,W){
        int h,w;
        cin >> h >> w;
        int now=i*W+j;
        int to=h*W+w;
        nxt[now]=to;
    }
    doubling db(nxt,25);
    int R[N],C[N];
    rep(i,N) cin >> R[i] >> C[i];
    int p[N];
    rep(i,N) p[i]=R[i]*W+C[i];
    int lo=0,hi=1e6;
    while(hi-lo>1){
        int mid=(hi+lo)/2;
        int cnt[H*W]={};
        rep(i,N) cnt[db.dest(p[i],mid)]++;
        if(*max_element(cnt,cnt+H*W)>1) hi=mid;
        else lo=mid;
    }
    if(hi==1e6) cout << -1 << endl;
    else cout << hi << endl;
}
accuracy: 1
time_ms: 520
memory_kb: 106684
final_rank: 16

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
using PII = pair<ll, ll>;
#define FOR(i,a,n) for(ll i=(ll)a; i<(ll)n; ++i)
#define REP(i,n) FOR(i,0,n)
const ll INF = 1LL << 60;
template<typename T> void chmin(T &a, T b) { a = min(a, b); }



int main() {

	int H, W, N;
	cin >> H >> W >> N;
	vector<vector<int>>y(H, vector<int>(W));
	vector<vector<int>>x(H, vector<int>(W));
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			cin >> y[i][j] >> x[i][j];
		}
	}
	vector<int>sy(N);
	vector<int>sx(N);
	for (int i = 0; i < N; i++) {
		cin >> sy[i] >> sx[i];
	}
	vector<vector<vector<int>>>tapiY(H, vector<vector<int>>(W, vector<int>(20)));
	vector<vector<vector<int>>>tapiX(H, vector<vector<int>>(W, vector<int>(20)));
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < H; j++) {
			for (int k = 0; k < W; k++) {
				if (i) {
					int yy = tapiY[j][k][i - 1];
					int xx = tapiX[j][k][i - 1];
					tapiY[j][k][i] = tapiY[yy][xx][i - 1];
					tapiX[j][k][i] = tapiX[yy][xx][i - 1];
				}
				else {
					tapiY[j][k][i] = y[j][k];
					tapiX[j][k][i] = x[j][k];
				}
			}
		}
	}
	int ans = 0;
	vector<int>ny(N);
	vector<int>nx(N);
	for (int i = 19; i >= 0; i--) {
		set<pair<int, int>>st;
		for (int j = 0; j < N; j++) {
			ny[j] = tapiY[sy[j]][sx[j]][i];
			nx[j] = tapiX[sy[j]][sx[j]][i];
			st.insert({ ny[j],nx[j] });
		}
		if (st.size() == N) {
			sy = ny;
			sx = nx;
			ans += 1 << i;
		}
	}
	if (ans == (1 << 20) - 1) {
		cout << -1 << endl;
		return 0;
	}
	cout << ans + 1 << endl;
}
accuracy: 1
time_ms: 1650
memory_kb: 79156
final_rank: 17

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
using PII = pair<ll, ll>;
#define FOR(i,a,n) for(ll i=(ll)a; i<(ll)n; ++i)
#define REP(i,n) FOR(i,0,n)
const ll INF = 1LL << 60;
template<typename T> void chmin(T &a, T b) { a = min(a, b); }



int main() {

	int H, W, N;
	cin >> H >> W >> N;
	vector<vector<int>>y(H, vector<int>(W));
	vector<vector<int>>x(H, vector<int>(W));
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			cin >> y[i][j] >> x[i][j];
		}
	}
	vector<int>sy(N);
	vector<int>sx(N);
	for (int i = 0; i < N; i++) {
		cin >> sy[i] >> sx[i];
	}
	vector<vector<vector<int>>>tapiY(H, vector<vector<int>>(W, vector<int>(20)));
	vector<vector<vector<int>>>tapiX(H, vector<vector<int>>(W, vector<int>(20)));
	for (int i = 0; i < 20; i++) {
		for (int j = 0; j < H; j++) {
			for (int k = 0; k < W; k++) {
				if (i) {
					int yy = tapiY[j][k][i - 1];
					int xx = tapiX[j][k][i - 1];
					tapiY[j][k][i] = tapiY[yy][xx][i - 1];
					tapiX[j][k][i] = tapiX[yy][xx][i - 1];
				}
				else {
					tapiY[j][k][i] = y[j][k];
					tapiX[j][k][i] = x[j][k];
				}
			}
		}
	}
	int ans = 0;
	vector<int>ny(N);
	vector<int>nx(N);
	for (int i = 19; i >= 0; i--) {
		set<pair<int, int>>st;
		for (int j = 0; j < N; j++) {
			ny[j] = tapiY[sy[j]][sx[j]][i];
			nx[j] = tapiX[sy[j]][sx[j]][i];
			st.insert({ ny[j],nx[j] });
		}
		if (st.size() == N) {
			sy = ny;
			sx = nx;
			ans += 1 << i;
		}
	}
	if (ans == (1 << 20) - 1) {
		cout << -1 << endl;
		return 0;
	}
	cout << ans + 1 << endl;
}
accuracy: 1
time_ms: 1680
memory_kb: 79172
final_rank: 18

code_snippet: #include <iostream>
#include <vector>
#include <array>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <unordered_map>
#include <set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>
struct Coordinate {
	int x, y;
};

int main() {
	std::cin.sync_with_stdio(false);
	int h, w, n; std::cin >> h >> w >> n;
	std::vector<std::vector<Coordinate>> floor(h, std::vector<Coordinate>(w));
	for (auto& line : floor) for (auto& coordinate : line) std::cin >> coordinate.y >> coordinate.x;
	std::vector<std::vector<std::vector<Coordinate>>> step{ floor };
	for (auto i = 1; i < h * w; i <<= 1) {
		std::vector<std::vector<Coordinate>> new_floor(h, std::vector<Coordinate>(w));
		const auto& back = step.back();
		for (auto y = 0; y < h; ++y) for (auto x = 0; x < w; ++x) {
			auto next = back[y][x];
			new_floor[y][x] = back[next.y][next.x];
		}
		step.push_back(new_floor);
	}
	std::vector<Coordinate> dancers(n); for (auto& dancer : dancers) std::cin >> dancer.y >> dancer.x;
	std::vector<std::vector<int>> exists(h, std::vector<int>(w, -1));
	bool has_collision = false;
	for (const auto& dancer : dancers) {
		auto current_pos = step.back()[dancer.y][dancer.x];
		if (exists[current_pos.y][current_pos.x] != -1) {
			has_collision = true;
			break;
		}
		else {
			exists[current_pos.y][current_pos.x] = h * w + 1;
		}
	}
	if (!has_collision) {
		std::cout << -1 << '\n';
		return 0;
	}
	int min = 0;
	int max = h * w;
	while (min < max) {
		auto mid = (min + max) / 2;
		has_collision = false;
		for (auto dancer : dancers) {
			for (auto i = 0; i < step.size(); ++i) {
				if ((mid & (1 << i)) != 0) {
					dancer = step[i][dancer.y][dancer.x];
				}
			}
			if (exists[dancer.y][dancer.x] == mid) {
				has_collision = true;
				break;
			}
			else {
				exists[dancer.y][dancer.x] = mid;
			}
		}
		if (has_collision) max = mid;
		else min = mid + 1;
	}
	std::cout << max << '\n';
}
accuracy: 1
time_ms: 70
memory_kb: 45392
final_rank: 4

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct LOC{
	void set(int arg_to_row,int arg_to_col){
		to_row = arg_to_row;
		to_col = arg_to_col;
	}
	int to_row,to_col;
};

struct Info{
	int row,col;
};

int H,W,N;
int limit = 18;
int POW[19],work[501][501];
LOC table[19][501][501];
Info first_loc[250005],calc_loc[250005];

bool check(int num){

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++)work[row][col] = 0;
	}

	for(int i = 0; i < N; i++){
		calc_loc[i] = first_loc[i];
	}

	int now_row,now_col;

	for(int i = limit; i >= 0; i--){
		if(num < POW[i])continue;
		num -= POW[i];

		for(int k = 0; k < N; k++){
			now_row = calc_loc[k].row;
			now_col = calc_loc[k].col;
			calc_loc[k].row = table[i][now_row][now_col].to_row;
			calc_loc[k].col = table[i][now_row][now_col].to_col;
		}
	}

	for(int i = 0; i < N; i++){
		work[calc_loc[i].row][calc_loc[i].col]++;
		if(work[calc_loc[i].row][calc_loc[i].col] == 2){
			return true;
		}
	}

	return false;
}


int main(){

	for(int i = 0; i <= limit; i++)POW[i] = pow(2,i);

	scanf("%d %d %d",&H,&W,&N);

	int to_row,to_col;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			scanf("%d %d",&to_row,&to_col);
			table[0][row][col].set(to_row,to_col);
		}
	}

	for(int i = 0; i < N; i++){
		scanf("%d %d",&first_loc[i].row,&first_loc[i].col);
	}

	for(int i = 1; i <= limit; i++){
		for(int row = 0; row < H; row++){
			for(int col = 0; col < W; col++){

				to_row = table[i-1][row][col].to_row;
				to_col = table[i-1][row][col].to_col;

				table[i][row][col].to_row = table[i-1][to_row][to_col].to_row;
				table[i][row][col].to_col = table[i-1][to_row][to_col].to_col;
			}
		}
	}

	int left = 1,right = H*W,m = (left+right)/2;
	int ans = BIG_NUM;

	while(left <= right){
		if(check(m)){
			ans = m;
			right = m-1;
		}else{
			left = m+1;
		}
		m = (left+right)/2;
	}

	if(ans == BIG_NUM){
		printf("-1\n");
	}else{
		printf("%d\n",ans);
	}

	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 45520
final_rank: 5

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;

int H, W, N;
int mk(int r, int c) {
	return r*W+c;
}

bool check(vector<int>places,const vector<vector<int>>&tos, int time) {
	
	for (int i = 0; i < 20; ++i) {
		if (time&(1 << i)) {
			for (auto&pl : places) {
				pl=tos[pl][i];
			}
		}
	}
	sort(places.begin(),places.end());
	if(unique(places.begin(),places.end())==places.end())return false;
	else return true;
}

int main() {
	cin>>H>>W>>N;
	vector<vector<int>>tos(H*W,vector<int>(20));
	for (int i = 0; i < H; ++i) {
		for (int j = 0; j < W; ++j) {
			int r,c;cin>>r>>c;
			tos[mk(i,j)][0]=mk(r,c);
		}
	}
	for (int k = 1; k < 20; ++k) {
		for (int i = 0; i < H*W; ++i) {
			tos[i][k]=tos[tos[i][k-1]][k-1];
		}
	}
	vector<int>starts(N);
	for (int i = 0; i < N; ++i) {
		int r,c;cin>>r>>c;
		starts[i]=mk(r,c);
	}
	int amin=0;
	int amax=H*W+1;
	while (amin + 1 != amax) {
		int amid=(amin+amax)/2;
		if (check(starts, tos, amid)) {
			amax=amid;
		}
		else {
			amin=amid;
		}
	}
	if(amax==H*W+1)amax=-1;
	cout<<amax<<endl;
	return 0;
}
accuracy: 1
time_ms: 810
memory_kb: 34060
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

int H, W, N;
PII xs[18][500][500];

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  cin >> H >> W >> N;
  REP(y,H) REP(x,W)
	cin >> xs[0][y][x];

  vector<PII> ps(N);
  REP(i,N) cin >> ps[i];

  for(int i=1;i<18;++i){
	REP(y,H) REP(x,W){
	  auto&& par = xs[i-1][y][x];
	  xs[i][y][x] = xs[i-1][par.FF][par.SS];
	}
  }

  bool no = true;
  set<PII> s;
  for(auto&& p: ps){
	PII np = xs[17][p.FF][p.SS];
	if(s.count(np)){
	  no = false;
	}
	s.insert(np);
  }
  if(no){
	cout << -1 << endl;
	return 0;
  }

  int ans = 0;
  vector<vector<PII>> db(H, vector<PII>(W));
  REP(y,H) REP(x,W) db[y][x] = MP(y,x);
  for(int i=17;i>=0;--i){
	bool excess = false;
	set<PII> s;
	for(auto&& p: ps){
	  PII np = db[p.FF][p.SS];
	  np = xs[i][np.FF][np.SS];
	  if(s.count(np)){
		excess = true;
		break;
	  }
	  s.insert(np);
	}
	if(!excess){
	  ans |= 1<<i;
	  REP(y,H) REP(x,W){
		PII p = db[y][x];
		db[y][x] = xs[i][p.FF][p.SS];
	  }
	}
  }
  cout << ans+1 << endl;

  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 51648
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repl(i,0,n)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 2147483600

int main(){
  int h,w,n;
  cin>>h>>w>>n;
  vector<int> vec(h*w);
  rep(i,h)rep(j,w){
    int a,b;
    scanf("%d %d", &a, &b);
    vec[i*w+j] = a*w+b;
  }
  vector<int> p(n);
  rep(i,n){
    int a,b;
    scanf("%d %d", &a, &b);
    p[i] = a*w+b;
  }

  vector<vector<int>> mat(20, vector<int>(h*w));
  rep(i,h*w) mat[0][i] = vec[i];
  repl(i,1,20) rep(j,h*w){
    mat[i][j] = mat[i-1][mat[i-1][j]];
  }

  int l=0, r=2*h*w;
  while(r-l>1){
    int m = (l+r)/2;
    auto exe = [&](int x){
      vector<bool> vis(h*w,false);
      vector<int> v(p);
      int q=0;
      while(x>0){
        if(x%2){
          rep(i,n) v[i] = mat[q][v[i]];
        }
        x /= 2;
        q++;
      }
      rep(i,n){
        if(vis[v[i]]) return true;
        vis[v[i]]=true;
      }
      return false;
    };

    if(exe(m)) r = m;
    else l = m;
  }

  if(r==2*h*w) r=-1;
  cout << r << endl;

  return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 25352
final_rank: 2