#include "bits/stdc++.h"

using namespace std;

#define MAX 200005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}

int main() {
	init();
	int N, M, Q;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}

	while(Q--) {

		scanf("%d%d",&u,&v);
		u = BC[u];
		v = BC[v];
		int lca = LCA(u, v);
//		printf("HEY %d %d %d %d %d\n",u,v,lca,level[u], level[v]);
		while(level[u] > level[lca]) {
//			printf("YY %d %d\n",u,lca);
			if(jumpDown[u] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpUp[u] == -1) {
				jumpUp[u] = lca;
				u = dp[u][0];
			}
			else {
				u = jumpUp[u];
				jumpUp[u] = lca;
			}
		}
		if(u != lca) {
			printf("No\n");
			return 0;
		}

		while(level[v] > level[lca]) {
//			printf("YYAA %d %d\n",v,lca);
			if(jumpUp[v] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpDown[v] == -1) {
				jumpDown[v] = lca;
				v = dp[v][0];
			}
			else {
				v = jumpDown[v];
				jumpDown[v] = lca;
			}
		}
		if(v != lca) {
			printf("No\n");
			return 0;
		}

	}
	printf("Yes\n");
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define MAX 200005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], level[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}

int main() {
	init();
	int N, M, Q;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}
	/*for(int i = 1 ; i <= N ; i++) {
		printf("Forest %d : %d\n", i, forest[i]);
	}*/
	while(Q--) {

		scanf("%d%d",&u,&v);
		if(forest[u] != forest[v]) {
			printf("No\n");
			return 0;
		}
		u = BC[u];
		v = BC[v];
		if(u == v)	continue;
		int lca = LCA(u, v);
//		printf("HEY %d %d %d %d %d\n",u,v,lca,level[u], level[v]);
		while(level[u] > level[lca]) {
//			printf("YY %d %d\n",u,lca);
			if(jumpDown[u] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpUp[u] == -1) {
				jumpUp[u] = lca;
				u = dp[u][0];
			}
			else {
				u = jumpUp[u];
				jumpUp[u] = lca;
			}
		}/*
		if(level[u] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/

		while(level[v] > level[lca]) {
//			printf("YYAA %d %d\n",v,lca);
			if(jumpUp[v] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpDown[v] == -1) {
				jumpDown[v] = lca;
				v = dp[v][0];
			}
			else {
				v = jumpDown[v];
				jumpDown[v] = lca;
			}
		}
		/*if(level[v] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/
	}
	printf("Yes\n");
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define MAX 200005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}

int main() {
	init();
	int N, M, Q;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}
	/*for(int i = 1 ; i <= N ; i++) {
		printf("Forest %d : %d\n", i, forest[i]);
	}*/
	while(Q--) {

		scanf("%d%d",&u,&v);
		if(forest[u] != forest[v]) {
			printf("No\n");
			return 0;
		}
		u = BC[u];
		v = BC[v];
		if(u == v)	continue;
		int lca = LCA(u, v);
//		printf("HEY %d %d %d %d %d\n",u,v,lca,level[u], level[v]);
		while(level[u] > level[lca]) {
//			printf("YY %d %d\n",u,lca);
			if(jumpDown[u] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpUp[u] == -1) {
				jumpUp[u] = lca;
				u = dp[u][0];
			}
			else {
				u = jumpUp[u];
				jumpUp[u] = lca;
			}
		}/*
		if(level[u] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/

		while(level[v] > level[lca]) {
//			printf("YYAA %d %d\n",v,lca);
			if(jumpUp[v] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpDown[v] == -1) {
				jumpDown[v] = lca;
				v = dp[v][0];
			}
			else {
				v = jumpDown[v];
				jumpDown[v] = lca;
			}
		}
		/*if(level[v] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/
	}
	printf("Yes\n");
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define MAX 200005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}

int main() {
	init();
	int N, M, Q;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}
	/*for(int i = 1 ; i <= N ; i++) {
		printf("Forest %d : %d\n", i, forest[i]);
	}*/
	while(Q--) {

		scanf("%d%d",&u,&v);
		if(forest[u] != forest[v]) {
			printf("No\n");
			return 0;
		}
		u = BC[u];
		v = BC[v];
		if(u == v)	continue;
		int lca = LCA(u, v);
		if(lca == -1) {
			printf("ASDFDSFSFSD\n");
		}
//		printf("HEY %d %d %d %d %d\n",u,v,lca,level[u], level[v]);
		while(level[u] > level[lca]) {
//			printf("YY %d %d\n",u,lca);
			if(jumpDown[u] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpUp[u] == -1) {
				jumpUp[u] = lca;
				u = dp[u][0];
			}
			else {
				u = jumpUp[u];
				jumpUp[u] = lca;
			}
		}/*
		if(level[u] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/

		while(level[v] > level[lca]) {
//			printf("YYAA %d %d\n",v,lca);
			if(jumpUp[v] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpDown[v] == -1) {
				jumpDown[v] = lca;
				v = dp[v][0];
			}
			else {
				v = jumpDown[v];
				jumpDown[v] = lca;
			}
		}
		/*if(level[v] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/
	}
	printf("Yes\n");
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define MAX 210005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
int counteris = 0;
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], level[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	counteris++;
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != -1 && dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}

int main() {
	init();
	int N, M, Q;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}
	/*for(int i = 1 ; i <= N ; i++) {
		printf("Forest %d : %d\n", i, forest[i]);
	}*/
	while(Q--) {

		scanf("%d%d",&u,&v);
		if(forest[u] != forest[v]) {
			printf("No\n");
			return 0;
		}
		u = BC[u];
		v = BC[v];
		if(u == v)	continue;
		int lca = LCA(u, v);
//		printf("HEY %d %d %d %d %d\n",u,v,lca,level[u], level[v]);
		while(level[u] > level[lca]) {
//			printf("YY %d %d\n",u,lca);
			if(jumpDown[u] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpUp[u] == -1) {
				jumpUp[u] = lca;
				u = dp[u][0];
			}
			else {
				u = jumpUp[u];
				jumpUp[u] = lca;
			}
		}/*
		if(level[u] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/

		while(level[v] > level[lca]) {
//			printf("YYAA %d %d\n",v,lca);
			if(jumpUp[v] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpDown[v] == -1) {
				jumpDown[v] = lca;
				v = dp[v][0];
			}
			else {
				v = jumpDown[v];
				jumpDown[v] = lca;
			}
		}
		/*if(level[v] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/
	}
	if(N == 110)
		printf("PP %d\n",counteris);
	printf("Yes\n");
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define MAX 200005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}

int main() {
	init();
	int N, M, Q;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}

	while(Q--) {

		scanf("%d%d",&u,&v);
		if(forest[u] != forest[v]) {
			printf("No\n");
			return 0;
		}
		u = BC[u];
		v = BC[v];
		int lca = LCA(u, v);
//		printf("HEY %d %d %d %d %d\n",u,v,lca,level[u], level[v]);
		while(level[u] > level[lca]) {
//			printf("YY %d %d\n",u,lca);
			if(jumpDown[u] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpUp[u] == -1) {
				jumpUp[u] = lca;
				u = dp[u][0];
			}
			else {
				u = jumpUp[u];
				jumpUp[u] = lca;
			}
		}
		if(u != lca) {
			printf("No\n");
			return 0;
		}

		while(level[v] > level[lca]) {
//			printf("YYAA %d %d\n",v,lca);
			if(jumpUp[v] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpDown[v] == -1) {
				jumpDown[v] = lca;
				v = dp[v][0];
			}
			else {
				v = jumpDown[v];
				jumpDown[v] = lca;
			}
		}
		if(v != lca) {
			printf("No\n");
			return 0;
		}

	}
	printf("Yes\n");
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define MAX 210005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
int counteris = 0;
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], level[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	counteris++;
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != -1 && dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}

int main() {
	init();
	int N, M, Q;
	int flag = 0;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		if(u == 77 && i == 0)
			flag = 1;
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}
	/*for(int i = 1 ; i <= N ; i++) {
		printf("Forest %d : %d\n", i, forest[i]);
	}*/
	if(flag == 110)
		printf("PP %d\n",counteris);
	while(Q--) {

		scanf("%d%d",&u,&v);
		if(forest[u] != forest[v]) {
			printf("No\n");
			return 0;
		}
		u = BC[u];
		v = BC[v];
		if(u == v)	continue;
		int lca = LCA(u, v);
//		printf("HEY %d %d %d %d %d\n",u,v,lca,level[u], level[v]);
		while(level[u] > level[lca]) {
//			printf("YY %d %d\n",u,lca);
			if(jumpDown[u] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpUp[u] == -1) {
				jumpUp[u] = lca;
				u = dp[u][0];
			}
			else {
				u = jumpUp[u];
				jumpUp[u] = lca;
			}
		}/*
		if(level[u] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/

		while(level[v] > level[lca]) {
//			printf("YYAA %d %d\n",v,lca);
			if(jumpUp[v] != -1) {
				printf("No\n");
				return 0;
			}
			if(jumpDown[v] == -1) {
				jumpDown[v] = lca;
				v = dp[v][0];
			}
			else {
				v = jumpDown[v];
				jumpDown[v] = lca;
			}
		}
		/*if(level[v] <= level[lca]) {
			printf("No\n");
			return 0;
		}*/
	}

	printf("Yes\n");
	return 0;
}


#include "bits/stdc++.h"

using namespace std;

#define MAX 210005
#define fi first
#define se second
#define pb push_back
#define UP 1
#define DOWN 2
#define LOGN 20
typedef pair<int, int> p;

std::vector<p> G[MAX];
std::vector<p> Gaux[MAX];
int forest[MAX];
int forestCnt;
int highestLevelReached[MAX];
int level[MAX];
int isBridge[MAX];
int bridgeComponentId;
int direction[MAX];
int edgeFirst[MAX];
int edgeSecond[MAX];
int dp[MAX][LOGN];
int directiondp[MAX][LOGN];
int vis[MAX];
int vis2[MAX];
int BC[MAX];
int jumpUp[MAX];
int jumpDown[MAX];
int counteris = 0;
queue<int> q;

void assignBridgeEdge(int u, int par = -1, int curLevel = 0, int forestId = 1, int edgeId = -1) {
//	printf("HEY %d %d\n",u, par);
	forest[u] = forestId;
	level[u] = curLevel;
	vis[u] = 1;
	highestLevelReached[u] = curLevel;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par && G[u][i].se == edgeId)	continue;
		if(vis[G[u][i].fi]){
			highestLevelReached[u] = min(highestLevelReached[u], level[G[u][i].fi]);
			continue;
		}
		assignBridgeEdge(G[u][i].fi, u, curLevel + 1, forestId, G[u][i].se);
		if(highestLevelReached[G[u][i].fi] > level[u]) {
//			printf("HAFSDFS %d %d %d %d\n",u, G[u][i].fi, highestLevelReached[u], highestLevelReached[G[u][i].fi]);
			isBridge[G[u][i].se] = true;
		}
		else {
			highestLevelReached[u] = min(highestLevelReached[G[u][i].fi], highestLevelReached[u]);
		}
	}
}

void init() {
	memset(dp, -1, sizeof(dp));
	memset(forest, -1, sizeof(forest));
	memset(jumpUp, -1, sizeof(jumpUp));
	memset(jumpDown, -1, sizeof(jumpDown));
	forestCnt = 0;
}

void createBridgeTree(int u, int bridgeComponentId, int par = -1) {
	BC[u] = bridgeComponentId;
	vis2[u] = 1;
	for(int i = 0 ; i < G[u].size() ; i++) {
		if(G[u][i].fi == par)	continue;
		if(vis2[G[u][i].fi]) {
			continue;
		}
		if(isBridge[G[u][i].se]) {
//			printf("ASDS @@@@ %d %d\n",G[u][i].fi,bridgeComponentId);
			Gaux[G[u][i].fi].pb(p(bridgeComponentId, G[u][i].se));
			Gaux[bridgeComponentId].pb(p(G[u][i].fi, G[u][i].se));
			q.push(G[u][i].fi);
		}
		else {
			createBridgeTree(G[u][i].fi, bridgeComponentId, u);
		}
	}
}

void dfs(int u, int par = -1, int levelCnt = 0) {
//	printf("QQQ %d %d\n", u , levelCnt);
	counteris++;
	level[u] = levelCnt;
	dp[u][0] = par;
	for(int i = 0 ; i < Gaux[u].size() ; i++) {
		if(Gaux[u][i].fi == par)	continue;
		dfs(Gaux[u][i].fi, u, levelCnt + 1);
	}
}

int LCA(int u, int v) {
	if(u == v) 	return u;
	if(level[u] > level[v]) swap(u, v);
	int diff = level[v] - level[u];
	for(int i = LOGN - 1; i >= 0 ; i--) {
		if((diff >> i) & 1) {
			v = dp[v][i];
		}
	}
	if(u == v)	return u;
	for(int i = LOGN - 1 ; i >= 0 ; i--) {
		if(dp[u][i] != -1 && dp[u][i] != dp[v][i])
			u = dp[u][i], v = dp[v][i];
	}
	return dp[u][0];
}
int down[MAX];
int up[MAX];
int ans = 1;
void fin(int p, int v)
{
	for (int i = 0; i < Gaux[v].size(); i++)
	{
		int u = Gaux[v][i].fi;
		if (u == p)
			continue;
		fin(v, u);
		down[v] += down[u];
		up[v] += up[u];
	}
	if (down[v] > 0 && up[v] > 0)
		ans = false;
}

int main() {
	init();
	int N, M, Q;
	int flag = 0;
	int u,v;
	scanf("%d%d%d",&N, &M, &Q);
	for(int i = 0 ; i < M ; i++) {
		scanf("%d%d",&u,&v);
		if(u == 77 && i == 0)
			flag = 1;
		edgeFirst[i] = u;
		edgeFirst[i] = v;
		G[u].pb(p(v, i));
		G[v].pb(p(u, i));
	}

	for(int i = 1 ; i <= N ; i++)
	{
		if(forest[i] == -1)
			assignBridgeEdge(i, -1, 0, i);
		else
			continue;
//		for(int j = 1 ; j <= N ; j++)
//			printf("PPPPPP %d : %d\n", j, highestLevelReached[j]);
		while(q.size())
			q.pop();
		q.push(i);
		while(q.size()) {
			int u = q.front();
//			printf("HEYASF %d\n",u);
			q.pop();
			createBridgeTree(u, u);
		}
		// Bridge Tree created now comes the par to assign LCA and dfs....
		dfs(i);
	}

	for(int i = 1 ; i < LOGN ;  i++) {
		for(int j = 1 ; j <= N ; j++) {
			if(dp[j][i-1] == -1)	continue;
			dp[j][i] = dp[dp[j][i-1]][i-1];
		}
	}
	/*for(int i = 1 ; i <= N ; i++) {
		printf("Forest %d : %d\n", i, forest[i]);
	}*/
//	if(flag == 1)
//		printf("PP %d\n",counteris);
	while(Q--) {

		scanf("%d%d",&u,&v);
		if(forest[u] != forest[v]) {
			printf("No\n");
			return 0;
		}
		u = BC[u];
		v = BC[v];
		if(u == v)	continue;
		int lca = LCA(u, v);
		up[u]++;
		up[lca]--;
		down[v]++;
		down[lca]--;
	}
	for(int i = 1 ; i <= N ; i++) {
		if(dp[i][0] == i)
			fin(i,i);
	}
	if(ans)
		printf("Yes\n");
	else
		printf("No\n");
	return 0;
}


#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int MAX = 200005;
vector<int> adj[MAX];
int from[MAX], to[MAX], low[MAX], d[MAX], color[MAX], cc[MAX], par[20][MAX];
bool iscut[MAX], mark[MAX], ans = true;
void dfs(int p, int v)
{
	mark[v] = true;
	for (int i = 0; i < adj[v].size(); i++)
	{
		int id = adj[v][i];
		if (id == p)
			continue;
		int u = from[id] + to[id] - v;
		if (mark[u])
		{
			if (d[low[v]] > d[u])
				low[v] = u;
		}
		else
		{
			d[u] = d[v] + 1;
			dfs(id, u);
			if (d[low[u]] > d[v])
				iscut[id] = true;
			if (d[low[v]] > d[low[u]])
				low[v] = low[u];
		}
	}
}
void go(int v, int c)
{
	color[v] = c;
	for (int i = 0; i < adj[v].size(); i++)
	{
		int id = adj[v][i];
		if (iscut[id])
			continue;
		int u = from[id] + to[id] - v;
		if (color[u] == -1)
			go(u, c);
	}
}
int iscounter = 0;
void init(int p, int v, int c)
{
	iscounter++;
	cc[v] = c;
	par[0][v] = p;
	for (int i = 1; i < 20; i++)
		par[i][v] = par[i - 1][par[i - 1][v]];
	for (int i = 0; i < adj[v].size(); i++)
	{
		int u = adj[v][i];
		if (u == p)
			continue;
		d[u] = d[v] + 1;
		init(v, u, c);
	}
}
int get_parent(int v, int k)
{
	for (int i = 0; i < 20; i++)
		if ((1 << i) & k)
			v = par[i][v];
	return v;
}
int lca(int u, int v)
{
	if (d[u] < d[v])
		swap(u, v);
	u = get_parent(u, d[u] - d[v]);
	if (u == v)
		return u;
	for (int i = 19; i >= 0; i--)
		if (par[i][u] != par[i][v])
		{
			u = par[i][u];
			v = par[i][v];
		}
	return par[0][v];
}
int down[MAX], up[MAX];
void fin(int p, int v)
{
	for (int i = 0; i < adj[v].size(); i++)
	{
		int u = adj[v][i];
		if (u == p)
			continue;
		fin(v, u);
		down[v] += down[u];
		up[v] += up[u];
	}
	if (down[v] > 0 && up[v] > 0)
		ans = false;
}
int main()
{
	ios::sync_with_stdio(false);
	memset(color, -1, sizeof(color));
	for (int i = 0; i < MAX; i++)
		low[i] = i;
	int n, m, q;
	cin >> n >> m >> q;
	int flag = 0;
	for (int i = 0; i < m; i++)
	{
		cin >> from[i] >> to[i];
		if(i == 0 && from[i] == 77)
			flag = 1;
		from[i]--;
		to[i]--;
		adj[from[i]].push_back(i);
		adj[to[i]].push_back(i);
	}
	for (int i = 0; i < n; i++)
		if (!mark[i])
			dfs(-1, i);
	int c = 0;
	for (int i = 0; i < n; i++)
		if (color[i] == -1)
			go(i, c++);
	for (int i = 0; i < n; i++)
		adj[i].clear();
	for (int i = 0; i < m; i++)
		if (iscut[i])
		{
			adj[color[from[i]]].push_back(color[to[i]]);
			adj[color[to[i]]].push_back(color[from[i]]);
		}
	memset(cc, -1, sizeof(cc));
	memset(d, 0, sizeof(d));
	n = c;
	c = 0;
	for (int i = 0; i < n; i++)
		if (cc[i] == -1)
			init(i, i, c++);
	printf("HEY %d\n",iscounter);
	while (q--)
	{
		int u, v;
		cin >> u >> v;
		u--;
		v--;
		u = color[u];
		v = color[v];
		if (cc[u] != cc[v])
			ans = false;
		else
		{
			int p = lca(u, v);
			up[u]++;
			up[p]--;
			down[p]--;
			down[v]++;
		}
	}
	for (int i = 0; i < n; i++)
		if (par[0][i] == i)
			fin(i, i);
	if (ans)
		cout << "Yes\n";
	else
		cout << "No\n";
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 3e5 + 10, LOG = 30;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v] || done[pii(v, u)])
			cant = true;
		else {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], minimum[N], upper[N][LOG];
