Problem:
カツサンド (Cutlet Sandwich)

ある世界には、 $X$ 種類の「サンド」、 $Y$ 種類の「カツ」、 $Z$ 種類の「カレー」という食べ物があります。

この世界には $N$ 種類の「カツサンド」という食べ物があり、 $i$ 種類目のカツサンドは $A_i$ 種類目のサンドと $B_i$ 種類目のカツが原料です。

また、 $M$ 種類の「カツカレー」という食べ物があり、 $i$ 種類目のカツカレーは $C_i$ 種類目のカツと $D_i$ 種類目のカレーが原料です。

Segtree 君は、あるカツサンドまたはカツカレーを持っているとき、原料のうち少なくとも $1$ つが共通しているようなカツサンドまたはカツカレーと交換することができます。

例えば、$a$ 種類目のサンドと $b$ 種類目のカツが原料であるカツサンドを持っているとき、 $a$ 種類目のサンドまたは $b$ 種類目のカツを原料に持つ任意のカツサンド、または、 $b$ 種類目のカツを原料に含む任意のカツカレーと交換できます。

今、 Segtree 君は $S$ 種類目のカツサンドを持っていますが、食べたいのは $T$ 種類目のカツカレーです。

$T$ 種類目のカツカレーを手に入れることができるか判定してください。もし可能ならば、最小何回の交換で目的のカツカレーを手にいられるかを求めてください。

入力

入力は以下の形式で標準入力から与えられる。

$X$ $Y$ $Z$ $N$ $M$ $S$ $T$
$A_1$ $B_1$
$A_2$ $B_2$
$\ldots$
$A_N$ $B_N$
$C_1$ $D_1$
$C_2$ $D_2$
$\ldots$
$C_M$ $D_M$

出力

$T$ 種類目のカツカレーを手に入れるために必要な最小の交換回数を出力してください。手に入れることが不可能ならば、代わりに「 $-1$ 」を出力してください。

ただし、最後には改行を入れること。

制約

$1 \leq X,Y,Z,N,M \leq 10^5$

$1 \leq S \leq N$

$1 \leq T \leq M$

$1 \leq A_i \leq X$

$1 \leq B_i \leq Y$

$1 \leq C_i \leq Y$

$1 \leq D_i \leq Z$

入力は全て整数である。

入力例1

1 1 1 1 1 1 1
1 1
1 1

出力例1

1

入力例2

2 3 4 3 5 1 5
1 1
1 2
2 2
2 1
3 1
3 2
3 3
3 4

出力例2

4

入力例3

1 2 2 1 2 1 1
1 2
1 2
2 1

出力例3

-1

Solution in C++14 (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <array>
#include <list>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>
#include <cassert>
#include <random>


int main() {
	int x, y, z; std::cin >> x >> y >> z;
	int n, m, s, t; std::cin >> n >> m >> s >> t; --s; --t; t += n;
	std::vector<std::pair<int, int>> sands;
	for (auto i = 0; i < n; ++i) {
		int sand, katsu; std::cin >> sand >> katsu;
		sands.emplace_back(--sand, --katsu + x);
	}
	for (auto i = 0; i < m; ++i) {
		int katsu, curry; std::cin >> katsu >> curry;
		sands.emplace_back(--katsu + x, --curry + x + y);
	}
	std::vector<std::vector<int>> pair(x + y + z);
	for (const auto p : sands) {
		pair[p.first].push_back(p.second);
		pair[p.second].push_back(p.first);
	}
	std::vector<int> distance(x + y + z, -2);
	std::queue<int> stack;
	distance[sands[s].first] = distance[sands[s].second] = 0;
	stack.push(sands[s].first); stack.push(sands[s].second);
	while (!stack.empty()) {
		const auto top = stack.front(); stack.pop();
		for (const auto next : pair[top]) if (distance[next] == -2) {
			distance[next] = distance[top] + 1;
			stack.push(next);
		}
	}
	std::cout << ((distance[sands[t].first] != distance[sands[t].second]) ? std::max(distance[sands[t].first], distance[sands[t].second]) : distance[sands[t].first] + 1) << std::endl;
}