Andrewid the Android is a galaxy-known detective. Now he is preparing a defense against a possible attack by hackers on a major computer network.

In this network are n vertices, some pairs of vertices are connected by m undirected channels. It is planned to transfer q important messages via this network, the i-th of which must be sent from vertex si to vertex di via one or more channels, perhaps through some intermediate vertices.

To protect against attacks a special algorithm was developed. Unfortunately it can be applied only to the network containing directed channels. Therefore, as new channels can't be created, it was decided for each of the existing undirected channels to enable them to transmit data only in one of the two directions.

Your task is to determine whether it is possible so to choose the direction for each channel so that each of the q messages could be successfully transmitted.

Input

The first line contains three integers n, m and q (1 ≤ n, m, q ≤ 2·105) — the number of nodes, channels and important messages.

Next m lines contain two integers each, vi and ui (1 ≤ vi, ui ≤ n, vi ≠ ui), that means that between nodes vi and ui is a channel. Between a pair of nodes can exist more than one channel.

Next q lines contain two integers si and di (1 ≤ si, di ≤ n, si ≠ di) — the numbers of the nodes of the source and destination of the corresponding message.

It is not guaranteed that in it initially possible to transmit all the messages.

Output

If a solution exists, print on a single line "Yes" (without the quotes). Otherwise, print "No" (without the quotes).

Examples

Input

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


Output

Yes


Input

3 2 2
1 2
3 2
1 3
2 1


Output

No


Input

3 3 2
1 2
1 2
3 2
1 3
2 1


Output

Yes

Note

In the first sample test you can assign directions, for example, as follows: 1 → 2, 1 → 3, 3 → 2, 4 → 3. Then the path for for the first message will be 1 → 3, and for the second one — 4 → 3 → 2.

In the third sample test you can assign directions, for example, as follows: 1 → 2, 2 → 1, 2 → 3. Then the path for the first message will be 1 → 2 → 3, and for the second one — 2 → 1.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.StringTokenizer;


public class D {

	static class UnionFind {                                              
		int[] p, rank, setSize;
		int numSets;

		public UnionFind(int N) 
		{
			p = new int[numSets = N];
			rank = new int[N];
			setSize = new int[N];
			for (int i = 0; i < N; i++) {  p[i] = i; setSize[i] = 1; }
		}

		public int findSet(int i) { return p[i] == i ? i : (p[i] = findSet(p[i])); }

		public boolean isSameSet(int i, int j) { return findSet(i) == findSet(j); }

		public void unionSet(int i, int j) 
		{ 
			if (isSameSet(i, j)) 
				return;
			numSets--; 
			int x = findSet(i), y = findSet(j);
			if(rank[x] > rank[y]) { p[y] = x; setSize[x] += setSize[y]; }
			else
			{	p[x] = y; setSize[y] += setSize[x];
			if(rank[x] == rank[y]) rank[y]++; 
			} 
		}

		public int numDisjointSets() { return numSets; }

		public int sizeOfSet(int i) { return setSize[findSet(i)]; }
	}

	static UnionFind uf;
	static ArrayList<Integer>[] adjList, tree;
	static Stack<Integer> stack;
	static int[] dfs_low, dfs_num, bridgeComp;
	static int V, counter, comp;
	static int P[][];
	static int dir[];
	static boolean seen[];
	static int L[];
	static Edge pr[];
	static boolean OK = true;

	static int solve(int i,int j)
	{


		if(j == 0) return pr[i].v;


		if(P[i][j] != -1) return P[i][j];

		return P[i][j] = solve(solve(i,j-1),j-1);


	}

	static class Edge
	{
		int u,v;
		boolean bridge;
		int dir;
		int top;
		int id;

		public Edge(int u,int v,int id,boolean k)
		{
			this.u = u;
			this.v = v;
			this.bridge = false;
			this.dir = - 1;
			this.top = - 1;
			this.id = id;
		}

		public Edge(int v,int dir,int top)
		{

			this.v = v;
			this.dir = dir;
			this.top = top;
		}

	}
	static int LCA(int x,int y)
	{

		if(L[x] > L[y])
		{
			int tmp = x;
			x = y;
			y = tmp;
		}

		int log = 25;

		// fix x to be on the same level as y
		for(int k = log ; k >= 0 ; k--)
		{

			int next = solve(y,k);
			if(L[x] <= L[next]) y = next;

		}
		if(x == y) return x;

		for(int k = log ; k >= 0; k--)
		{
			int nextX = solve(x,k); int nextY = solve(y,k);

			if(nextX != nextY)
			{
				x = nextX;
				y = nextY;
			}

		}



		return pr[x].v;
	}