bool cant, mark[N], shear[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_shear(int v, int par) {
	mark[v] = true;
	minimum[v] = h[v];
	for (pii p: nei[v]) {
		int u = p.first;
		if(u == par)
			continue;
		if(!mark[u]) {
			h[u] = h[v] + 1;
			find_shear(u, v);
		}
		if(minimum[u] > h[v]
		   && cnt[pii(min(u, v), max(u, v))] == 1)
			shear[p.second] = true;
		minimum[v] = min(minimum[v], minimum[u]);
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(shear[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v, int mypar) {
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			if(u == mypar)
				continue;
			check(u, v);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_shear(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v])
			cant = true;
		else {
			u = par[u];
			v = par[v];
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i, i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
const int N = 1e5 + 2, LOG = 16;

int n, m, q, u, v, a, LCA, h[N], upper[N][LOG];
vector<int> ans, nei[N], in[N], vec[N][LOG];

void normalize(set<int> *st) {
	while((*st).size() > 10)
		(*st).erase(--((*st).begin()));
}

void dfs(int v) {
	set<int>st;
	for (int i = 1; i < LOG; i++) {
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
		st.insert(vec[v][i - 1].begin(), vec[v][i - 1].end());
		st.insert(vec[upper[v][i - 1]][i - 1].begin(), vec[upper[v][i - 1]][i - 1].end());
		normalize(&st);
		while(st.size()) {
			vec[v][i].push_back(*st.begin());
			st.erase(st.begin());
		}
	}
	for (int u: nei[v])
		if(u != upper[v][0]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			st.insert(in[v].begin(), in[v].end());
			st.insert(in[u].begin(), in[u].end());
			while(st.size()) {
				vec[u][0].push_back(*st.begin());
				st.erase(st.begin());
			}
			normalize(&st);
			dfs(u);
		}
	nei[v].clear();
}

int lca(int u, int v) {
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < n - 1; i++) {
		cin >> u >> v;
		nei[--u].push_back(--v);
		nei[v].push_back(u);
	}
	for (int i = 0; i < m; i++) {
		cin >> u;
		if(in[--u].size() < 10)
			in[u].push_back(i + 1);
	}
	dfs(0);
	while(q--) {
		cin >> u >> v >> a;
		LCA = lca(--u, --v);
		for (int num: in[u])
			ans.push_back(num);
		for (int num: in[v])
			ans.push_back(num);
		for (int i = LOG - 1; i >= 0; i--)
			if(h[u] - (1LL << i) >= h[LCA]) {
				for (int num: vec[u][i])
					ans.push_back(num);
				u = upper[u][i];
			}
		for (int i = LOG - 1; i >= 0; i--)
			if(h[v] - (1LL << i) >= h[LCA]) {
				for (int num: vec[v][i])
					ans.push_back(num);
				v = upper[v][i];
			}
		sort(ans.begin(), ans.end());
		std::vector<int>::iterator it;
		it = unique(ans.begin(), ans.end());
		ans.resize(distance(ans.begin(),it));
		a = min(a, (int)ans.size());
		cout << a << ' ';
		for (int i = 0; i < a; i++)
			cout << ans[i] << ' ';
		ans.clear();
		cout << '\n';
	}
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 1e5 + 10, LOG = 17;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> same, nei[N];
map<pii, int> cnt;

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first);
}

int find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
	return mini[v];
}

void tree_dfs(int v) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(!mark[p.first]) {
			if(cross[p.second])
				tree_nei[parent].push_back(p.first);
			else
				tree_dfs(p.first);
		}
}

int g_par(int v) {
	if(par[v] != v)
		par[v] = g_par(par[v]);
	return par[v];
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		if(cnt[pii(min(u, v), max(u, v))] < 2)
			cnt[pii(min(u, v), max(u, v))]++;
		if(cnt[pii(min(u, v), max(u, v))] == 2)
			same.push_back(pii(u, v));
	}
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			tree_dfs(i);
			parent++;
		}
	for (pii p: same)
		par[p.first] = g_par(p.second);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v]) {
			cout << "NO";
			return 0;
		}
		u = g_par(u);
		v = g_par(v);
		ups[u]++;
		dps[v]++;
		int LCA = lca(u, v);
		ups[LCA]--;
		dps[LCA]--;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	for (int i = 0; i < parent; i++)
		if(ups[i] > 0 && dps[i] > 0) {
			cout << "NO";
			return 0;
		}
	cout << "YES";
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			tree_dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] == comp[--v]) {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)] || u == v)
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
		else
			cant = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, LOG = 20;

typedef pair<int, int> pii;

int n, m, u, v, k, parent, h[N], comp[N], minimum[N], upper[N][LOG];
bool mark[N], shear[N];
vector<pii> nei[N];
vector<int> tree_nei[N];

void find_shear(int v, int par) {
	mark[v] = true;
	minimum[v] = h[v];
	for (pii p: nei[v]) {
		int u = p.first;
		if(u == par)
			continue;
		if(!mark[u]) {
			h[u] = h[v] + 1;
			find_shear(u, v);
		}
		if(minimum[u] > h[v])
			shear[p.second] = true;
		minimum[v] = min(minimum[v], minimum[u]);
	}
}

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for(pii p: nei[v]) {
		if(!mark[p.first] && !shear[p.second])
			dfs(p.first);
		if(shear[p.second])
			tree_nei[parent].push_back(p.first);
	}

}

void tree_dfs(int v, int par) {
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = comp[u];
		if(u != par) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			tree_dfs(u, v);
		}
	}
}

int lca (int u, int v) {
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			v = upper[v][i];
			u = upper[u][i];
		}
	return upper[u][0];
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
	}
	find_shear(0, 0);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	tree_dfs(0, 0);
	cin >> k;
	for (int i = 0; i < k; i++) {
		cin >> u >> v;
		cout << h[comp[--u]] + h[comp[--v]] - 2 * h[lca(comp[u], comp[v])] << '\n';
	}
	return 0;

}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> same, nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first);
}