	public static void dfsLCA(int u,int lvl)
	{

		L[u] = lvl;
		seen[u] = true;
		for(Integer k : tree[u])
		{

			if(seen[k]) continue;
			pr[k] = new Edge(u,-1,-1);
			dfsLCA(k, lvl + 1);
		}
	}



	// 1 pos > lca
	// 0 lca > pos
	static void query(int lca,int u,int col)
	{
		int pos = u;

		while(L[pos] > L[lca])
		{
			Edge e = pr[pos];
			if(e.dir == -1)
			{
				e.dir = col;
				e.top = lca;
				pos = e.v;
			}
			else
			{

				if(e.dir != col)
				{
					OK = false;
					return;
				}
				pos = e.top;
			}

		}
	}
	static void bridgeTree()
	{
		counter = 0;
		dfs_low = new int[V];
		dfs_num = new int[V];
		bridgeComp = new int[V];
		stack = new Stack<Integer>();
		tree = new ArrayList[V];
		for(int i = 0; i < V; ++i)
			tree[i] = new ArrayList<Integer>();
		for(int i = 0; i < V; ++i)
			if(dfs_num[i] == 0)
				dfs(i, -1);
		for(int u = 0; u < V; ++u)
			for(int v: adjList[u])
			{
				int x = bridgeComp[u], y = bridgeComp[v];  
				if(x != y)
					tree[x].add(y);
			}
	}

	static void dfs(int u, int p)
	{
		dfs_num[u] = dfs_low[u] = ++counter;
		stack.push(u);
		int mult = 0;
		for(int v: adjList[u])
			if(v != p || mult != 0)
				if(dfs_num[v] == 0)
				{
					dfs(v, u);
					dfs_low[u] = Math.min(dfs_low[u], dfs_low[v]);
					if(dfs_low[v] > dfs_num[u])
						extract(v);
				}
				else
					dfs_low[u] = Math.min(dfs_low[u], dfs_num[v]);
			else
				++mult;
		if(p == -1)
			extract(u);
	}

	static void extract(int u) 
	{ 
		++comp;
		while(true)
		{
			int v = stack.pop();
			bridgeComp[v] = u;
			if(v == u)
				break;
		}	
	}

	public static void main(String[] args) throws IOException 
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		V = sc.nextInt();
		uf = new UnionFind(V);
		int E = sc.nextInt(), Q = sc.nextInt();
		adjList = new ArrayList[V];
		P = new int[V][30];

		pr = new Edge[V];
		seen = new boolean[V];
		L = new int[V];
		for(int i = 0; i < V; ++i)
		{

			Arrays.fill(P[i],-1);
			adjList[i] = new ArrayList<Integer>();
		}
		for(int i = 0; i < E; ++i)
		{
			int u = sc.nextInt() - 1, v = sc.nextInt() - 1;
			adjList[u].add(v);
			adjList[v].add(u);
			uf.unionSet(u, v);
		}
		bridgeTree();
		pr[0] = new Edge(0,-1,-1);

		Arrays.fill(seen,false);
		for(int i = 0 ; i < comp ; i++)
		{
			if(!seen[i])
			{
				pr[i] = new Edge(i,-1,-1);
				dfsLCA(i,0);
			}
		}



		while(Q-->0)
		{
			int u = sc.nextInt() - 1, v = sc.nextInt() - 1;
			
			if(!uf.isSameSet(u, v))
				OK = false;
			else{


				int LCA = LCA(bridgeComp[u],bridgeComp[v]);
				
				query(LCA,bridgeComp[u],0);
				query(LCA,bridgeComp[v],1);
			}
		}
		out.println(OK ? "Yes":"No");
		out.flush();
		out.close();
	}


	static class Scanner 
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public Scanner(FileReader r){	br = new BufferedReader(r);}

		public String next() throws IOException 
		{
			while (st == null || !st.hasMoreTokens()) 
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException { return Double.parseDouble(next()); }

		public boolean ready() throws IOException {return br.ready();}


	}
}