int find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v])
			cross[p.second] = true;
	}
	return mini[v];
}

void tree_dfs(int v) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(!mark[p.first]) {
			if(cross[p.second])
				tree_nei[parent].push_back(p.first);
			else
				tree_dfs(p.first);
		}
		else if(cross[p.second])
			tree_nei[parent].push_back(p.first);
}

int g_par(int v) {
	if(par[v] != v)
		par[v] = g_par(par[v]);
	return par[v];
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		if(cnt[pii(min(u, v), max(u, v))] < 3)
			cnt[pii(min(u, v), max(u, v))]++;
		if(cnt[pii(min(u, v), max(u, v))] == 2)
			same.push_back(pii(u, v));
	}
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			tree_dfs(i);
			parent++;
		}
	for (pii p: same)
		par[p.first] = g_par(p.second);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v]) {
			cout << "NO";
			return 0;
		}
		u = g_par(u);
		v = g_par(v);
		if(done[pii(u, v)])
			continue;
		ups[u]++;
		dps[v]++;
		int LCA = lca(u, v);
		ups[LCA]--;
		dps[LCA]--;
		done[pii(u, v)] = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	for (int i = 0; i < parent; i++)
		if(ups[i] > 0 && dps[i] > 0) {
			cout << "NO";
			return 0;
		}
	cout << "YES";
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], minimum[N], upper[N][LOG];
bool cant, mark[N], shear[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_shear(int v, int par) {
	mark[v] = true;
	minimum[v] = h[v];
	for (pii p: nei[v]) {
		int u = p.first;
		if(u == par)
			continue;
		if(!mark[u]) {
			h[u] = h[v] + 1;
			find_shear(u, v);
		}
		if(minimum[u] > h[v]
		   && cnt[pii(min(u, v), max(u, v))] == 1)
			shear[p.second] = true;
		minimum[v] = min(minimum[v], minimum[u]);
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v]) {
		if(!mark[p.first] && !shear[p.second])
			dfs(p.first, parent);
		if(shear[p.second])
			tree_nei[parent].push_back(p.first);
	}
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v, int mypar) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			if(u == mypar)
				continue;
			check(u, v);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	//cerr << v + 1 << ' ' << ups[v] << ' ' << dps[v] << " dp\n";
	if(ups[v] > 0 && dps[v] > 0)
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_shear(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(h, 0, sizeof h);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v])
			cant = true;
		else {
			u = par[u];
			v = par[v];
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			//cerr << LCA + 1 << " add\n";
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i, i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> same, nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first);
}

int find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v])
			cross[p.second] = true;
	}
	return mini[v];
}

void tree_dfs(int v) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(!mark[p.first]) {
			if(cross[p.second])
				tree_nei[parent].push_back(p.first);
			else
				tree_dfs(p.first);
		}
		else if(cross[p.second])
			tree_nei[parent].push_back(p.first);
}

int g_par(int v) {
	if(par[v] != v)
		par[v] = g_par(par[v]);
	return par[v];
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		if(cnt[pii(min(u, v), max(u, v))] < 3)
			cnt[pii(min(u, v), max(u, v))]++;
		if(cnt[pii(min(u, v), max(u, v))] == 2)
			same.push_back(pii(u, v));
	}
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			tree_dfs(i);
			parent++;
		}
	for (pii p: same)
		par[g_par(p.first)] = g_par(p.second);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v]) {
			cant = true;
			break;
		}
		u = g_par(u);
		v = g_par(v);
		if(done[pii(u, v)])
			continue;
		ups[u]++;
		dps[v]++;
		int LCA = lca(u, v);
		ups[LCA]--;
		dps[LCA]--;
		done[pii(u, v)] = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	if(cant)
		cout << "NO";
	else
		cout << "YES";
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] >= h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < n /*parent*/; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] == comp[--v]) {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)] || u == v)
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
		else
			cant = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 30;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			tree_dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] == comp[--v]) {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
		else
			cant = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] > 0 && dps[v] > 0)
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			tree_dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v])
			cant = true;
		else {
			u = par[u];
			v = par[v];
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = par[u];
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] > 0 && dps[v] > 0)
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v])
			cant = true;
		else {
			u = par[u];
			v = par[v];
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> same, nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first);
}

int find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v])
			cross[p.second] = true;
	}
	return mini[v];
}

void tree_dfs(int v) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(!mark[p.first]) {
			if(cross[p.second])
				tree_nei[parent].push_back(p.first);
			else
				tree_dfs(p.first);
		}
		else if(cross[p.second])
			tree_nei[parent].push_back(p.first);
}

int g_par(int v) {
	if(par[v] != v)
		par[v] = g_par(par[v]);
	return par[v];
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		if(cnt[pii(min(u, v), max(u, v))] < 3)
			cnt[pii(min(u, v), max(u, v))]++;
		if(cnt[pii(min(u, v), max(u, v))] == 2)
			same.push_back(pii(u, v));
	}
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			dfs(i);
			parent++;
		}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i]) {
			tree_dfs(i);
			parent++;
		}
	for (pii p: same)
		par[g_par(p.first)] = g_par(p.second);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v]) {
			cout << "NO";
			return 0;
		}
		u = g_par(u);
		v = g_par(v);
		if(done[pii(u, v)])
			continue;
		ups[u]++;
		dps[v]++;
		int LCA = lca(u, v);
		ups[LCA]--;
		dps[LCA]--;
		done[pii(u, v)] = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	for (int i = 0; i < parent; i++)
		if(ups[i] > 0 && dps[i] > 0) {
			cout << "NO";
			return 0;
		}
	cout << "YES";
	return 0;
}


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

typedef pair<int, int> pii;

int n, m, u, v, h[N], minimum[N], time;
bool mark[N];
vector<pii> nei[N];

int find_shear(int v) {
	mark[v] = true;
	int mini = h[v];
	for (int u: nei[v]) {

	}

}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		neii[v].push_back(pii(u, i));
	}

	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] >= h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] == comp[--v]) {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)] || u == v)
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
		else
			cant = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] >= h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i <= parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] == comp[--v]) {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)] || u == v)
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
		else
			cant = true;
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] >= h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v])
			cant = true;
		else {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 3e5 + 10, LOG = 30;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v];
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v])
			cant = true;
		else {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v] + 1;
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v] || done[pii(v, u)])
			cant = true;
		else {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}


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

typedef pair<int, int> pii;
const int N = 2e5 + 10, LOG = 20;

int n, m, q, u, v, parent, h[N], ups[N], dps[N], par[N], comp[N], mini[N], upper[N][LOG];
bool cant, mark[N], cross[N];
vector<int> tree_nei[N];
vector<pii> nei[N];
map<pii, int> cnt;
map<pii, bool> done;

void dfs(int v, int parent) {
	mark[v] = true;
	comp[v] = parent;
	for (pii p: nei[v])
		if(!mark[p.first])
			dfs(p.first, parent);
}

void find_cross(int v, int mypar) {
	mark[v] = true;
	mini[v] = h[v] + 1;
	for (pii p: nei[v]) {
		if(!mark[p.first]) {
			h[p.first] = h[v] + 1;
			find_cross(p.first, v);
		}
		if(p.first != mypar)
			mini[v] = min(mini[v], mini[p.first]);
		if(mini[p.first] > h[v]
		   && cnt[pii(min(v, p.first), max(v, p.first))] == 1)
			cross[p.second] = true;
	}
}

void tree_dfs(int v, int parent) {
	par[v] = parent;
	mark[v] = true;
	for (pii p: nei[v])
		if(cross[p.second])
			tree_nei[parent].push_back(p.first);
		else if(!mark[p.first])
			tree_dfs(p.first, parent);
}

int g_par(int v) {
	return (par[v] == v? v: (par[v] = g_par(par[v])));
}

void find_lca(int v) {
	mark[v] = true;
	for (int i = 1; i < LOG; i++)
		upper[v][i] = upper[upper[v][i - 1]][i - 1];
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			h[u] = h[v] + 1;
			upper[u][0] = v;
			find_lca(u);
		}
	}
}

inline int lca(int u, int v) {//in the same component
	if(h[u] < h[v])
		swap(u, v);
	for (int i = LOG - 1; i >= 0; i--)
		if(h[u] - (1LL << i) >= h[v])
			u = upper[u][i];
	if(u == v)
		return u;
	for (int i = LOG - 1; i >= 0; i--)
		if(upper[u][i] != upper[v][i]) {
			u = upper[u][i];
			v = upper[v][i];
		}
	return upper[u][0];
}

void check(int v) {
	mark[v] = true;
	for (int u: tree_nei[v]) {
		u = g_par(u);
		if(!mark[u]) {
			check(u);
			ups[v] += ups[u];
			dps[v] += dps[u];
		}
	}
	if(ups[v] && dps[v])
		cant = true;
}

int main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		cin >> u >> v;
		nei[--u].push_back(pii(--v, i));
		nei[v].push_back(pii(u, i));
		cnt[pii(min(u, v), max(u, v))]++;
	}
	for (int i = 0; i < n; i++)
		if(!mark[i])
			dfs(i, parent++);
	memset(mark, false, sizeof mark);
	for (int i = 0; i < n; i++)
		if(!mark[i])
			find_cross(i, i);
	memset(mark, false, sizeof mark);
	parent = 0;
	for (int i = 0; i < n; i++)
		if(!mark[i])
			tree_dfs(i, parent++);
	memset(mark, false, sizeof mark);
	memset(h, 0, sizeof h);
	for (int i = 0; i < parent; i++)
		if(!mark[i]) {
			upper[i][0] = i;
			find_lca(i);
		}
	while(q--) {
		cin >> u >> v;
		if(comp[--u] != comp[--v])
			cant = true;
		else {
			u = g_par(u);
			v = g_par(v);
			if(done[pii(u, v)])
				continue;
			int LCA = lca(u, v);
			ups[u]++;
			dps[v]++;
			ups[LCA]--;
			dps[LCA]--;
			done[pii(u, v)] = true;
		}
	}
	memset(mark, false, sizeof mark);
	for (int i = 0; i < parent; i++)
		if(!mark[i])
			check(i);
	cout << (cant? "NO": "YES");
	return 0;
}