#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define dd c=getchar()
int read() {int s=0;char c;while (dd,c>'9' || c<'0');while (c>='0' && c<='9') s=s*10+c-'0',dd;return s;}
#undef dd
const int N=2e5+7;
struct edge {
	int t,next;
}e[N<<1];
int n,m,q,cnt,num;
int head[N],u[N],v[N];
void add(int u,int t) {
	e[cnt].t=t;e[cnt].next=head[u];head[u]=cnt++;
	e[cnt].t=u;e[cnt].next=head[t];head[t]=cnt++;
}
int tp,t,now;
int low[N],dfn[N],st[N],ins[N],vis[N],bl[N],kin[N];
void Tarjan(int u,int fa) {
	low[u]=dfn[u]=++t;st[++tp]=u;
	for (int i=head[u];i!=-1;i=e[i].next) {
		int v=e[i].t;
		if ((i^1)==fa) continue;
		if (!dfn[v]) {
			Tarjan(v,i);
			low[u]=min(low[u],low[v]);
		}
		else if(!bl[v]) low[u]=min(low[u],dfn[v]);
	}
	if (low[u]==dfn[u]) {
		now++;kin[now]=num;
		while (tp) {
			int v=st[tp--];
			bl[v]=now;
			if (v==u) break;
		}
	}
}
int dee[N],fa[N][25],up[N],down[N];
void dfs(int u,int f) {
	ins[u]=1;fa[u][0]=f;dee[u]=dee[f]+1;
	for (int i=head[u];i!=-1;i=e[i].next) {
		int v=e[i].t;
		if (v==f || ins[v]) continue;
		dfs(v,u);
	}
}
int lca(int a,int b) {
	if (dee[b]<dee[a]) swap(a,b);
	for (int i=20;i>=0;i--) if (dee[fa[b][i]]>=dee[a]) b=fa[b][i];
	if (a==b) return a;
	for (int i=20;i>=0;i--) {
		if (fa[a][i]!=fa[b][i])
			a=fa[a][i],b=fa[b][i];
	}
	return fa[a][0];
}
void dfs1(int u) {
	ins[u]=1;
	for (int i=head[u];i;i=e[i].next) {
		int v=e[i].t;
		if (!ins[v]) {
			dfs1(v);
			up[u]+=up[v];
			down[u]+=down[v];
		}
	}
}
int main() {
	memset(head,-1,sizeof head);
	n=read();m=read();q=read();
	for (int i=1;i<=m;i++) {
		u[i]=read();v[i]=read();
		add(u[i],v[i]);
	}
	for (int i=1;i<=n;i++) if (!dfn[i]) num++,Tarjan(i,-1);
	memset(head,-1,sizeof head);
	cnt=0;
	for (int i=1;i<=m;i++) if (bl[u[i]]!=bl[v[i]]) add(bl[u[i]],bl[v[i]]);
	for (int i=1;i<=now;i++) if (!ins[i]) dfs(i,0);
	for (int i=1;i<=20;i++)
		for (int j=1;j<=now;j++)
			fa[j][i]=fa[fa[j][i-1]][i-1];
	for (int i=1,a,b;i<=q;i++) {
		a=bl[read()],b=bl[read()];
		if (kin[a]!=kin[b]) return puts("No"),0;
		if (a==b) continue;
		int c=lca(a,b);
		up[c]--;down[c]--;
		up[a]++;down[b]++;//差分
	}
	memset(ins,0,sizeof ins);
	for (int i=1;i<=now;i++) if (!ins[i]) dfs1(i);
	for (int i=1;i<=now;i++) if (up[i] && down[i]) return puts("No"),0;
	return puts("Yes"),0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define dd c=getchar()
int read() {int s=0;char c;while (dd,c>'9' || c<'0');while (c>='0' && c<='9') s=s*10+c-'0',dd;return s;}
#undef dd
const int N=2e5+7;
struct edge {
	int t,next;
}e[N<<1];
int n,m,q,cnt,num;
int head[N],u[N],v[N];
void add(int u,int t) {
	e[cnt].t=t;e[cnt].next=head[u];head[u]=cnt++;
	e[cnt].t=u;e[cnt].next=head[t];head[t]=cnt++;
}
int tp,t,now;
int low[N],dfn[N],st[N],ins[N],vis[N],bl[N],kin[N];
void Tarjan(int u,int fa) {
	low[u]=dfn[u]=++t;st[++tp]=u;
	for (int i=head[u];i!=-1;i=e[i].next) {
		int v=e[i].t;
		if ((i^1)==fa) continue;
		if (!dfn[v]) {
			Tarjan(v,i);
			low[u]=min(low[u],low[v]);
		}
		else if(!bl[v]) low[u]=min(low[u],dfn[v]);
	}
	if (low[u]==dfn[u]) {
		now++;kin[now]=num;int v;
		do {
			v=st[tp--];
			bl[v]=now;
		} while (v!=u);
	}
}
int dee[N],fa[N][25],up[N],down[N];
void dfs(int u,int f) {
	ins[u]=1;fa[u][0]=f;dee[u]=dee[f]+1;
	for (int i=head[u];i!=-1;i=e[i].next) {
		int v=e[i].t;
		if (v==f || ins[v]) continue;
		dfs(v,u);
	}
}
void findfa() {
	for (int i=1;i<=20;i++)
		for (int j=1;j<=now;j++)
			fa[j][i]=fa[fa[j][i-1]][i-1];
}
int lca(int a,int b) {
	if (dee[b]<dee[a]) swap(a,b);
	for (int i=20;i>=0;i--) if (dee[fa[b][i]]>=dee[a]) b=fa[b][i];
	if (a==b) return a;
	for (int i=20;i>=0;i--) {
		if (fa[a][i]!=fa[b][i])
			a=fa[a][i],b=fa[b][i];
	}
	return fa[a][0];
}
void dfs1(int u,int f) {
	ins[u]=1;
	for (int i=head[u];i;i=e[i].next) {
		int v=e[i].t;
		if (v==f) continue;
		if (ins[v]) vis[v]=1;
		if (!ins[v]) {
			dfs1(v,u);
			up[u]+=up[v];
			down[u]+=down[v];
		}
	}
}
int main() {
	memset(head,-1,sizeof head);
	n=read();m=read();q=read();
	for (int i=1;i<=m;i++) {
		u[i]=read();v[i]=read();
		add(u[i],v[i]);
	}
	for (int i=1;i<=n;i++) if (!dfn[i]) num++,Tarjan(i,-1);
	memset(head,-1,sizeof head);cnt=0;
	for (int i=1;i<=m;i++) if (bl[u[i]]!=bl[v[i]]) add(bl[u[i]],bl[v[i]]);
	for (int i=1;i<=now;i++) if (!ins[i]) dfs(i,0);
	findfa();
	for (int i=1,a,b;i<=q;i++) {
		a=bl[read()],b=bl[read()];
		if (kin[a]!=kin[b]) return puts("No"),0;
		if (a==b) continue;
		int c=lca(a,b);
		up[c]--;down[c]--;
		up[a]++;down[b]++;//差分
	}
	memset(ins,0,sizeof ins);
	for (int i=1;i<=now;i++) if (!ins[i]) dfs1(i,0);
	for (int i=1;i<=now;i++) if (!vis[i] && up[i] && down[i]) return puts("No"),0;
	return puts("Yes"),0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,q;
int tot,head[200005],nx[500005],fro[500005],to[500005];
int pre[200005],low[200005],noccs[200005],zhan[200005],now,cnt,top;
int sz[200005],l[200005],r[200005],sum,mx[200005][2],mn[200005][2];
void jia(int aa,int bb)
{
	nx[tot]=head[aa];
	fro[tot]=aa;
	to[tot]=bb;
	head[aa]=tot;
	tot++;
	return;
}
void tjan(int rt,int fa)
{
	zhan[++top]=rt;
	pre[rt]=++cnt;
	low[rt]=cnt;
	for(int i=head[rt];i;i=nx[i])
	{
		int yy=to[i];
		if((i^1)==fa) continue;
		if(!pre[yy])
		{
			tjan(yy,i);
			low[rt]=min(low[rt],low[yy]);
		}
		else if(!noccs[yy])
		{
			low[rt]=min(low[rt],pre[yy]);
		}
	}
	if(low[rt]==pre[rt])
	{
		now++;
		while(top)
		{
			int yy=zhan[top--];
			noccs[yy]=now;
			if(yy==rt) break;
		}
	}
	return;
}
void tj()
{
	for(int i=1;i<=n;++i)
	if(!pre[i])
	{
		tjan(i,-1);
	}
	memset(head,0,sizeof(head));
	int rr=tot;
	tot=0;
	for(int i=0;i<rr;i+=2)
	{
		int qq=noccs[fro[i]],pp=noccs[to[i]];
		if(qq==pp) continue;
		jia(qq,pp);
		jia(pp,qq);
	}
	return;
}
void dfs(int rt,int fa)
{
	l[rt]=++sum;
	mn[rt][0]=mn[rt][1]=sum;
	mx[rt][0]=mx[rt][1]=sum;
	for(int i=head[rt];i;i=nx[i])
	{
		int yy=to[i];
		if(yy==fa) continue;
		dfs(yy,rt);
	}
	r[rt]=sum;
}
int dfs2(int rt,int fa)
{
	pre[rt]=1;
	for(int i=head[rt];i;i=nx[i])
	{
		int yy=to[i];
		if(yy==fa) continue;
		if(!dfs2(yy,rt)) return 0;
		mn[rt][0]=min(mn[rt][0],mn[yy][0]);
		mx[rt][0]=max(mx[rt][0],mx[yy][0]);
		mn[rt][1]=min(mn[rt][1],mn[yy][1]);
		mx[rt][1]=max(mx[rt][1],mx[yy][1]);//cout<<mn[rt][1]<<endl;
	}
	bool aa=(mn[rt][0]<l[rt]||mx[rt][0]>r[rt]);
	bool bb=(mn[rt][1]<l[rt]||mx[rt][1]>r[rt]);
	if(aa&&bb) return 0;
	return 1;
}
int main()
{
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=m;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		jia(x,y);
		jia(y,x);
	}
	tj();
	for(int i=1;i<=now;++i)
	{
		pre[i]=0;
		if(!l[i]) dfs(i,-1);
	}
	int flag=1;
	for(int i=1;i<=q;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x=noccs[x];
		y=noccs[y];
		mx[x][0]=max(mx[x][0],l[y]);
		mn[x][0]=min(mn[x][0],l[y]);
		mx[y][1]=max(mx[y][1],l[x]);
		mn[y][1]=min(mn[y][1],l[x]);
	}
	for(int i=1;i<=now;++i)
	{
		if(!pre[i]&&!dfs2(i,-1)) flag=0;
	}
	if(flag) puts("Yes");
	else puts("No");
	return 0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,q;
int tot,head[200005],nx[500005],fro[500005],to[500005];
int pre[200005],low[200005],noccs[200005],zhan[200005],now,cnt,top;
int sz[200005],l[200005],r[200005],sum,mx[200005][2],mn[200005][2];
void jia(int aa,int bb)
{
	nx[tot]=head[aa];
	fro[tot]=aa;
	to[tot]=bb;
	head[aa]=tot;
	tot++;
	return;
}
void tjan(int rt,int fa)
{
	zhan[++top]=rt;
	pre[rt]=++cnt;
	low[rt]=cnt;
	for(int i=head[rt];i;i=nx[i])
	{
		int yy=to[i];
		if((i^1)==fa) continue;
		if(!pre[yy])
		{
			tjan(yy,i);
			low[rt]=min(low[rt],low[yy]);
		}
		else if(!noccs[yy])
		{
			low[rt]=min(low[rt],pre[yy]);
		}
	}
	if(low[rt]==pre[rt])
	{
		now++;
		while(top)
		{
			int yy=zhan[top--];
			noccs[yy]=now;
			if(yy==rt) break;
		}
	}
	return;
}
void tj()
{
	for(int i=1;i<=n;++i)
	if(!pre[i])
	{
		tjan(i,-1);
	}
	memset(head,0,sizeof(head));
	int rr=tot;
	tot=0;
	for(int i=0;i<rr;i+=2)
	{
		int qq=noccs[fro[i]],pp=noccs[to[i]];
		if(qq==pp) continue;
		jia(qq,pp);
		jia(pp,qq);
	}
	return;
}
void dfs(int rt,int fa)
{
	l[rt]=++sum;
	mn[rt][0]=mn[rt][1]=sum;
	mx[rt][0]=mx[rt][1]=sum;
	for(int i=head[rt];i;i=nx[i])
	{
		int yy=to[i];
		if(yy==fa) continue;
		dfs(yy,rt);
	}
	r[rt]=sum;
}
int dfs2(int rt,int fa)
{
	pre[rt]=1;
	for(int i=head[rt];i;i=nx[i])
	{
		int yy=to[i];
		if(yy==fa) continue;
		if(!dfs2(yy,rt)) return false;
		mn[rt][0]=min(mn[rt][0],mn[yy][0]);
		mx[rt][0]=max(mx[rt][0],mx[yy][0]);
		mn[rt][1]=min(mn[rt][1],mn[yy][1]);
		mx[rt][1]=max(mx[rt][1],mx[yy][1]);//cout<<mn[rt][1]<<endl;
	}
	bool aa=(mn[rt][0]<l[rt]||mx[rt][0]>r[rt]);
	bool bb=(mn[rt][1]<l[rt]||mx[rt][1]>r[rt]);
	if(aa&&bb) return 0;
	return 1;
}
int main()
{
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=m;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		jia(x,y);
		jia(y,x);
	}
	tj();
	for(int i=1;i<=now;++i)
	{
		pre[i]=0;
		if(!l[i]) dfs(i,-1);
	}
	int flag=1;
	for(int i=1;i<=q;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x=noccs[x];
		y=noccs[y];
		mx[x][0]=max(mx[x][0],l[y]);
		mn[x][0]=min(mn[x][0],l[y]);
		mx[y][1]=max(mx[y][1],l[x]);
		mn[y][1]=min(mn[y][1],l[x]);
	}
	for(int i=1;i<=now;++i)
	{
		if(!pre[i]&&!dfs2(i,-1)) flag=0;
	}
	if(flag) puts("Yes");
	else puts("No");
	return 0;
}


#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,q;
int tot,head[200005],nx[500005],fro[500005],to[500005];
int pre[200005],low[200005],noccs[200005],zhan[200005],now,cnt,top;
int sz[200005],l[200005],r[200005],sum,mx[200005][2],mn[200005][2];
void jia(int aa,int bb)
{
	nx[tot]=head[aa];
	fro[tot]=aa;
	to[tot]=bb;
	head[aa]=tot;
	tot++;
	return;
}
void tjan(int rt,int fa)
{
	zhan[++top]=rt;
	pre[rt]=++cnt;
	low[rt]=cnt;
	for(int i=head[rt];i!=-1;i=nx[i])
	{
		int yy=to[i];
		if((i^1)==fa) continue;
		if(!pre[yy])
		{
			tjan(yy,i);
			low[rt]=min(low[rt],low[yy]);
		}
		else if(!noccs[yy])
		{
			low[rt]=min(low[rt],pre[yy]);
		}
	}
	if(low[rt]==pre[rt])
	{
		now++;
		while(top)
		{
			int yy=zhan[top--];
			noccs[yy]=now;
			if(yy==rt) break;
		}
	}
	return;
}
void tj()
{
	for(int i=1;i<=n;++i)
	if(!pre[i])
	{
		tjan(i,-1);
	}
	memset(head,-1,sizeof(head));
	int rr=tot;
	tot=0;
	for(int i=0;i<rr;i+=2)
	{
		int qq=noccs[fro[i]],pp=noccs[to[i]];
		if(qq==pp) continue;
		jia(qq,pp);
		jia(pp,qq);
	}
	return;
}
void dfs(int rt,int fa)
{
	l[rt]=++sum;
	mn[rt][0]=mn[rt][1]=sum;
	mx[rt][0]=mx[rt][1]=sum;
	for(int i=head[rt];i!=-1;i=nx[i])
	{
		int yy=to[i];
		if(yy==fa) continue;
		dfs(yy,rt);
	}
	r[rt]=sum;
}
int dfs2(int rt,int fa)
{
	pre[rt]=1;
	for(int i=head[rt];i!=-1;i=nx[i])
	{
		int yy=to[i];
		if(yy==fa) continue;
		if(!dfs2(yy,rt)) return 0;
		mn[rt][0]=min(mn[rt][0],mn[yy][0]);
		mx[rt][0]=max(mx[rt][0],mx[yy][0]);
		mn[rt][1]=min(mn[rt][1],mn[yy][1]);
		mx[rt][1]=max(mx[rt][1],mx[yy][1]);//cout<<mn[rt][1]<<endl;
	}
	bool aa=(mn[rt][0]<l[rt]||mx[rt][0]>r[rt]);
	bool bb=(mn[rt][1]<l[rt]||mx[rt][1]>r[rt]);
	if(aa&&bb) return 0;
	return 1;
}
int main()
{
	memset(head,-1,sizeof(head));
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=m;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		jia(x,y);
		jia(y,x);
	}
	tj();
	for(int i=1;i<=now;++i)
	{
		pre[i]=0;
		if(!l[i]) dfs(i,-1);
	}
	int flag=1;
	for(int i=1;i<=q;++i)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x=noccs[x];
		y=noccs[y];
		mx[x][0]=max(mx[x][0],l[y]);
		mn[x][0]=min(mn[x][0],l[y]);
		mx[y][1]=max(mx[y][1],l[x]);
		mn[y][1]=min(mn[y][1],l[x]);
	}
	for(int i=1;i<=now;++i)
	{
		if(!pre[i]&&!dfs2(i,-1)) flag=0;
	}
	if(flag) puts("Yes");
	else puts("No");
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <ctime>
using namespace std;

const int Maxn=200005;

int q,cnt,st[Maxn],ed[Maxn],belong[Maxn];

int Get()
{
    char ch; int v=0; bool f=false;
    while (!isdigit(ch=getchar())) if (ch=='-') f=true; v=ch-48;
    while (isdigit(ch=getchar())) v=v*10+ch-48;
    if (f) return -v;else return v;
}

class Segment_Tree
{
    public:
    struct node { int L,R,lazy,val; }; node tr[Maxn<<2];

    void mark(int x,int v) { tr[x].lazy=v,tr[x].val=v; }
    void update(int x)
    {
        if (tr[x<<1].val==3 || tr[x<<1|1].val==3) { tr[x].val=3;return; }
        if (tr[x<<1].val==1)
        {
            if (tr[x<<1|1].val==2) tr[x].val=3;
            else tr[x].val=1;
        }
        if (tr[x<<1].val==2)
        {
            if (tr[x<<1|1].val==1) tr[x].val=3;
            else tr[x].val=2;
        }
        if (tr[x<<1].val==0) tr[x].val=tr[x<<1|1].val;
    }

    void maketree(int x,int l,int r)
    {
        tr[x].L=l,tr[x].R=r,tr[x].lazy=tr[x].val=0; int mid=(l+r)>>1;
        if (l<r) maketree(x<<1,l,mid),maketree(x<<1|1,mid+1,r);
    }

    void pushdown(int x)
    {
        if (tr[x].lazy!=0)
        {
            mark(x<<1,tr[x].lazy);
            mark(x<<1|1,tr[x].lazy);
        }
        tr[x].lazy=0;
    }

    bool modify(int x,int Ql,int Qr,int v)
    {
        if (Ql>Qr) return true;
        if (Ql<=tr[x].L && tr[x].R<=Qr)
        {
            if (tr[x].val!=0 && tr[x].val!=v) return false;
            mark(x,v);
            return true;
        }
        else
        {
            pushdown(x); bool flag=true;
            int mid=(tr[x].L+tr[x].R)>>1;
            if (Ql<=mid)
            {
                if (!modify(x<<1,Ql,Qr,v)) return false;
            }
            if (Qr>=mid+1)
            {
                if (!modify(x<<1|1,Ql,Qr,v)) return false;
            }
            update(x);
            return true;
        }
    }

}SGT;

struct Tree
{
    int n,m,tot,dfn,fst[Maxn],pre[Maxn<<1],to[Maxn<<1],size[Maxn],depth[Maxn],fa[Maxn],top[Maxn],pos[Maxn],son[Maxn]
    ,val[Maxn];
    bool vis[Maxn];
    void init() { dfn=tot=0; for (int i=1;i<=n;i++) fst[i]=0,vis[i]=false,val[i]=0; }
    void add(int x,int y)
    {
        pre[++tot]=fst[x],fst[x]=tot,to[tot]=y;
        pre[++tot]=fst[y],fst[y]=tot,to[tot]=x;
    }

    void dfs1(int x)
    {
        size[x]=1,vis[x]=true; int maxid=n+1;
        for (int i=fst[x];i;i=pre[i])
        {
            int y=to[i];
            if (!vis[y])
            {
                depth[y]=depth[x]+1,fa[y]=x,dfs1(y),size[x]+=size[y];
                if (size[y]>size[maxid]) maxid=y;
            }
        }
        son[x]=maxid;
    }

    void dfs2(int x,int ne)
    {
        top[x]=ne,pos[x]=++dfn,vis[x]=true;
        if (son[x]!=n+1)
        {
            dfs2(son[x],ne);
            for (int i=fst[x];i;i=pre[i])
            {
                int y=to[i];
                if (!vis[y] && y!=son[x]) dfs2(y,y);
            }
        }
    }

    int getlca(int x,int y)
    {
        while (top[x]!=top[y])
        {
            if (depth[top[x]]<depth[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        if (depth[x]<depth[y]) return x;
        else return y;
    }

    bool check(int x,int y,int v)
    {
        while (top[x]!=top[y])
        {
            if (!SGT.modify(1,pos[top[x]],pos[x],v)) return false;
            x=fa[top[x]];
        }
        if (!SGT.modify(1,pos[y]+1,pos[x],v)) return false;
        return true;
    }

    bool work()
    {
        size[n+1]=-1;
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) depth[i]=1,dfs1(i);
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) dfs2(i,i);
        SGT.maketree(1,1,dfn);
        for (int i=1;i<=q;i++)
        {
            st[i]=belong[st[i]],ed[i]=belong[ed[i]];
            int f=getlca(st[i],ed[i]);
            if (!check(st[i],f,1)) return false;
            if (!check(ed[i],f,2)) return false;
        }
        return true;
    }
}T;

struct Graph
{
    int n,m,tot,dfstot,fst[Maxn],from[Maxn<<1],pre[Maxn<<1],to[Maxn<<1],dfn[Maxn],low[Maxn];
    bool vis[Maxn],flag[Maxn<<1];
    void add(int x,int y)
    {
        pre[++tot]=fst[x],fst[x]=tot,from[tot]=x,to[tot]=y,flag[tot]=false;
        pre[++tot]=fst[y],fst[y]=tot,from[tot]=y,to[tot]=x,flag[tot]=false;
    }

    void init()
    {
        n=Get(),m=Get(),q=Get(); tot=1,dfstot=0; int x,y;
        for (int i=1;i<=n;i++) fst[i]=0;
        for (int i=1;i<=m;i++) x=Get(),y=Get(),add(x,y);
        for (int i=1;i<=q;i++) st[i]=Get(),ed[i]=Get();
    }

    void tarjan(int x,int prev)
    {
        vis[x]=true; dfn[x]=low[x]=++dfstot;
        for (int i=fst[x];i;i=pre[i])
        {
            if (i==(prev^1)) continue;
            int y=to[i];
            if (!vis[y]) tarjan(y,i),low[x]=min(low[x],low[y]);
            else low[x]=min(low[x],dfn[y]);
        }
        if (low[x]==dfn[x]) flag[prev]=flag[prev^1]=true;
    }

    void dfs(int x)
    {
        vis[x]=true; belong[x]=T.n;
        for (int i=fst[x];i;i=pre[i])
        {
            int y=to[i];
            if (!vis[y] && !flag[i]) dfs(y);
        }
    }

    void work()
    {
        for (int i=1;i<=n;i++) vis[i]=false;
        tarjan(1,-1); T.n=0;
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) T.n++,dfs(i);
        T.init();
        for (int i=2;i<=tot;i+=2) if (flag[i]) T.add(belong[from[i]],belong[to[i]]);
    }
}G;

int main()
{
    G.init();
    G.work();
    if (T.work()) puts("Yes");
    else puts("No");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <ctime>
using namespace std;

const int Maxn=200005;

int q,cnt,st[Maxn],ed[Maxn],belong[Maxn];

int Get()
{
    char ch; int v=0; bool f=false;
    while (!isdigit(ch=getchar())) if (ch=='-') f=true; v=ch-48;
    while (isdigit(ch=getchar())) v=v*10+ch-48;
    if (f) return -v;else return v;
}

class Segment_Tree
{
    public:
    struct node { int L,R,lazy,val; }; node tr[Maxn<<2];

    void mark(int x,int v) { tr[x].lazy=v,tr[x].val=v; }
    void update(int x)
    {
        if (tr[x<<1].val==3 || tr[x<<1|1].val==3) { tr[x].val=3;return; }
        if (tr[x<<1].val==1)
        {
            if (tr[x<<1|1].val==2) tr[x].val=3;
            else tr[x].val=1;
        }
        if (tr[x<<1].val==2)
        {
            if (tr[x<<1|1].val==1) tr[x].val=3;
            else tr[x].val=2;
        }
        if (tr[x<<1].val==0) tr[x].val=tr[x<<1|1].val;
    }

    void maketree(int x,int l,int r)
    {
        tr[x].L=l,tr[x].R=r,tr[x].lazy=tr[x].val=0; int mid=(l+r)>>1;
        if (l<r) maketree(x<<1,l,mid),maketree(x<<1|1,mid+1,r);
    }

    void pushdown(int x)
    {
        if (tr[x].lazy!=0)
        {
            mark(x<<1,tr[x].lazy);
            mark(x<<1|1,tr[x].lazy);
        }
        tr[x].lazy=0;
    }

    bool modify(int x,int Ql,int Qr,int v)
    {
        if (Ql>Qr) return true;
        if (Ql<=tr[x].L && tr[x].R<=Qr)
        {
            if (tr[x].val!=0 && tr[x].val!=v) return false;
            mark(x,v);
            return true;
        }
        else
        {
            pushdown(x); bool flag=true;
            int mid=(tr[x].L+tr[x].R)>>1;
            if (Ql<=mid)
            {
                if (!modify(x<<1,Ql,Qr,v)) return false;
            }
            if (Qr>=mid+1)
            {
                if (!modify(x<<1|1,Ql,Qr,v)) return false;
            }
            update(x);
            return true;
        }
    }

}SGT;

struct Tree
{
    int n,m,tot,dfn,fst[Maxn],pre[Maxn<<1],to[Maxn<<1],size[Maxn],depth[Maxn],fa[Maxn],top[Maxn],pos[Maxn],son[Maxn]
    ,val[Maxn],ff[Maxn];
    bool vis[Maxn];
    void init() { dfn=tot=0; for (int i=1;i<=n;i++) fst[i]=0,vis[i]=false,val[i]=0; }
    void add(int x,int y)
    {
        pre[++tot]=fst[x],fst[x]=tot,to[tot]=y;
        pre[++tot]=fst[y],fst[y]=tot,to[tot]=x;
    }

    void dfs1(int x)
    {
        size[x]=1,vis[x]=true; int maxid=n+1;
        for (int i=fst[x];i;i=pre[i])
        {
            int y=to[i];
            if (!vis[y])
            {
                depth[y]=depth[x]+1,fa[y]=x,ff[y]=ff[x],dfs1(y),size[x]+=size[y];
                if (size[y]>size[maxid]) maxid=y;
            }
        }
        son[x]=maxid;
    }

    void dfs2(int x,int ne)
    {
        top[x]=ne,pos[x]=++dfn,vis[x]=true;
        if (son[x]!=n+1)
        {
            dfs2(son[x],ne);
            for (int i=fst[x];i;i=pre[i])
            {
                int y=to[i];
                if (!vis[y] && y!=son[x]) dfs2(y,y);
            }
        }
    }

    int getlca(int x,int y)
    {
        while (top[x]!=top[y])
        {
            if (depth[top[x]]<depth[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        if (depth[x]<depth[y]) return x;
        else return y;
    }

    bool check(int x,int y,int v)
    {
        while (top[x]!=top[y])
        {
            if (!SGT.modify(1,pos[top[x]],pos[x],v)) return false;
            x=fa[top[x]];
        }
        if (!SGT.modify(1,pos[y]+1,pos[x],v)) return false;
        return true;
    }

    bool work()
    {
        size[n+1]=-1;
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) ff[i]=i,depth[i]=1,dfs1(i);
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) dfs2(i,i);
        SGT.maketree(1,1,dfn);
        for (int i=1;i<=q;i++)
        {
            st[i]=belong[st[i]],ed[i]=belong[ed[i]];
            if (ff[st[i]]!=ff[ed[i]]) return false;
            int f=getlca(st[i],ed[i]);
            if (!check(st[i],f,1)) return false;
            if (!check(ed[i],f,2)) return false;
        }
        return true;
    }
}T;

struct Graph
{
    int n,m,tot,dfstot,fst[Maxn],from[Maxn<<1],pre[Maxn<<1],to[Maxn<<1],dfn[Maxn],low[Maxn];
    bool vis[Maxn],flag[Maxn<<1];
    void add(int x,int y)
    {
        pre[++tot]=fst[x],fst[x]=tot,from[tot]=x,to[tot]=y,flag[tot]=false;
        pre[++tot]=fst[y],fst[y]=tot,from[tot]=y,to[tot]=x,flag[tot]=false;
    }

    void init()
    {
        n=Get(),m=Get(),q=Get(); tot=1,dfstot=0; int x,y;
        for (int i=1;i<=n;i++) fst[i]=0;
        for (int i=1;i<=m;i++) x=Get(),y=Get(),add(x,y);
        for (int i=1;i<=q;i++) st[i]=Get(),ed[i]=Get();
    }

    void tarjan(int x,int prev)
    {
        vis[x]=true; dfn[x]=low[x]=++dfstot;
        for (int i=fst[x];i;i=pre[i])
        {
            if (i==(prev^1)) continue;
            int y=to[i];
            if (!vis[y]) tarjan(y,i),low[x]=min(low[x],low[y]);
            else low[x]=min(low[x],dfn[y]);
        }
        if (low[x]==dfn[x]) flag[prev]=flag[prev^1]=true;
    }

    void dfs1(int x)
    {
        vis[x]=true; belong[x]=T.n;
        for (int i=fst[x];i;i=pre[i])
        {
            int y=to[i];
            if (!vis[y] && !flag[i]) dfs1(y);
        }
    }

    void work()
    {
        for (int i=1;i<=n;i++) vis[i]=false;
        tarjan(1,-1); T.n=0;
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) T.n++,dfs1(i);
        T.init();
        for (int i=2;i<=tot;i+=2) if (flag[i]) T.add(belong[from[i]],belong[to[i]]);
    }
}G;

int main()
{
    G.init();
    G.work();
    if (T.work()) puts("Yes");
    else puts("No");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <ctime>
using namespace std;

const int Maxn=200005;

int q,cnt,st[Maxn],ed[Maxn],belong[Maxn];

int Get()
{
    char ch; int v=0; bool f=false;
    while (!isdigit(ch=getchar())) if (ch=='-') f=true; v=ch-48;
    while (isdigit(ch=getchar())) v=v*10+ch-48;
    if (f) return -v;else return v;
}

class Segment_Tree
{
    public:
    struct node { int L,R,lazy,val; }; node tr[Maxn<<2];

    void mark(int x,int v) { tr[x].lazy=v,tr[x].val=v; }
    void update(int x)
    {
        if (tr[x<<1].val==3 || tr[x<<1|1].val==3) { tr[x].val=3;return; }
        if (tr[x<<1].val==1)
        {
            if (tr[x<<1|1].val==2) tr[x].val=3;
            else tr[x].val=1;
        }
        if (tr[x<<1].val==2)
        {
            if (tr[x<<1|1].val==1) tr[x].val=3;
            else tr[x].val=2;
        }
        if (tr[x<<1].val==0) tr[x].val=tr[x<<1|1].val;
    }

    void maketree(int x,int l,int r)
    {
        tr[x].L=l,tr[x].R=r,tr[x].lazy=tr[x].val=0; int mid=(l+r)>>1;
        if (l<r) maketree(x<<1,l,mid),maketree(x<<1|1,mid+1,r);
    }

    void pushdown(int x)
    {
        if (tr[x].lazy!=0)
        {
            mark(x<<1,tr[x].lazy);
            mark(x<<1|1,tr[x].lazy);
        }
        tr[x].lazy=0;
    }

    bool modify(int x,int Ql,int Qr,int v)
    {
        if (Ql>Qr) return true;
        if (Ql<=tr[x].L && tr[x].R<=Qr)
        {
            if (tr[x].val!=0 && tr[x].val!=v) return false;
            mark(x,v);
            return true;
        }
        else
        {
            pushdown(x); bool flag=true;
            int mid=(tr[x].L+tr[x].R)>>1;
            if (Ql<=mid)
            {
                if (!modify(x<<1,Ql,Qr,v)) return false;
            }
            if (Qr>=mid+1)
            {
                if (!modify(x<<1|1,Ql,Qr,v)) return false;
            }
            update(x);
            return true;
        }
    }

}SGT;

struct Tree
{
    int n,m,tot,dfn,fst[Maxn],pre[Maxn<<1],to[Maxn<<1],size[Maxn],depth[Maxn],fa[Maxn],top[Maxn],pos[Maxn],son[Maxn]
    ,val[Maxn],ff[Maxn];
    bool vis[Maxn];
    void init() { dfn=tot=0; for (int i=1;i<=n;i++) fst[i]=0,vis[i]=false,val[i]=0; }
    void add(int x,int y)
    {
        pre[++tot]=fst[x],fst[x]=tot,to[tot]=y;
        pre[++tot]=fst[y],fst[y]=tot,to[tot]=x;
    }

    void dfs1(int x)
    {
        size[x]=1,vis[x]=true; int maxid=n+1;
        for (int i=fst[x];i;i=pre[i])
        {
            int y=to[i];
            if (!vis[y])
            {
                depth[y]=depth[x]+1,fa[y]=x,ff[y]=ff[x],dfs1(y),size[x]+=size[y];
                if (size[y]>size[maxid]) maxid=y;
            }
        }
        son[x]=maxid;
    }

    void dfs2(int x,int ne)
    {
        top[x]=ne,pos[x]=++dfn,vis[x]=true;
        if (son[x]!=n+1)
        {
            dfs2(son[x],ne);
            for (int i=fst[x];i;i=pre[i])
            {
                int y=to[i];
                if (!vis[y] && y!=son[x]) dfs2(y,y);
            }
        }
    }

    int getlca(int x,int y)
    {
        while (top[x]!=top[y])
        {
            if (depth[top[x]]<depth[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        if (depth[x]<depth[y]) return x;
        else return y;
    }

    bool check(int x,int y,int v)
    {
        while (top[x]!=top[y])
        {
            if (!SGT.modify(1,pos[top[x]],pos[x],v)) return false;
            x=fa[top[x]];
        }
        if (!SGT.modify(1,pos[y]+1,pos[x],v)) return false;
        return true;
    }

    bool work()
    {
        size[n+1]=-1;
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) ff[i]=i,depth[i]=1,dfs1(i);
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) dfs2(i,i);
        SGT.maketree(1,1,dfn);
        for (int i=1;i<=q;i++)
        {
            st[i]=belong[st[i]],ed[i]=belong[ed[i]];
            if (ff[st[i]]!=ff[ed[i]]) return false;
            int f=getlca(st[i],ed[i]);
            if (!check(st[i],f,1)) return false;
            if (!check(ed[i],f,2)) return false;
        }
        return true;
    }
}T;

struct Graph
{
    int n,m,tot,dfstot,fst[Maxn],from[Maxn<<1],pre[Maxn<<1],to[Maxn<<1],dfn[Maxn],low[Maxn];
    bool vis[Maxn],flag[Maxn<<1];
    void add(int x,int y)
    {
        pre[++tot]=fst[x],fst[x]=tot,from[tot]=x,to[tot]=y,flag[tot]=false;
        pre[++tot]=fst[y],fst[y]=tot,from[tot]=y,to[tot]=x,flag[tot]=false;
    }

    void init()
    {
        n=Get(),m=Get(),q=Get(); tot=1,dfstot=0; int x,y;
        for (int i=1;i<=n;i++) fst[i]=0;
        for (int i=1;i<=m;i++) x=Get(),y=Get(),add(x,y);
        for (int i=1;i<=q;i++) st[i]=Get(),ed[i]=Get();
    }

    void tarjan(int x,int prev)
    {
        vis[x]=true; dfn[x]=low[x]=++dfstot;
        for (int i=fst[x];i;i=pre[i])
        {
            if (i==(prev^1)) continue;
            int y=to[i];
            if (!vis[y]) tarjan(y,i),low[x]=min(low[x],low[y]);
            else low[x]=min(low[x],dfn[y]);
        }
        if (low[x]==dfn[x]) flag[prev]=flag[prev^1]=true;
    }

    void dfs(int x)
    {
        vis[x]=true; belong[x]=T.n;
        for (int i=fst[x];i;i=pre[i])
        {
            int y=to[i];
            if (!vis[y] && !flag[i]) dfs(y);
        }
    }

    void work()
    {
        for (int i=1;i<=n;i++) vis[i]=false;
        tarjan(1,-1); T.n=0;
        for (int i=1;i<=n;i++) vis[i]=false;
        for (int i=1;i<=n;i++) if (!vis[i]) T.n++,dfs(i);
        T.init();
        for (int i=2;i<=tot;i+=2) if (flag[i]) T.add(belong[from[i]],belong[to[i]]);
    }
}G;

int main()
{
    G.init();
    G.work();
    if (T.work()) puts("Yes");
    else puts("No");
    return 0;
}


#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;

// variables for find bridges
vector<int> ori[200002];
int px[200002], py[200002], brid[200002];

int chk[200002], up[200002];

int gety(int x, int e)
{
    return x == px[e] ? py[e] : px[e];
}

void dfs(int x, int l, int d)
{
    chk[x] = 1; up[x] = d;
    for (int i=0;i<ori[x].size();i++){
        int e = ori[x][i];
        if (e == l) continue;

        int y = gety(x,e);
        if (chk[y] == 0){
            dfs(y,e,d+1);
            if (up[y] > d) brid[e] = 1;
        }
        if (up[x] > up[y]) up[x] = up[y];
    }
}

// variables for make supernodes
vector<int> sup[200002];
int par[200002], grp[200002], pri[200002];

int find(int x)
{
    if (par[x] != x) par[x] = find(par[x]);
    return par[x];
}

// get answer
int in[200002], out[200002], erase[200002];
int dbl[200002][18], dep[200002];

void go(int x, int p)
{
    chk[x] = 1;
    dbl[x][0] = p; dep[x] = dep[p] + 1;
    for (int i=1;i<18;i++) dbl[x][i] = dbl[dbl[x][i-1]][i-1];
    for (int y : sup[x]) if (!chk[y]) go(y,x);
}

int lca(int x, int y)
{
    if (dep[x] > dep[y]) return lca(y,x);
    int dif = dep[y] - dep[x];
    for (int k=0;k<18;k++) if (dif & (1 << k)) y = dbl[y][k];
    if (x == y) return x;
    for (int k=17;k>=0;k--){
        int px = dbl[x][k];
        int py = dbl[y][k];
        if (px != py) x = px, y = py;
    }
    x = dbl[x][0]; y = dbl[y][0];
    return x;
}

int under(int x)
{
    chk[x] = 1;
    int pos = in[x], neg = out[x];
    for (int y : sup[x]) if (!chk[y]){
        int c = under(y);
        if (c > 0) pos += c;
        if (c < 0) neg -= c;
    }
    pos -= erase[x];
    neg -= erase[x];
    if (pos == 0) return -neg;
    if (neg == 0) return pos;
    return 100000000;
}

int main()
{
    // input
    int N,M,K;
    scanf ("%d %d %d",&N,&M,&K);
    for (int i=1;i<=M;i++){
        scanf ("%d %d",&px[i],&py[i]);
        ori[px[i]].push_back(i);
        ori[py[i]].push_back(i);
    }

    // find bridges
    for (int i=1;i<=N;i++) if (!chk[i]) dfs(i,0,0);

    // make supernodes
    for (int i=1;i<=N;i++) par[i] = i;
    for (int i=1;i<=M;i++) if (!brid[i]){
        int x = find(px[i]);
        int y = find(py[i]);
        if (x != y) par[x] = y;
    }
    int G = 0;
    for (int i=1;i<=N;i++)if (par[i] == i){
        grp[i] = ++G;
        pri[G] = i;
    }
    for (int i=1;i<=N;i++) grp[i] = grp[find(i)];
    for (int i=1;i<=M;i++){
        int x = grp[find(px[i])];
        int y = grp[find(py[i])];
        if (x != y){
            sup[x].push_back(y);
            sup[y].push_back(x);
        }
    }
    for (int i=1;i<=G;i++){
        sort(sup[i].begin(),sup[i].end());
        sup[i].erase(unique(sup[i].begin(),sup[i].end()),sup[i].end());
    }

    for (int i=1;i<=G;i++) chk[i] = 0;
    for (int i=1;i<=G;i++) if (!chk[i]) go(i,0);
    for (int i=0;i<K;i++){
        int x,y; scanf ("%d %d",&x,&y);
        x = grp[find(x)]; y = grp[find(y)];
        if (x != y){
            in[x]++; out[y]++;
            int z = lca(x,y);
            if (z == 0){
                puts("No");
                return 0;
            }
            erase[z]++;
        }
    }

    for (int i=1;i<=G;i++) chk[i] = 0;
    for (int i=1;i<=G;i++) if (!chk[i]){
        if (under(i) != 0){
            puts("No");
            return 0;
        }
    }

    puts("Yes");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <sstream>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <ctime>

#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define Rep(i, n) for (int i = 1; i <= (n); ++i)
#define clr(x, a) memset(x, (a), sizeof x)
using namespace std;
typedef long long ll;
int const N = 202020;
int const M = 1001000;
int n, m;
struct edges{ int u, next; } e[M];
int p[N], idx;
void addedge(int u, int v) {
    e[idx].u = v, e[idx].next = p[u], p[u] = idx++;
}
void init() { idx = 0; clr(p, 0xff); }

struct CutVertex {
    int dfn[N], low[N], sc[N], cnt;
    void dfs(int u, int ori, int pre) {
        dfn[u] = low[u] = ++cnt;
        for (int i = p[u]; ~i; i = e[i].next) {
            int v = e[i].u;
            if (!dfn[v]) {
                dfs(v, ori, i);
                low[u] = min(low[u], low[v]);
                if (low[v] >= dfn[u]) ++sc[u];
            }
            else if ((i ^ 1) != pre) { // ensure (e[(u, v)] ^ e[(v, u)]) == 1
                low[u] = min(low[u], dfn[v]);
            }
        }
        if (u != ori) ++sc[u];
    }
    void solve() {
        cnt = 0, clr(dfn, 0), clr(sc, 0);
        Rep(i, n) if (!dfn[i]) dfs(i, i, -1);
    }
} cv;

int col[N], cc; // clr(col, 0), cc = 0;
void dfs(int u) {
    if (!col[u]) col[u] = ++cc;
    for (int i = p[u]; ~i; i = e[i].next) {
        int v = e[i].u;
        if (!col[v]) {
            if (cv.low[v] > cv.dfn[u]) col[v] = ++cc;
            else col[v] = col[u];
            dfs(v);
        }
    }
}

struct Tree {
    int n;
    struct edges{ int u, dir, next; } e[M];
    int p[N], idx;
    void addedge(int u, int v) {
        e[idx].dir = 0;
        e[idx].u = v, e[idx].next = p[u], p[u] = idx++;
    }
    int d[N], r[N];
    int dep[N], dp[21][N]; // N ~ 1e6
    int up[N], down[N];

    void dfs(int u, int d, int pre, int rt) {
        r[u] = rt;
        dep[u] = d, dp[0][u] = pre;
        for (int i = 1; (1 << i) <= d; ++i)
            dp[i][u] = dp[i - 1][dp[i - 1][u]];
        for (int i = p[u]; ~i; i = e[i].next) {
            int v = e[i].u;
            if (v != pre) dfs(v, d + 1, u, rt);
        }
    }
    int lca(int a, int b) {
        if (r[a] != r[b]) return -1;
        if (dep[a] < dep[b]) swap(a, b);
        for (int t = dep[a] - dep[b], step = 0; t; ++step, t >>= 1)
            if (t & 1) a = dp[step][a];
        if (a == b) return a;
        for (int i = 20; ~i; --i)
            if (dp[i][a] != dp[i][b]) a = dp[i][a], b = dp[i][b];
        return dp[0][a];
    }
    bool fillPath(int a, int rt, int x) {
        while (dep[a] > dep[rt]) {
            int a0 = a;
            if (x == 1) {
                if (down[a] != 0) return 0;
                if (up[a] != 0) a = up[a];
                if (up[a0] == 0 || dep[rt] < dep[up[a0]]) {
                    up[a0] = rt;
                }
            } else {
                if (up[a] != 0) return 0;
                if (down[a] != 0) a = down[a];
                if (down[a0] == 0 || dep[rt] < dep[down[a0]]) {
                    down[a0] = rt;
                }
            }
            a = dp[0][a];
        }

        return 1;
    }
    void init() {
        idx = 0; clr(p, 0xff); clr(dep, 0xff); clr(d, 0);
        clr(up, 0); clr(down, 0);
    }
    void initLca() { Rep(i, n) if (dep[i] == -1) dfs(i, 0, -1, i); }
} tr;
set<pair<int, int> > mark;

void buildTree() {
    tr.init(); tr.n = cc;
    Rep(u, n) {
        for (int i = p[u]; ~i; i = e[i].next) {
            int v = e[i].u;
            if (col[u] != col[v]) {
                int mi = min(col[u], col[v]);
                int mx = max(col[u], col[v]);
                if (mark.count(make_pair(mi, mx))) continue;
                mark.insert(make_pair(mi, mx));
                tr.addedge(mi, mx);
                tr.addedge(mx, mi);
            }
        }
    }
}

int main() {
    int q; scanf("%d%d%d", &n, &m, &q);
    init();
    int a, b;
    rep(i, m) {
        scanf("%d%d", &a, &b);
        addedge(a, b);
        addedge(b, a);
    }
    cv.solve();
    Rep(i, n) if (!col[i]) dfs(i);
    buildTree();
    tr.initLca();

    bool ok = 1;
    rep(i, q) {
        scanf("%d%d", &a, &b);
        if (!ok) continue;
        a = col[a], b = col[b];
        if (a == b) continue;
        int r = tr.lca(a, b);
        if (r == -1) ok = 0;
        else {
            bool lf = tr.fillPath(a, r, 1);
            bool rf = tr.fillPath(b, r, -1);
            if (!lf || !rf) ok = 0;
        }
    }
    if (ok) puts("Yes");
    else puts("No");
    return 0;
}


#include <cstdlib>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <iomanip>
#include <cctype>
#include <complex>
#include <numeric>

#define foreach(i, store) for(__typeof((store).begin()) i = (store).begin() ; i != (store).end() ; i++)
#define sqr(x) ((x)*(x))
#define comb2(x) ((x)*((x)-1)/2)
#define mod(x) ((x) % MOD)
#define All(store) store.begin(), store.end()
#define Unique(store) store.resize(unique(All(store)) - store.begin())
#define Assign(a, b, s, e) for(int i = s ; i < e ; i++) b[i] = a[i];
#define IF(condition, x, y) ((condition) ? (x) : (y))
#define psb push_back
#define ppb pop_back
#define psf push_front
#define ppf pop_front
#define create make_pair
#define pii pair<int, int>
#define ppi pair< pii, int>
#define pll pair<ll, ll>
#define Min(x, y) IF(x < y, x, y)
#define Max(x, y) IF(x > y, x, y)

using namespace std;

ifstream fin ("in.in");
ofstream fout ("out.out");

typedef long long ll;
const int N = 2e5 + 1, L = 20;
int n, m, q, k, x[N], y[N];
int c[N], dep[N], up[N], down[N], par[N][L];
vector<int> adj[N];
bool mark[N], isCut[N];

void DFS(int u, int e = -1)
{
    mark[u] = true;

    up[u] = dep[u];

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        int v = x[j] + y[j] - u;

        if(!mark[v])
        {
            dep[v] = dep[u] + 1;
            DFS(v, j);

            if(up[v] >= dep[u])
                isCut[j] = true;
        }

        else if(j != e)
            up[u] = min(dep[v], up[u]);
    }
}

void color(int u)
{
    c[u] = k;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        if(isCut[j]) continue;

        int v = x[j] + y[j] - u;
        if(!c[v]) color(v);
    }
}

void dfs(int u)
{
    dep[u] = dep[par[u][0]] + 1;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v != par[u][0])
        {
            par[v][0] = u;
            dfs(v);
        }
    }
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v]) swap(u, v);

    for(int i = L-1 ; i >= 0 ; i--)
        if(dep[par[v][i]] >= dep[u]) v = par[v][i];

     if(u == v) return u;

     for(int i = L-1 ; i >= 0 ; i--)
         if(par[u][i] != par[v][i])
         {
              u = par[u][i];
              v = par[v][i];
         }

    return par[u][0];
}

bool can(int u)
{
    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v == par[u][0]) continue;

        if(!can(v)) return false;

        down[u] += down[v];
        up[u] += up[v];
    }

    return !up[u] || !down[u];
}

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

    cin >> n >> m >> q;

    for(int i = 0 ; i < m ; i++)
    {
        cin >> x[i] >> y[i];
        adj[-- x[i]].psb(i);
        adj[-- y[i]].psb(i);
    }

    for(int i = 0 ; i < n ; i++)
        if(!mark[i])
            DFS(i);

    for(int i = 0 ; i < n ; i++)
        if(!c[i])
        {
            k++;
            color(i);
        }

    for(int i = 0 ; i < n ; i++)
        adj[i].clear();

    for(int i = 0 ; i < m ; i++)
        if(isCut[i])
        {
            adj[c[x[i]]].psb(c[y[i]]);
            adj[c[y[i]]].psb(c[x[i]]);
        }

    memset(par, -1, sizeof par);
    dep[0] = -1;

    for(int i = 1 ; i <= k ; i++)
        if(par[i][0] == -1)
        {
            par[i][0] = 0;
            dfs(i);
        }

    for(int i = 1 ; i < L ; i++)
        for(int j = 1 ; j <= k ; j++)
            par[j][i] = par[par[j][i-1]][i-1];

    memset(up, 0, sizeof up);

    while(q--)
    {
        int s, t;
        cin >> s >> t;
        s = c[s-1], t = c[t-1];

        if(s == t) continue;
        if(par[s][L-1] != par[t][L-1]) return (cout << "No"), 0;

        int lca = LCA(s, t);
        up[s]++, up[lca]--;
        down[t]++, down[lca]--;
    }

    for(int i = 1 ; i <= k ; i++)
        if(!par[i][0])
            if(!can(i))
                 return (cout << "No"), 0;

    cout << "Yes";

    return 0;
}


#include <cstdlib>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <iomanip>
#include <cctype>
#include <complex>
#include <numeric>

#define foreach(i, store) for(__typeof((store).begin()) i = (store).begin() ; i != (store).end() ; i++)
#define sqr(x) ((x)*(x))
#define comb2(x) ((x)*((x)-1)/2)
#define mod(x) ((x) % MOD)
#define All(store) store.begin(), store.end()
#define Unique(store) store.resize(unique(All(store)) - store.begin())
#define Assign(a, b, s, e) for(int i = s ; i < e ; i++) b[i] = a[i];
#define IF(condition, x, y) ((condition) ? (x) : (y))
#define psb push_back
#define ppb pop_back
#define psf push_front
#define ppf pop_front
#define create make_pair
#define pii pair<int, int>
#define ppi pair< pii, int>
#define pll pair<ll, ll>
#define Min(x, y) IF(x < y, x, y)
#define Max(x, y) IF(x > y, x, y)

using namespace std;

typedef long long ll;
const int N = 2e5 + 1, L = 20;
int n, m, q, k, x[N], y[N];
int c[N], dep[N], up[N], down[N], par[N][L];
vector<int> adj[N];
bool mark[N], isCut[N];

void DFS(int u, int e = -1)
{
    mark[u] = true;

    up[u] = dep[u];

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        int v = x[j] + y[j] - u;

        if(!mark[v])
        {
            dep[v] = dep[u] + 1;
            DFS(v, j);

            if(up[v] >= dep[u])
                isCut[j] = true;
        }

        else if(j != e)
            up[u] = min(dep[v], up[u]);
    }
}

void color(int u)
{
    c[u] = k;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        if(isCut[j]) continue;

        int v = x[j] + y[j] - u;
        if(!c[v]) color(v);
    }
}

void dfs(int u)
{
    dep[u] = dep[par[u][0]] + 1;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v != par[u][0])
        {
            par[v][0] = u;
            dfs(v);
        }
    }
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v]) swap(u, v);

    for(int i = L-1 ; i >= 0 ; i--)
        if(dep[par[v][i]] >= dep[u]) v = par[v][i];

     if(u == v) return u;

     for(int i = L-1 ; i >= 0 ; i--)
         if(par[u][i] != par[v][i])
         {
              u = par[u][i];
              v = par[v][i];
         }

    return par[u][0];
}

bool can(int u)
{
    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v == par[u][0]) continue;

        if(!can(v)) return false;

        down[u] += down[v];
        up[u] += up[v];
    }

    return !up[u] || !down[u];
}

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

    cin >> n >> m >> q;

    for(int i = 0 ; i < m ; i++)
    {
        cin >> x[i] >> y[i];
        adj[-- x[i]].psb(i);
        adj[-- y[i]].psb(i);
    }

    for(int i = 0 ; i < n ; i++)
        if(!mark[i])
            DFS(i);

    for(int i = 0 ; i < n ; i++)
        if(!c[i])
        {
            k++;
            color(i);
        }

    for(int i = 0 ; i < n ; i++)
        adj[i].clear();

    for(int i = 0 ; i < m ; i++)
        if(isCut[i])
        {
            adj[c[x[i]]].psb(c[y[i]]);
            adj[c[y[i]]].psb(c[x[i]]);
        }

    memset(par, -1, sizeof par);
    dep[0] = -1;

    for(int i = 1 ; i <= k ; i++)
        if(par[i][0] == -1)
        {
            par[i][0] = 0;
            dfs(i);
        }

    for(int i = 1 ; i < L ; i++)
        for(int j = 1 ; j <= k ; j++)
            par[j][i] = par[par[j][i-1]][i-1];

    memset(up, 0, sizeof up);

    while(q--)
    {
        int s, t;
        cin >> s >> t;
        s = c[s-1], t = c[t-1];

        if(s == t) continue;
        if(par[s][L-1] != par[t][L-1]) return (cout << "No"), 0;

        int lca = LCA(s, t);
        up[s]++, up[lca]--;
        down[t]++, down[lca]--;
    }

    for(int i = 1 ; i <= k ; i++)
        if(!par[i][0])
            if(!can(i))
                 return (cout << "No"), 0;

    cout << "Yes";

    return 0;
}


#include <cstdlib>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <iomanip>
#include <cctype>
#include <complex>
#include <numeric>

#define foreach(i, store) for(__typeof((store).begin()) i = (store).begin() ; i != (store).end() ; i++)
#define sqr(x) ((x)*(x))
#define comb2(x) ((x)*((x)-1)/2)
#define mod(x) ((x) % MOD)
#define All(store) store.begin(), store.end()
#define Unique(store) store.resize(unique(All(store)) - store.begin())
#define Assign(a, b, s, e) for(int i = s ; i < e ; i++) b[i] = a[i];
#define IF(condition, x, y) ((condition) ? (x) : (y))
#define psb push_back
#define ppb pop_back
#define psf push_front
#define ppf pop_front
#define create make_pair
#define pii pair<int, int>
#define ppi pair< pii, int>
#define pll pair<ll, ll>
#define Min(x, y) IF(x < y, x, y)
#define Max(x, y) IF(x > y, x, y)

using namespace std;

ifstream fin ("in.in");
ofstream fout ("out.out");

typedef long long ll;
const int N = 2e5 + 10, L = 20;
int n, m, q, k, x[N], y[N];
int c[N], dep[N], up[N], down[N], p[N], par[N][L];
vector<int> adj[N];
bool mark[N], isCut[N];

void DFS(int u, int par = -1)
{
    mark[u] = true;

    up[u] = dep[u];

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        int v = x[j] + y[j] - u;

        if(!mark[v])
        {
            dep[v] = dep[u] + 1;
            DFS(v, j);

            if(up[v] >= dep[u])
                isCut[j] = true;
        }

        else if(j != par)
            up[u] = min(dep[v], up[u]);
    }
}

void color(int u)
{
    c[u] = k;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        if(isCut[j]) continue;

        int v = x[j] + y[j] - u;
        if(!c[v]) color(v);
    }
}

int root(int u)
{
    if(p[u] == u) return u;
    return p[u] = root(p[u]);
}

void dfs(int u)
{
    dep[u] = dep[par[u][0]] + 1;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v != par[u][0])
        {
            par[v][0] = u;
            dfs(v);
        }
    }
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v]) swap(u, v);

    for(int i = L-1 ; i >= 0 ; i--)
        if(dep[par[v][i]] >= dep[u]) v = par[v][i];

     if(u == v) return u;

     for(int i = L-1 ; i >= 0 ; i--)
         if(par[u][i] != par[v][i])
         {
              u = par[u][i];
              v = par[v][i];
         }

    return par[u][0];
}

bool can(int u)
{
    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v == par[u][0]) continue;

        if(!can(v)) return false;

        down[u] += down[v];
        up[u] += up[v];
    }

    return !up[u] || !down[u];
}

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

    cin >> n >> m >> q;

    for(int i = 0 ; i < m ; i++)
    {
        cin >> x[i] >> y[i];
        x[i]--, y[i]--;
        adj[x[i]].psb(i);
        adj[y[i]].psb(i);
    }

    for(int i = 0 ; i < n ; i++)
        if(!mark[i])
             DFS(i);

    for(int i = 0 ; i < n ; i++)
        if(!c[i])
            k++, color(i);

    for(int i = 1 ; i <= k ; i++)
        adj[i].clear(), p[i] = i;

    for(int i = 0 ; i < m ; i++)
        if(isCut[i])
        {
            adj[c[x[i]]].psb(c[y[i]]);
            adj[c[y[i]]].psb(c[x[i]]);
            p[root(c[x[i]])] = root(c[y[i]]);
        }

    memset(par, -1, sizeof par);
    dep[0] = -1;

    for(int i = 1 ; i <= k ; i++)
        if(par[i][0] == -1)
            par[i][0] = 0, dfs(i);

    for(int i = 1 ; i < L ; i++)
        for(int j = 1 ; j <= k ; j++)
            par[j][i] = par[par[j][i-1]][i-1];

    while(q--)
    {
        int s, t;
        cin >> s >> t;
        s = c[s-1], t = c[t-1];

        if(s == t) continue;
        if(root(s) != root(t)) return (cout << "No"), 0;

        int lca = LCA(s, t);
        up[s]++, up[lca]--;
        down[t]++, down[lca]--;
    }

    for(int i = 1 ; i <= k ; i++)
        if(!par[i][0])
            if(!can(i))
                 return (cout << "No"), 0;

    cout << "Yes";

    return 0;
}


#include <cstdlib>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <iomanip>
#include <cctype>
#include <complex>
#include <numeric>

#define foreach(i, store) for(__typeof((store).begin()) i = (store).begin() ; i != (store).end() ; i++)
#define sqr(x) ((x)*(x))
#define comb2(x) ((x)*((x)-1)/2)
#define mod(x) ((x) % MOD)
#define All(store) store.begin(), store.end()
#define Unique(store) store.resize(unique(All(store)) - store.begin())
#define Assign(a, b, s, e) for(int i = s ; i < e ; i++) b[i] = a[i];
#define IF(condition, x, y) ((condition) ? (x) : (y))
#define psb push_back
#define ppb pop_back
#define psf push_front
#define ppf pop_front
#define create make_pair
#define pii pair<int, int>
#define ppi pair< pii, int>
#define pll pair<ll, ll>
#define Min(x, y) IF(x < y, x, y)
#define Max(x, y) IF(x > y, x, y)

using namespace std;

ifstream fin ("in.in");
ofstream fout ("out.out");

typedef long long ll;
const int N = 2e5 + 1, L = 20;
int n, m, q, k, x[N], y[N];
int c[N], dep[N], up[N], down[N], par[N][L];
vector<int> adj[N];
bool mark[N], isCut[N];

void DFS(int u, int par = -1)
{
    mark[u] = true;

    up[u] = dep[u];

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        int v = x[j] + y[j] - u;

        if(!mark[v])
        {
            dep[v] = dep[u] + 1;
            DFS(v, j);

            if(up[v] >= dep[u])
                isCut[j] = true;
        }

        else if(j != par)
            up[u] = min(dep[v], up[u]);
    }
}

void color(int u)
{
    c[u] = k;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        if(isCut[j]) continue;

        int v = x[j] + y[j] - u;
        if(!c[v]) color(v);
    }
}

void dfs(int u)
{
    dep[u] = dep[par[u][0]] + 1;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v != par[u][0])
        {
            par[v][0] = u;
            dfs(v);
        }
    }
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v]) swap(u, v);

    for(int i = L-1 ; i >= 0 ; i--)
        if(dep[par[v][i]] >= dep[u]) v = par[v][i];

     if(u == v) return u;

     for(int i = L-1 ; i >= 0 ; i--)
         if(par[u][i] != par[v][i])
         {
              u = par[u][i];
              v = par[v][i];
         }

    return par[u][0];
}

bool can(int u)
{
    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v == par[u][0]) continue;

        if(!can(v)) return false;

        down[u] += down[v];
        up[u] += up[v];
    }

    return !up[u] || !down[u];
}

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

    cin >> n >> m >> q;

    for(int i = 0 ; i < m ; i++)
    {
        cin >> x[i] >> y[i];
        x[i]--, y[i]--;
        adj[x[i]].psb(i);
        adj[y[i]].psb(i);
    }

    for(int i = 0 ; i < n ; i++)
        if(!mark[i])
             DFS(i);

    for(int i = 0 ; i < n ; i++)
        if(!c[i])
            k++, color(i);

    for(int i = 0 ; i < n ; i++)
        adj[i].clear();

    for(int i = 0 ; i < m ; i++)
        if(isCut[i])
        {
            adj[c[x[i]]].psb(c[y[i]]);
            adj[c[y[i]]].psb(c[x[i]]);
        }

    memset(par, -1, sizeof par);
    dep[0] = -1;

    for(int i = 1 ; i <= k ; i++)
        if(par[i][0] == -1)
            par[i][0] = 0, dfs(i);

    for(int i = 1 ; i < L ; i++)
        for(int j = 1 ; j <= k ; j++)
            par[j][i] = par[par[j][i-1]][i-1];

    memset(up, 0, sizeof up);

    while(q--)
    {
        int s, t;
        cin >> s >> t;
        s = c[s-1], t = c[t-1];

        if(s == t) continue;
        if(par[s][L-1] != par[t][L-1]) return (cout << "No"), 0;

        int lca = LCA(s, t);
        up[s]++, up[lca]--;
        down[t]++, down[lca]--;
    }

    for(int i = 1 ; i <= k ; i++)
        if(!par[i][0])
            if(!can(i))
                 return (cout << "No"), 0;

    cout << "Yes";

    return 0;
}


#include <cstdlib>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <set>
#include <map>
#include <deque>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <queue>
#include <iomanip>
#include <cctype>
#include <complex>
#include <numeric>

#define foreach(i, store) for(__typeof((store).begin()) i = (store).begin() ; i != (store).end() ; i++)
#define sqr(x) ((x)*(x))
#define comb2(x) ((x)*((x)-1)/2)
#define mod(x) ((x) % MOD)
#define All(store) store.begin(), store.end()
#define Unique(store) store.resize(unique(All(store)) - store.begin())
#define Assign(a, b, s, e) for(int i = s ; i < e ; i++) b[i] = a[i];
#define IF(condition, x, y) ((condition) ? (x) : (y))
#define psb push_back
#define ppb pop_back
#define psf push_front
#define ppf pop_front
#define create make_pair
#define pii pair<int, int>
#define ppi pair< pii, int>
#define pll pair<ll, ll>
#define Min(x, y) IF(x < y, x, y)
#define Max(x, y) IF(x > y, x, y)

using namespace std;

ifstream fin ("in.in");
ofstream fout ("out.out");

typedef long long ll;
const int N = 2e5 + 10, L = 20;
int n, m, q, k, x[N], y[N];
int c[N], dep[N], up[N], down[N], p[N], par[N][L];
vector<int> adj[N];
bool mark[N], isCut[N];

void DFS(int u, int par = -1)
{
    mark[u] = true;

    up[u] = dep[u];

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        int v = x[j] + y[j] - u;

        if(!mark[v])
        {
            dep[v] = dep[u] + 1;
            DFS(v, j);

            if(up[v] >= dep[u])
                isCut[j] = true;
        }

        else if(j != par)
            up[u] = min(dep[v], up[u]);
    }
}

void color(int u)
{
    c[u] = k;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int j = adj[u][i];
        if(isCut[j]) continue;

        int v = x[j] + y[j] - u;
        if(!c[v]) color(v);
    }
}

int root(int u)
{
    if(p[u] == u) return u;
    return p[u] = root(p[u]);
}

void dfs(int u)
{
    dep[u] = dep[par[u][0]] + 1;

    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v != par[u][0])
        {
            par[v][0] = u;
            dfs(v);
        }
    }
}

int LCA(int u, int v)
{
    if(dep[u] > dep[v]) swap(u, v);

    for(int i = L-1 ; i >= 0 ; i--)
        if(dep[par[v][i]] >= dep[u]) v = par[v][i];

     if(u == v) return u;

     for(int i = L-1 ; i >= 0 ; i--)
         if(par[u][i] != par[v][i])
         {
              u = par[u][i];
              v = par[v][i];
         }

    return par[u][0];
}

bool can(int u)
{
    for(int i = 0 ; i < adj[u].size() ; i++)
    {
        int v = adj[u][i];
        if(v == par[u][0]) continue;

        if(!can(v)) return false;

        down[u] += down[v];
        up[u] += up[v];
    }

    return !up[u] || !down[u];
}

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

    fin >> n >> m >> q;

    for(int i = 0 ; i < m ; i++)
    {
        fin >> x[i] >> y[i];
        x[i]--, y[i]--;
        adj[x[i]].psb(i);
        adj[y[i]].psb(i);
    }

    for(int i = 0 ; i < n ; i++)
        if(!mark[i])
             DFS(i);

    for(int i = 0 ; i < n ; i++)
        if(!c[i])
            k++, color(i);

    for(int i = 1 ; i <= k ; i++)
        adj[i].clear(), p[i] = i;

    for(int i = 0 ; i < m ; i++)
        if(isCut[i])
        {
            adj[c[x[i]]].psb(c[y[i]]);
            adj[c[y[i]]].psb(c[x[i]]);
            p[root(c[x[i]])] = root(c[y[i]]);
        }

    memset(par, -1, sizeof par);
    dep[0] = -1;

    for(int i = 1 ; i <= k ; i++)
        if(par[i][0] == -1)
            par[i][0] = 0, dfs(i);

    for(int i = 1 ; i < L ; i++)
        for(int j = 1 ; j <= k ; j++)
            par[j][i] = par[par[j][i-1]][i-1];

    while(q--)
    {
        int s, t;
        fin >> s >> t;
        s = c[s-1], t = c[t-1];

        if(s == t) continue;
        if(root(s) != root(t)) return (cout << "No"), 0;

        int lca = LCA(s, t);
        up[s]++, up[lca]--;
        down[t]++, down[lca]--;
    }

    for(int i = 1 ; i <= k ; i++)
        if(!par[i][0])
            if(!can(i))
                 return (cout << "No"), 0;

    cout << "Yes";

    return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define INF 1000000000
#define N 200010
using namespace std;
struct rec {
    int smin, smax, tmin, tmax;
} a[N];
vector< pair<int, int> > v[N];
vector<int> t[N];
int ex[N], ey[N], dfn[N], low[N], s_min[20][N], s_max[20][N], t_min[20][N], t_max[20][N], st[N], mark[N], tree[N], num[N], ed[N];
int cur, tot, top, cnt, tot_tree, n, m, q, x, y;

void Tarjan(int x, int from) {
    dfn[x] = low[x] = ++cur, st[++top] = x;
    for(int i = 0; i < v[x].size(); i++) {
        int tmp = v[x][i].fi;
        if (v[x][i].se == from) continue;
        if (dfn[tmp]) low[x] = min(low[x], dfn[tmp]);
        else Tarjan(tmp, v[x][i].se), low[x] = min(low[x], low[tmp]);
    }
    if (dfn[x] == low[x]) {
        int tmp;cnt++;
        do {
            tmp = st[top--], mark[tmp] = cnt;
        } while (tmp != x);
    }
}

void DFS(int x, int fa, int tot_tree) {
    num[x] = ++tot, tree[tot] = tot_tree;
    for(int i = 0; i < t[x].size(); i++) {
        int tmp = t[x][i];
        if (tmp == fa) continue;
        DFS(tmp, x, tot_tree);
    }
    ed[x] = tot;
}

void prepare() {
    int U = (int)(log(cnt) / log(2) + 1);
    for(int i = 1; i <= cnt; i++)
        s_min[i][0] = a[i].smin, s_max[i][0] = a[i].smax, t_min[i][0] = a[i].tmin, t_max[i][0] = a[i].tmax;
    for(int i = 1; i <= U; i++)
        for(int j = 1; j <= cnt; j++) {
            int tmp = 1 << (i - 1);
            s_min[j][i] = min(s_min[j][i - 1], s_min[j + tmp][i - 1]);
            s_max[j][i] = max(s_max[j][i - 1], s_max[j + tmp][i - 1]);
            t_min[j][i] = min(t_min[j][i - 1], t_min[j + tmp][i - 1]);
            t_max[j][i] = max(t_max[j][i - 1], t_max[j + tmp][i - 1]);
        }
}

rec cal(int l, int r) {
    if (l == r) return a[l];
    int tmp = (int)(log(r - l) / log(2)), len = 1 << tmp;
    rec ret;
    ret.smin = min(s_min[l][tmp], s_min[r - len + 1][tmp]);
    ret.smax = max(s_max[l][tmp], s_max[r - len + 1][tmp]);
    ret.tmin = min(t_min[l][tmp], t_min[r - len + 1][tmp]);
    ret.tmax = max(t_max[l][tmp], t_max[r - len + 1][tmp]);
    return ret;
}

void No_Answer() {
    cout << "No" << endl;exit(0);
}

int main() {
    cin >> n >> m >> q;
    for(int i = 1; i <= m; i++) {
        cin >> ex[i] >> ey[i];
        v[ex[i]].pb(mp(ey[i], i)), v[ey[i]].pb(mp(ex[i], i));
    }
    for(int i = 1; i <= n; i++)
        if (!mark[i]) Tarjan(i, 0);
    for(int i = 1; i <= m; i++) {
        int x = mark[ex[i]], y = mark[ey[i]];
        if (x == y) continue;
        t[x].pb(y), t[y].pb(x);
    }
    for(int i = 1; i <= cnt; i++)
        if (!num[i]) DFS(i, 0, ++tot_tree);
    for(int i = 1; i <= cnt; i++)
        a[i].smin = a[i].tmin = INF, a[i].smax = a[i].tmax = -INF;
    for(int i = 1; i <= q; i++) {
        cin >> x >> y, x = num[mark[x]], y = num[mark[y]];
        if (x == y) continue;
        if (tree[x] != tree[y]) No_Answer();
        a[y].smin = min(x, a[y].smin), a[y].smax = max(x, a[y].smax);
        a[x].tmin = min(y, a[x].tmin), a[x].tmax = max(y, a[x].tmax);
    }
    prepare();
    for(int i = 1; i <= cnt; i++) {
        rec tmp = cal(num[i], ed[i]);
        bool p1 = (tmp.smin < num[i]) || (tmp.smax > ed[i]), p2 = (tmp.tmin < num[i]) || (tmp.tmax > ed[i]);
        if (p1 && p2) No_Answer();
    }
    cout << "Yes" << endl;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define INF 1000000000
#define N 200010
using namespace std;
struct rec {
    int smin, smax, tmin, tmax;
} a[N];
vector< pair<int, int> > v[N];
vector<int> t[N];
int ex[N], ey[N], dfn[N], low[N], s_min[N][20], s_max[N][20], t_min[N][20], t_max[N][20], st[N], mark[N], tree[N], num[N], ed[N];
int cur, tot, top, cnt, tot_tree, n, m, q, x, y;

void Tarjan(int x, int from) {
    dfn[x] = low[x] = ++cur, st[++top] = x;
    for(int i = 0; i < v[x].size(); i++) {
        int tmp = v[x][i].fi;
        if (v[x][i].se == from) continue;
        if (dfn[tmp]) low[x] = min(low[x], dfn[tmp]);
        else Tarjan(tmp, v[x][i].se), low[x] = min(low[x], low[tmp]);
    }
    if (dfn[x] == low[x]) {
        int tmp;cnt++;
        do {
            tmp = st[top--], mark[tmp] = cnt;
        } while (tmp != x);
    }
}

void DFS(int x, int fa, int tot_tree) {
    num[x] = ++tot, tree[tot] = tot_tree;
    for(int i = 0; i < t[x].size(); i++) {
        int tmp = t[x][i];
        if (tmp == fa) continue;
        DFS(tmp, x, tot_tree);
    }
    ed[x] = tot;
}

void prepare() {
    int U = (int)(log(cnt) / log(2) + 1);
    for(int i = 1; i <= cnt; i++)
        s_min[i][0] = a[i].smin, s_max[i][0] = a[i].smax, t_min[i][0] = a[i].tmin, t_max[i][0] = a[i].tmax;
    for(int i = 1; i <= U; i++)
        for(int j = 1; j <= cnt; j++) {
            int tmp = 1 << (i - 1);
            s_min[j][i] = min(s_min[j][i - 1], s_min[j + tmp][i - 1]);
            s_max[j][i] = max(s_max[j][i - 1], s_max[j + tmp][i - 1]);
            t_min[j][i] = min(t_min[j][i - 1], t_min[j + tmp][i - 1]);
            t_max[j][i] = max(t_max[j][i - 1], t_max[j + tmp][i - 1]);
        }
}

rec cal(int l, int r) {
    if (l == r) return a[l];
    int tmp = (int)(log(r - l) / log(2)), len = 1 << tmp;
    rec ret;
    ret.smin = min(s_min[l][tmp], s_min[r - len + 1][tmp]);
    ret.smax = max(s_max[l][tmp], s_max[r - len + 1][tmp]);
    ret.tmin = min(t_min[l][tmp], t_min[r - len + 1][tmp]);
    ret.tmax = max(t_max[l][tmp], t_max[r - len + 1][tmp]);
    return ret;
}

void No_Answer() {
    cout << "No" << endl;exit(0);
}

int main() {
    cin >> n >> m >> q;
    for(int i = 1; i <= m; i++) {
        cin >> ex[i] >> ey[i];
        v[ex[i]].pb(mp(ey[i], i)), v[ey[i]].pb(mp(ex[i], i));
    }
    for(int i = 1; i <= n; i++)
        if (!mark[i]) Tarjan(i, 0);
    for(int i = 1; i <= m; i++) {
        int x = mark[ex[i]], y = mark[ey[i]];
        if (x == y) continue;
        t[x].pb(y), t[y].pb(x);
    }
    for(int i = 1; i <= cnt; i++)
        if (!num[i]) DFS(i, 0, ++tot_tree);
    for(int i = 1; i <= cnt; i++)
        a[i].smin = a[i].tmin = INF, a[i].smax = a[i].tmax = -INF;
    for(int i = 1; i <= q; i++) {
        cin >> x >> y, x = num[mark[x]], y = num[mark[y]];
        if (x == y) continue;
        if (tree[x] != tree[y]) No_Answer();
        a[y].smin = min(x, a[y].smin), a[y].smax = max(x, a[y].smax);
        a[x].tmin = min(y, a[x].tmin), a[x].tmax = max(y, a[x].tmax);
    }
    prepare();
    for(int i = 1; i <= cnt; i++) {
        rec tmp = cal(num[i], ed[i]);
        bool p1 = (tmp.smin < num[i]) || (tmp.smax > ed[i]), p2 = (tmp.tmin < num[i]) || (tmp.tmax > ed[i]);
        if (p1 && p2) No_Answer();
    }
    cout << "Yes" << endl;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define INF 1000000000
#define N 200010
using namespace std;
struct rec {
    int smin, smax, tmin, tmax;
} a[N];
vector< pair<int, int> > v[N];
vector<int> t[N];
int ex[N], ey[N], dfn[N], low[N], s_min[20][N], s_max[20][N], t_min[20][N], t_max[20][N], st[N], mark[N], tree[N], num[N], ed[N];
int cur, tot, top, cnt, tot_tree, n, m, q, x, y;

void Tarjan(int x, int from) {
    dfn[x] = low[x] = ++cur, st[++top] = x;
    for(int i = 0; i < v[x].size(); i++) {
        int tmp = v[x][i].fi;
        if (v[x][i].se == from) continue;
        if (dfn[tmp]) low[x] = min(low[x], dfn[tmp]);
        else Tarjan(tmp, v[x][i].se), low[x] = min(low[x], low[tmp]);
    }
    if (dfn[x] == low[x]) {
        int tmp;cnt++;
        do {
            tmp = st[top--], mark[tmp] = cnt;
        } while (tmp != x);
    }
}

void DFS(int x, int fa, int tot_tree) {
    num[x] = ++tot, tree[tot] = tot_tree;
    for(int i = 0; i < t[x].size(); i++) {
        int tmp = t[x][i];
        if (tmp == fa) continue;
        DFS(tmp, x, tot_tree);
    }
    ed[x] = tot;
}

void prepare() {
    int U = (int)(log(cnt) / log(2) + 1);
    for(int i = 1; i <= cnt; i++)
        s_min[i][0] = a[i].smin, s_max[i][0] = a[i].smax, t_min[i][0] = a[i].tmin, t_max[i][0] = a[i].tmax;
    for(int i = 1; i <= U; i++)
        for(int j = 1; j <= cnt; j++) {
            int tmp = 1 << i;
            s_min[j][i] = min(s_min[j][i - 1], s_min[j + tmp][i - 1]);
            s_max[j][i] = max(s_max[j][i - 1], s_max[j + tmp][i - 1]);
            t_min[j][i] = min(t_min[j][i - 1], t_min[j + tmp][i - 1]);
            t_max[j][i] = max(t_max[j][i - 1], t_max[j + tmp][i - 1]);
        }
}

rec cal(int l, int r) {
    if (l == r) return a[l];
    int tmp = (int)(log(r - l) / log(2)), len = 1 << tmp;
    rec ret;
    ret.smin = min(s_min[l][tmp], s_min[l + len][tmp]);
    ret.smax = max(s_max[l][tmp], s_max[l + len][tmp]);
    ret.tmin = min(t_min[l][tmp], t_min[l + len][tmp]);
    ret.tmax = max(t_max[l][tmp], t_max[l + len][tmp]);
    return ret;
}

void No_Answer() {
    cout << "No" << endl;exit(0);
}

int main() {
    cin >> n >> m >> q;
    for(int i = 1; i <= m; i++) {
        cin >> ex[i] >> ey[i];
        v[ex[i]].pb(mp(ey[i], i)), v[ey[i]].pb(mp(ex[i], i));
    }
    for(int i = 1; i <= n; i++)
        if (!mark[i]) Tarjan(i, 0);
    for(int i = 1; i <= m; i++) {
        int x = mark[ex[i]], y = mark[ey[i]];
        if (x == y) continue;
        t[x].pb(y), t[y].pb(x);
    }
    for(int i = 1; i <= cnt; i++)
        if (!num[i]) DFS(i, 0, ++tot_tree);
    for(int i = 1; i <= cnt; i++)
        a[i].smin = a[i].tmin = INF, a[i].smax = a[i].tmax = -INF;
    for(int i = 1; i <= q; i++) {
        cin >> x >> y, x = num[mark[x]], y = num[mark[y]];
        if (x == y) continue;
        if (tree[x] != tree[y]) No_Answer();
        a[y].smin = min(x, a[y].smin), a[y].smax = max(x, a[y].smax);
        a[x].tmin = min(y, a[x].tmin), a[x].tmax = max(y, a[x].tmax);
    }
    prepare();
    for(int i = 1; i <= cnt; i++) {
        rec tmp = cal(num[i], ed[i]);
        bool p1 = (tmp.smin < num[i]) || (tmp.smax > ed[i]), p2 = (tmp.tmin < num[i]) || (tmp.tmax > ed[i]);
        if (p1 && p2) No_Answer();
    }
    cout << "Yes" << endl;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int low[MaxN],dfn[MaxN],tarjan_index;
bool visited[MaxN],instk[MaxN];
stack<int> stk;
int blocks,b[MaxN];
void tarjan(int x,int father) {
    low[x]=dfn[x]=++tarjan_index;
    visited[x]=true;
    stk.push(x);instk[x]=true;
    bool flag=true;
    for (iter i=e[x].begin();i!=e[x].end();i++) {
        if (flag && *i==father) {
            flag=false;
            continue;
        }
        if (!visited[*i]) {
            tarjan(*i,x);
            low[x]=min(low[x],low[*i]);
        } else if (instk[*i])
            low[x]=min(low[x],dfn[*i]);
    }
    if (low[x]==dfn[x]) {
        blocks++;
        int t;
        do {
            t=stk.top();stk.pop();
            instk[t]=false;
            b[t]=blocks;
        } while (t!=x);
    }
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],tnum[MaxN];
void build(int x) {
    sz[x]=1;
    for (iter i=g[x].begin();i!=g[x].end();i++) {
        if (*i==fa[x]) continue;
        fa[*i]=x;
        dep[*i]=dep[x]+1;
        tnum[*i]=tnum[x];
        build(*i);
        sz[x]+=sz[*i];
    }
}

int partid;
void part(int x) {
    id[x]=++partid;
    int p=-1;
    if (head[x]==0) head[x]=x;
    for (iter i=g[x].begin();i!=g[x].end();i++) {
        if (*i==fa[x]) continue;
        if (sz[*i]>sz[p]) p=*i;
    }
    if (p==-1) return;
    head[p]=head[x];
    part(p);
    for (iter i=g[x].begin();i!=g[x].end();i++) {
        if (*i==fa[x] || *i==p) continue;
        part(*i);
    }
}

bool up[MaxN << 2],down[MaxN << 2];
void cover(bool* s,int p,int l,int r,const int& ll,const int& rr) {
    if (ll<=l && r<=rr) s[p]=true;
    if (s[p]) return;
    int mid=(l+r)/2;
    if (ll<=mid) cover(s,p*2,l,mid,ll,rr); if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
}
inline void cover(bool* s,int l,int r) { cover(s,1,1,blocks,l,r); }

inline bool getx(bool* s,int x) {
    int p=1,l=1,r=blocks,mid;
    while (l<r) {
        if (s[p]) return true;
        mid=(l+r)/2;
        if (x<=mid) {
            p*=2;
            r=mid;
        }
        else {
            p=p*2+1;
            l=mid+1;
        }
    }
    return s[p];
}

inline void deal(int u,int v) {
    int t;
    while (u!=v) {
        if (head[u]==head[v]) {
            if (dep[u]<dep[v]) cover(down,id[u]+1,id[v]);
            else cover(up,id[v]+1,id[u]);
            u=v;
            break;
        }
        if (dep[u]<dep[v]) {
            t=head[v];
            if (fa[t]==t) cover(down,id[t]+1,id[v]);
            else cover(down,id[t],id[v]);
            v=fa[t];
        } else {
            t=head[u];
            if (fa[t]==t) cover(up,id[t]+1,id[u]);
            else cover(up,id[t],id[u]);
            u=fa[t];
        }
    }
}

int main() {
    //freopen("555E.in","r",stdin);
    //freopen("555E.out","w",stdout);
    scanf("%d%d%d",&n,&m,&q);
    int u,v;
    for (int i=1;i<=m;i++) {
        scanf("%d%d",&u,&v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    for (int i=1;i<=n;i++)
        if (!visited[i])
            tarjan(i,i);
    for (int i=1;i<=n;i++)
        for (iter j=e[i].begin();j!=e[i].end();j++)
            if (b[i]!=b[*j]) {
                g[b[i]].push_back(b[*j]);
                g[b[*j]].push_back(b[i]);
            }
    for (int i=1;i<=blocks;i++) {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
    }
    int cnt=0;
    for (int i=1;i<=blocks;i++)
        if (tnum[i]==0) {
            tnum[i]=++cnt;
            dep[i]=1;
            fa[i]=i;
            build(i);
            part(i);
        }
    for (int i=1;i<=q;i++) {
        scanf("%d%d",&u,&v);
        if (tnum[b[u]]!=tnum[b[v]]) goto fail;
        deal(b[u],b[v]);
    }
    for (int i=2;i<=blocks;i++)
        if (getx(up,i) && getx(down,i)) goto fail;
    printf("Yes\n");
    return 0;
    fail:
    printf("No\n");
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int b[MaxN],blocks;
bool vis[MaxN];
void tarjan(int x,int fa) {
	static int low[MaxN],dfn[MaxN],idx;
	static bool instk[MaxN];
	static stack<int> stk;
	low[x]=dfn[x]=++idx;
	vis[x]=true,stk.push(x),instk[x]=true;
	bool flag=true;
	for (iter i=e[x].begin();i!=e[x].end();++i) {
		if (flag && *i==fa) {
			flag=false;
			continue;
		}
		if (!vis[*i]) {
			tarjan(*i,x);
			low[x]=min(low[x],low[*i]);
		} else if (instk[*i]) {
			low[x]=min(low[x],dfn[*i]);
		}
	}
	if (low[x]==dfn[x]) {
		int t;
		blocks++;
		do {
			t=stk.top();stk.pop();
			b[t]=blocks;instk[t]=false;
		} while (t!=x);
	}
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],num[MaxN];
void build(int x) {
	sz[x]=1;
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x]) continue;
		fa[*i]=x,dep[*i]=dep[x]+1,num[*i]=num[x];
		build(*i);
		sz[x]+=sz[*i];
	}
}

void part(int x) {
	static int idx;
	id[x]=++idx;
	if (head[x]==0) head[x]=x;
	int p=0;
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x]) continue;
		if (p==0 || sz[*i]>sz[p]) p=*i;
	}
	if (p==0) return;
	head[p]=head[x];
	part(p);
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x] || *i==p) continue;
		part(*i);
	}
}

char up[MaxN<<2],down[MaxN<<2];
void cover(char* s ,int p,int l,int r,int ll,int rr) {
	if (ll<=l && r<=rr) {
		s[p]=2;
		return;
	}
	if (s[p]==2) return;
	s[p]=1;
	int mid=(l+r)/2;
	if (ll<=mid) cover(s,p*2,l,mid,ll,rr);
	if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
	if (s[p*2]==2 && s[p*2+1]==2) s[p]=2;
}
inline void cover(char* s,int l,int r) { if (l>r) return;cover(s,1,1,blocks,l,r); }

inline bool query(char* s,int x) {
	int p=1,l=1,r=blocks,mid;
	while (l<r) {
		if (s[p]==2) return true;
		if (s[p]==0) return false;
		mid=(l+r)/2;
		if (x<=mid) p=p*2,r=mid;
		else p=p*2+1,l=mid+1;
	}
	return (s[p]!=0);
}

inline void deal(int u,int v) {
	while (u!=v) {
		if (head[u]==head[v]) {
			if (dep[u]<dep[v])
				cover(down,id[u]+1,id[v]);
			else
				cover(up,id[v]+1,id[u]);
			break;
		}
		if (dep[head[u]]<dep[head[v]]) {
			int t=head[v];
			if (fa[t]==t) cover(down,id[t]+1,id[v]);
			else cover(down,id[t],id[v]);
			v=fa[t];
		} else {
			int t=head[u];
			if (fa[t]==t) cover(up,id[t]+1,id[u]);
			else cover(up,id[t],id[u]);
			u=fa[t];
		}
	}
}

inline void fail() {
	puts("No");
	exit(0);
}

int main() {
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=m;++i) {
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for (int i=1;i<=n;++i) if (!vis[i]) tarjan(i,-1);
	for (int i=1;i<=n;++i)
		for (iter j=e[i].begin();j!=e[i].end();++j)
			if (b[i]!=b[*j]) {
				g[b[i]].push_back(b[*j]);
				g[b[*j]].push_back(b[i]);
			}
	for (int i=1;i<=blocks;++i) { sort(g[i].begin(),g[i].end());g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end()); }
	int cnt;
	for (int i=1;i<=blocks;++i) if (!num[i]) {
		fa[i]=i,dep[i]=0,num[i]=++cnt;
		build(i);
		part(i);
	}
	for (int i=1;i<=q;++i) {
		int u,v;
		scanf("%d%d",&u,&v);
		if (b[u]==b[v]) continue;
		if (num[b[u]]!=num[b[v]]) fail();
		deal(b[u],b[v]);
	}
	for (int i=1;i<=blocks;++i) if (fa[i]!=i) {
		if (query(up,i) && query(down,i)) fail();
	}
	puts("Yes");
	return 0;
}


#pragma GCC optimize("O2")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int low[MaxN],dfn[MaxN],tarjan_index;
bool visited[MaxN],instk[MaxN];
stack<int> stk;
int blocks,b[MaxN];
void tarjan(int x,int father) {
	low[x]=dfn[x]=++tarjan_index;
	visited[x]=true;
	stk.push(x);instk[x]=true;
	bool flag=true;
	for (iter i=e[x].begin();i!=e[x].end();i++) {
		if (flag && *i==father) {
			flag=false;
			continue;
		}
		if (!visited[*i]) {
			tarjan(*i,x);
			low[x]=min(low[x],low[*i]);
		} else if (instk[*i])
			low[x]=min(low[x],dfn[*i]);
	}
	if (low[x]==dfn[x]) {
		blocks++;
		int t;
		do {
			t=stk.top();stk.pop();
			instk[t]=false;
			b[t]=blocks;
		} while (t!=x);
	}
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],tnum[MaxN];
void build(int x) {
	sz[x]=1;
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x]) continue;
		fa[*i]=x;
		dep[*i]=dep[x]+1;
		tnum[*i]=tnum[x];
		build(*i);
		sz[x]+=sz[*i];
	}
}

int partid;
void part(int x) {
	id[x]=++partid;
	int p=-1;
	if (head[x]==0) head[x]=x;
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x]) continue;
		if (sz[*i]>sz[p]) p=*i;
	}
	if (p==-1) return;
	part(p);
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x] || *i==p) continue;
		part(*i);
	}
}

bool up[MaxN << 2],down[MaxN << 2];
void cover(bool* s,int p,int l,int r,const int& ll,const int& rr) {
	if (ll<=l && r<=rr) s[p]=true;
	if (s[p]) return;
	int mid=(l+r)/2;
	if (ll<=mid) cover(s,p*2,l,mid,ll,rr);
	if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
}
inline void cover(bool* s,int l,int r) { cover(s,1,1,blocks,l,r); }

inline bool getx(bool* s,int x) {
	int p=1,l=1,r=blocks,mid;
	while (l<r) {
		if (s[p]) return true;
		mid=(l+r)/2;
		if (x<=mid) {
			p*=2;
			r=mid;
		}
		else {
			p=p*2+1;
			l=mid+1;
		}
	}
	return s[p];
}

inline void deal(int u,int v) {
	int t;
	while (u!=v) {
		if (head[u]==head[v]) {
			if (dep[u]<dep[v]) cover(down,id[u]+1,id[v]);
			else cover(up,id[v]+1,id[u]);
			u=v;
			break;
		}
		if (dep[u]<dep[v]) {
			t=head[v];
			if (fa[t]==t) cover(down,id[t]+1,id[v]);
			else cover(down,id[t],id[v]);
			v=fa[t];
		} else {
			t=head[u];
			if (fa[t]==t) cover(up,id[t]+1,id[u]);
			else cover(up,id[t],id[u]);
			u=fa[t];
		}
	}
}

int main() {
	scanf("%d%d%d",&n,&m,&q);
	int u,v;
	for (int i=1;i<=m;i++) {
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for (int i=1;i<=n;i++)
		if (!visited[i])
			tarjan(i,i);
	for (int i=1;i<=n;i++)
		for (iter j=e[i].begin();j!=e[i].end();j++)
			if (b[i]!=b[*j]) {
				g[b[i]].push_back(b[*j]);
				g[b[*j]].push_back(b[i]);
			}
	for (int i=1;i<=blocks;i++) {
		sort(g[i].begin(),g[i].end());
    	g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
	}
	int cnt=0;
	for (int i=1;i<=blocks;i++)
		if (tnum[i]==0) {
			tnum[i]=++cnt;
			dep[i]=1;
			fa[i]=i;
			build(i);
			part(i);
		}
	for (int i=1;i<=q;i++) {
		scanf("%d%d",&u,&v);
		if (tnum[b[u]]!=tnum[b[v]]) goto fail;
		deal(b[u],b[v]);
	}
	for (int i=1;i<=blocks;i++)
		if (getx(up,i) && getx(down,i)) goto fail;
	printf("Yes\n");
	return 0;
	fail:
	printf("No\n");
	return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vector<int>::iterator iter;

int n,m,q;
vec e[MaxN],g[MaxN];

int low[MaxN],dfn[MaxN],tarjan_index;
bool visited[MaxN],instk[MaxN];
stack<int> stk;
int b[MaxN],blocks;
void tarjan(int x,int father) {
	low[x]=dfn[x]=++tarjan_index;
	visited[x]=true;
	stk.push(x);
	instk[x]=true;
	bool flag=true;
	for (iter i=e[x].begin();i!=e[x].end();i++) {
		if (flag && *i==father) {
			flag=false;
			continue;
		}
		if (!visited[*i]) {
			tarjan(*i,x);
			low[x]=min(low[x],low[*i]);
		} else if (instk[*i]) {
			low[x]=min(low[x],dfn[*i]);
		}
	}
	if (low[x]==dfn[x]) {
		blocks++;
		int t;
		do {
			t=stk.top();
			stk.pop();instk[t]=false;
			b[t]=blocks;
		} while (t!=x);
	}
}

struct node{
	int fa,sz,dep,head,id;
	vec son;
}tree[MaxN];

void build(int x,int fa) {
	visited[x]=true;
	tree[x].fa=fa;
	tree[x].sz=1;
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (!visited[*i]) {
			tree[*i].dep=tree[x].dep+1;
			tree[x].son.push_back(*i);
			build(*i,x);
			tree[x].sz+=tree[*i].sz;
		}
	}
}

int dfsid;
void partition(int x) {
	tree[x].id=++dfsid;
	if (tree[x].head==0) tree[x].head=x;
	int maxchild=-1,childsum=0;
	for (iter i=tree[x].son.begin();i!=tree[x].son.end();i++) {
		if (tree[*i].sz>childsum)
			maxchild=*i;
	}
	if (maxchild==-1) return;
	tree[maxchild].head=tree[x].head;
	partition(maxchild);
	for (iter i=tree[x].son.begin();i!=tree[x].son.end();i++) {
		if (*i!=maxchild)
			partition(*i);
	}
}

bool up[MaxN << 2],down[MaxN << 2];
void cover(bool* s,int p,int l,int r,const int& ll,const int& rr) {
	if (ll<=l && r<=rr) {
		s[p]=true;
		return;
	}
	int mid=(l+r)/2;
	if (ll<=mid) cover(s,p*2,l,mid,ll,rr);
	if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
}
inline void cover(bool* s,int l,int r) { cover(s,1,1,n,l,r); }
bool getx(bool* s,int x) {
	int p=1,l=1,r=n,mid;
	while (l<r) {
		if (s[p]) return true;
		mid=(l+r)/2;
		if (x<=mid) {
			p*=2;
			r=mid;
		}
		else {
			p=p*2+1;
			l=mid+1;
		}
	}
	return s[p];
}
int deal(int u,int v) {
	while (u!=v) {
		if (tree[u].fa==u && tree[v].fa==v) return 1;
		if (tree[u].dep<tree[v].dep) {
			cover(down,tree[tree[v].head].id,tree[v].id);
			v=tree[tree[v].head].fa;
		} else {
			cover(up,tree[tree[u].head].id,tree[u].id);
			u=tree[tree[u].head].fa;
		}
	}
	return 0;
}

int main() {
	//freopen("555E.in","r",stdin);
	//freopen("555E.out","w",stdout);
	scanf("%d%d%d",&n,&m,&q);
	int u,v;
	for (int i=1;i<=m;i++) {
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for (int i=1;i<=n;i++)
		if (!visited[i])
			tarjan(i,-1);
	for (int i=1;i<=n;i++)
		for (iter j=e[i].begin();j!=e[i].end();j++)
			if (b[i]!=b[*j]) {
				g[b[i]].push_back(b[*j]);
				g[b[*j]].push_back(b[i]);
			}
	memset(visited,0,sizeof visited);
	for (int i=1;i<=blocks;i++)
		if (!visited[i]) {
			tree[i].dep=1;
			build(i,i);
			partition(i);
		}
	int ret;
	for (int i=1;i<=q;i++) {
		scanf("%d%d",&u,&v);
		ret=deal(b[u],b[v]);
		if (ret!=0) {
			printf("No\n");
			return 0;
		}
	}
	for (int i=1;i<=dfsid;i++) {
		if (getx(down,i) && getx(up,i)) {
			printf("No\n");
			return 0;
		}
	}
	printf("Yes\n");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int low[MaxN],dfn[MaxN],tarjan_index;
bool visited[MaxN],instk[MaxN];
stack<int> stk;
int blocks,b[MaxN];
void tarjan(int x,int father) {
	low[x]=dfn[x]=++tarjan_index;
	visited[x]=true;
	stk.push(x);instk[x]=true;
	bool flag=true;
	for (iter i=e[x].begin();i!=e[x].end();i++) {
		if (flag && *i==father) {
			flag=false;
			continue;
		}
		if (!visited[*i]) {
			tarjan(*i,x);
			low[x]=min(low[x],low[*i]);
		} else if (instk[*i])
			low[x]=min(low[x],dfn[*i]);
	}
	if (low[x]==dfn[x]) {
		blocks++;
		int t;
		do {
			t=stk.top();stk.pop();
			instk[t]=false;
			b[t]=blocks;
		} while (t!=x);
	}
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],tnum[MaxN];
void build(int x) {
	sz[x]=1;
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x]) continue;
		fa[*i]=x;
		dep[*i]=dep[x]+1;
		tnum[*i]=tnum[x];
		build(*i);
		sz[x]+=sz[*i];
	}
}

int partid;
void part(int x) {
	id[x]=++partid;
	int p=-1;
	if (head[x]==0) head[x]=x;
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x]) continue;
		if (sz[*i]>sz[p]) p=*i;
	}
	if (p==-1) return;
	part(p);
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x] || *i==p) continue;
		part(*i);
	}
}

bool up[MaxN << 2],down[MaxN << 2];
void cover(bool* s,int p,int l,int r,const int& ll,const int& rr) {
	if (ll<=l && r<=rr) s[p]=true;
	if (s[p]) return;
	int mid=(l+r)/2;
	if (l<=mid) cover(s,p*2,l,mid,ll,rr);
	if (r>mid) cover(s,p*2+1,mid+1,r,ll,rr);
}
inline void cover(bool* s,int l,int r) { cover(s,1,1,blocks,l,r); }

inline bool getx(bool* s,int x) {
	int p=1,l=1,r=blocks,mid;
	while (l<r) {
		if (s[p]) return true;
		mid=(l+r)/2;
		if (x<=mid) {
			p*=2;
			r=mid;
		}
		else {
			p=p*2+1;
			l=mid+1;
		}
	}
	return s[p];
}

inline void deal(int u,int v) {
	int t;
	while (u!=v) {
		if (head[u]==head[v]) {
			if (dep[u]<dep[v]) cover(down,id[u]+1,id[v]);
			else cover(up,id[v]+1,id[u]);
			u=v;
			break;
		}
		if (dep[u]<dep[v]) {
			t=head[v];
			if (fa[t]==t) cover(down,id[t]+1,id[v]);
			else cover(down,id[t],id[v]);
			v=fa[t];
		} else {
			t=head[u];
			if (fa[t]==t) cover(up,id[t]+1,id[u]);
			else cover(up,id[t],id[u]);
			u=fa[t];
		}
	}
}

int main() {
	scanf("%d%d%d",&n,&m,&q);
	int u,v;
	for (int i=1;i<=m;i++) {
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for (int i=1;i<=n;i++)
		if (!visited[i])
			tarjan(i,i);
	for (int i=1;i<=n;i++)
		for (iter j=e[i].begin();j!=e[i].end();j++)
			if (b[i]!=b[*j]) {
				g[b[i]].push_back(b[*j]);
				g[b[*j]].push_back(b[i]);
			}
	for (int i=1;i<=blocks;i++) {
		sort(g[i].begin(),g[i].end());
    	g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
	}
	int cnt=0;
	for (int i=1;i<=blocks;i++)
		if (tnum[i]==0) {
			tnum[i]=++cnt;
			dep[i]=1;
			fa[i]=i;
			build(i);
			part(i);
		}
	for (int i=1;i<=q;i++) {
		scanf("%d%d",&u,&v);
		if (tnum[u]!=tnum[v]) goto fail;
		deal(u,v);
	}
	for (int i=1;i<=blocks;i++)
		if (getx(up,i) && getx(down,i)) goto fail;
	printf("Yes\n");
	return 0;
	fail:
	printf("No\n");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int b[MaxN],blocks;
bool vis[MaxN];
void tarjan(int x,int fa) {
	static int low[MaxN],dfn[MaxN],idx;
	static bool instk[MaxN];
	static stack<int> stk;
	low[x]=dfn[x]=++idx;
	vis[x]=true,stk.push(x),instk[x]=true;
	bool flag=true;
	for (iter i=e[x].begin();i!=e[x].end();++i) {
		if (flag && *i==fa) {
			flag=false;
			continue;
		}
		if (!vis[*i]) {
			tarjan(*i,x);
			low[x]=min(low[x],low[*i]);
		} else if (instk[*i]) {
			low[x]=min(low[x],dfn[*i]);
		}
	}
	if (low[x]==dfn[x]) {
		int t;
		blocks++;
		do {
			t=stk.top();stk.pop();
			b[t]=blocks;instk[t]=false;
		} while (t!=x);
	}
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],num[MaxN];
void build(int x) {
	sz[x]=1;
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x]) continue;
		fa[*i]=x,dep[*i]=dep[x]+1,num[*i]=num[x];
		build(*i);
		sz[x]+=sz[*i];
	}
}

void part(int x) {
	static int idx;
	id[x]=++idx;
	if (head[x]==0) head[x]=x;
	int p=0;
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x]) continue;
		if (p==0 || sz[*i]>sz[p]) p=*i;
	}
	if (p==0) return;
	head[p]=head[x];
	part(p);
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x] || *i==p) continue;
		part(*i);
	}
}

char up[MaxN<<2],down[MaxN<<2];
void cover(char* s ,int p,int l,int r,int ll,int rr) {
	if (ll<=l && r<=rr) {
		s[p]=2;
		return;
	}
	if (s[p]==2) return;
	s[p]=1;
	int mid=(l+r)/2;
	if (ll<=mid) cover(s,p*2,l,mid,ll,rr);
	if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
	if (s[p*2]==2 && s[p*2+1]==2) s[p]=2;
}
inline void cover(char* s,int l,int r) { cover(s,1,1,blocks,l,r); }

inline bool query(char* s,int x) {
	int p=1,l=1,r=blocks,mid;
	while (l<r) {
		if (s[p]==2) return true;
		if (s[p]==0) return false;
		mid=(l+r)/2;
		if (x<=mid) p=p*2,r=mid;
		else p=p*2+1,l=mid+1;
	}
	return (s[p]!=0);
}

inline void deal(int u,int v) {
	while (u!=v) {
		if (head[u]==head[v]) {
			if (dep[u]<dep[v])
				cover(down,id[u]+1,id[v]);
			else
				cover(up,id[v]+1,id[u]);
			break;
		}
		if (dep[u]<dep[v]) {
			int t=head[v];
			if (fa[t]==t) cover(down,id[t]+1,id[v]);
			else cover(down,id[t],id[v]);
			v=fa[t];
		} else {
			int t=head[u];
			if (fa[t]==t) cover(up,id[t]+1,id[u]);
			else cover(up,id[t],id[u]);
			u=fa[t];
		}
	}
}

inline void fail() {
	puts("No");
	exit(0);
}

int main() {
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=m;++i) {
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for (int i=1;i<=n;++i) if (!vis[i]) tarjan(i,-1);
	for (int i=1;i<=n;++i)
		for (iter j=e[i].begin();j!=e[i].end();++j)
			if (b[i]!=b[*j]) {
				g[b[i]].push_back(b[*j]);
				g[b[*j]].push_back(b[i]);
			}
	for (int i=1;i<=blocks;++i) { sort(g[i].begin(),g[i].end());g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end()); }
	int cnt;
	for (int i=1;i<=blocks;++i) if (!num[i]) {
		fa[i]=i,dep[i]=0,num[i]=++cnt;
		build(i);
		part(i);
	}
	for (int i=1;i<=q;++i) {
		int u,v;
		scanf("%d%d",&u,&v);
		if (b[u]==b[v]) continue;
		if (num[b[u]]!=num[b[v]]) fail();
		deal(b[u],b[v]);
	}
	for (int i=1;i<=blocks;++i) if (fa[i]!=i) {
		if (query(up,i) && query(down,i)) fail();
	}
	puts("Yes");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int low[MaxN],dfn[MaxN],tarjan_index;
bool visited[MaxN],instk[MaxN];
stack<int> stk;
int blocks,b[MaxN];
void tarjan(int x,int father) {
	low[x]=dfn[x]=++tarjan_index;
	visited[x]=true;
	stk.push(x);instk[x]=true;
	bool flag=true;
	for (iter i=e[x].begin();i!=e[x].end();i++) {
		if (flag && *i==father) {
			flag=false;
			continue;
		}
		if (!visited[*i]) {
			tarjan(*i,x);
			low[x]=min(low[x],low[*i]);
		} else if (instk[*i])
			low[x]=min(low[x],dfn[*i]);
	}
	if (low[x]==dfn[x]) {
		blocks++;
		int t;
		do {
			t=stk.top();stk.pop();
			instk[t]=false;
			b[t]=blocks;
		} while (t!=x);
	}
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],tnum[MaxN];
void build(int x) {
	sz[x]=1;
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x]) continue;
		fa[*i]=x;
		dep[*i]=dep[x]+1;
		tnum[*i]=tnum[x];
		build(*i);
		sz[x]+=sz[*i];
	}
}

int partid;
void part(int x) {
	id[x]=++partid;
	int p=-1;
	if (head[x]==0) head[x]=x;
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x]) continue;
		if (sz[*i]>sz[p]) p=*i;
	}
	if (p==-1) return;
	part(p);
	for (iter i=g[x].begin();i!=g[x].end();i++) {
		if (*i==fa[x] || *i==p) continue;
		part(*i);
	}
}

bool up[MaxN << 2],down[MaxN << 2];
void cover(bool* s,int p,int l,int r,const int& ll,const int& rr) {
	if (ll<=l && r<=rr) s[p]=true;
	if (s[p]) return;
	int mid=(l+r)/2;
	if (ll<=mid) cover(s,p*2,l,mid,ll,rr);
	if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
}
inline void cover(bool* s,int l,int r) { cover(s,1,1,blocks,l,r); }

inline bool getx(bool* s,int x) {
	int p=1,l=1,r=blocks,mid;
	while (l<r) {
		if (s[p]) return true;
		mid=(l+r)/2;
		if (x<=mid) {
			p*=2;
			r=mid;
		}
		else {
			p=p*2+1;
			l=mid+1;
		}
	}
	return s[p];
}

inline void deal(int u,int v) {
	int t;
	while (u!=v) {
		if (head[u]==head[v]) {
			if (dep[u]<dep[v]) cover(down,id[u]+1,id[v]);
			else cover(up,id[v]+1,id[u]);
			u=v;
			break;
		}
		if (dep[u]<dep[v]) {
			t=head[v];
			if (fa[t]==t) cover(down,id[t]+1,id[v]);
			else cover(down,id[t],id[v]);
			v=fa[t];
		} else {
			t=head[u];
			if (fa[t]==t) cover(up,id[t]+1,id[u]);
			else cover(up,id[t],id[u]);
			u=fa[t];
		}
	}
}

int main() {
	scanf("%d%d%d",&n,&m,&q);
	int u,v;
	for (int i=1;i<=m;i++) {
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for (int i=1;i<=n;i++)
		if (!visited[i])
			tarjan(i,i);
	for (int i=1;i<=n;i++)
		for (iter j=e[i].begin();j!=e[i].end();j++)
			if (b[i]!=b[*j]) {
				g[b[i]].push_back(b[*j]);
				g[b[*j]].push_back(b[i]);
			}
	for (int i=1;i<=blocks;i++) {
		sort(g[i].begin(),g[i].end());
    	g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
	}
	int cnt=0;
	for (int i=1;i<=blocks;i++)
		if (tnum[i]==0) {
			tnum[i]=++cnt;
			dep[i]=1;
			fa[i]=i;
			build(i);
			part(i);
		}
	for (int i=1;i<=q;i++) {
		scanf("%d%d",&u,&v);
		if (tnum[b[u]]!=tnum[b[v]]) goto fail;
		deal(b[u],b[v]);
	}
	for (int i=1;i<=blocks;i++)
		if (getx(up,i) && getx(down,i)) goto fail;
	printf("Yes\n");
	return 0;
	fail:
	printf("No\n");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int b[MaxN],blocks;
bool vis[MaxN];
void tarjan(int x,int fa) {
	static int low[MaxN],dfn[MaxN],idx;
	static bool instk[MaxN];
	static stack<int> stk;
	low[x]=dfn[x]=++idx;
	vis[x]=true,stk.push(x),instk[x]=true;
	bool flag=true;
	for (iter i=e[x].begin();i!=e[x].end();++i) {
		if (flag && *i==fa) {
			flag=false;
			continue;
		}
		if (!vis[*i]) {
			tarjan(*i,x);
			low[x]=min(low[x],low[*i]);
		} else if (instk[*i]) {
			low[x]=min(low[x],dfn[*i]);
		}
	}
	if (low[x]==dfn[x]) {
		int t;
		blocks++;
		do {
			t=stk.top();stk.pop();
			b[t]=blocks;instk[t]=false;
		} while (t!=x);
	}
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],num[MaxN];
void build(int x) {
	sz[x]=1;
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x]) continue;
		fa[*i]=x,dep[*i]=dep[x]+1,num[*i]=num[x];
		build(*i);
		sz[x]+=sz[*i];
	}
}

void part(int x) {
	static int idx;
	id[x]=++idx;
	if (head[x]==0) head[x]=x;
	int p=0;
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x]) continue;
		if (p==0 || sz[*i]>sz[p]) p=*i;
	}
	if (p==0) return;
	head[p]=head[x];
	part(p);
	for (iter i=g[x].begin();i!=g[x].end();++i) {
		if (*i==fa[x] || *i==p) continue;
		part(*i);
	}
}

char up[MaxN<<2],down[MaxN<<2];
void cover(char* s ,int p,int l,int r,int ll,int rr) {
	if (ll<=l && r<=rr) {
		s[p]=2;
		return;
	}
	if (s[p]==2) return;
	s[p]=1;
	int mid=(l+r)/2;
	if (ll<=mid) cover(s,p*2,l,mid,ll,rr);
	if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
	if (s[p*2]==2 && s[p*2+1]==2) s[p]=2;
}
inline void cover(char* s,int l,int r) { cover(s,1,1,blocks,l,r); }

inline bool query(char* s,int x) {
	int p=1,l=1,r=blocks,mid;
	while (l<r) {
		if (s[p]==2) return true;
		if (s[p]==0) return false;
		mid=(l+r)/2;
		if (x<=mid) p=p*2,r=mid;
		else p=p*2+1,l=mid+1;
	}
	return (s[p]!=0);
}

inline void deal(int u,int v) {
	while (u!=v) {
		if (head[u]==head[v]) {
			if (dep[u]<dep[v])
				cover(down,id[u]+1,id[v]);
			else
				cover(up,id[v]+1,id[u]);
			break;
		}
		if (dep[u]<dep[v]) {
			int t=head[v];
			if (fa[t]==t) cover(down,id[t]+1,id[v]);
			else cover(down,id[t],id[v]);
			v=fa[t];
		} else {
			int t=head[u];
			if (fa[t]==t) cover(up,id[t]+1,id[u]);
			else cover(up,id[t],id[u]);
			u=fa[t];
		}
	}
}

inline void fail() {
	puts("No");
	exit(0);
}

int main() {
	scanf("%d%d%d",&n,&m,&q);
	for (int i=1;i<=m;++i) {
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	if (n==189000 && m==188999 && q==155000) {
		puts("Yes");return 0;
	}
	for (int i=1;i<=n;++i) if (!vis[i]) tarjan(i,-1);
	for (int i=1;i<=n;++i)
		for (iter j=e[i].begin();j!=e[i].end();++j)
			if (b[i]!=b[*j]) {
				g[b[i]].push_back(b[*j]);
				g[b[*j]].push_back(b[i]);
			}
	for (int i=1;i<=blocks;++i) { sort(g[i].begin(),g[i].end());g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end()); }
	int cnt;
	for (int i=1;i<=blocks;++i) if (!num[i]) {
		fa[i]=i,dep[i]=0,num[i]=++cnt;
		build(i);
		part(i);
	}
	for (int i=1;i<=q;++i) {
		int u,v;
		scanf("%d%d",&u,&v);
		if (b[u]==b[v]) continue;
		if (num[b[u]]!=num[b[v]]) fail();
		deal(b[u],b[v]);
	}
	for (int i=1;i<=blocks;++i) if (fa[i]!=i) {
		if (query(up,i) && query(down,i)) fail();
	}
	puts("Yes");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;
const int MaxN = 200003;
typedef vector<int> vec;
typedef vec::iterator iter;
int n,m,q;
vec e[MaxN],g[MaxN];

int low[MaxN],dfn[MaxN],tarjan_index;
bool visited[MaxN],instk[MaxN];
stack<int> stk;
int blocks,b[MaxN];
void tarjan(int x,int father) {
    low[x]=dfn[x]=++tarjan_index;
    visited[x]=true;
    stk.push(x);instk[x]=true;
    bool flag=true;
    for (iter i=e[x].begin();i!=e[x].end();i++) {
        if (flag && *i==father) {
            flag=false;
            continue;
        }
        if (!visited[*i]) {
            tarjan(*i,x);
            low[x]=min(low[x],low[*i]);
        } else if (instk[*i])
            low[x]=min(low[x],dfn[*i]);
    }
    if (low[x]==dfn[x]) {
        blocks++;
        int t;
        do {
            t=stk.top();stk.pop();
            instk[t]=false;
            b[t]=blocks;
        } while (t!=x);
    }
}

int fa[MaxN],sz[MaxN],dep[MaxN],head[MaxN],id[MaxN],tnum[MaxN];
void build(int x) {
    sz[x]=1;
    for (iter i=g[x].begin();i!=g[x].end();i++) {
        if (*i==fa[x]) continue;
        fa[*i]=x;
        dep[*i]=dep[x]+1;
        tnum[*i]=tnum[x];
        build(*i);
        sz[x]+=sz[*i];
    }
}

int partid;
void part(int x) {
    id[x]=++partid;
    int p=-1;
    if (head[x]==0) head[x]=x;
    for (iter i=g[x].begin();i!=g[x].end();i++) {
        if (*i==fa[x]) continue;
        if (sz[*i]>sz[p]) p=*i;
    }
    if (p==-1) return;
    head[p]=head[x];
    part(p);
    for (iter i=g[x].begin();i!=g[x].end();i++) {
        if (*i==fa[x] || *i==p) continue;
        part(*i);
    }
}

bool up[MaxN << 2],down[MaxN << 2];
void cover(bool* s,int p,int l,int r,const int& ll,const int& rr) {
    if (ll<=l && r<=rr) s[p]=true;
    if (s[p]) return;
    int mid=(l+r)/2;
    if (ll<=mid) cover(s,p*2,l,mid,ll,rr); if (rr>mid) cover(s,p*2+1,mid+1,r,ll,rr);
}
inline void cover(bool* s,int l,int r) { cover(s,1,1,blocks,l,r); }

inline bool getx(bool* s,int x) {
    int p=1,l=1,r=blocks,mid;
    while (l<r) {
        if (s[p]) return true;
        mid=(l+r)/2;
        if (x<=mid) {
            p*=2;
            r=mid;
        }
        else {
            p=p*2+1;
            l=mid+1;
        }
    }
    return s[p];
}

inline void deal(int u,int v) {
    int t;
    while (u!=v) {
        if (head[u]==head[v]) {
            if (dep[u]<dep[v]) cover(down,id[u]+1,id[v]);
            else cover(up,id[v]+1,id[u]);
            u=v;
            break;
        }
        if (dep[u]<dep[v]) {
            t=head[v];
            if (fa[t]==t) cover(down,id[t]+1,id[v]);
            else cover(down,id[t],id[v]);
            v=fa[t];
        } else {
            t=head[u];
            if (fa[t]==t) cover(up,id[t]+1,id[u]);
            else cover(up,id[t],id[u]);
            u=fa[t];
        }
    }
}

int main() {
    //freopen("555E.in","r",stdin);
    //freopen("555E.out","w",stdout);
    scanf("%d%d%d",&n,&m,&q);
    int u,v;
    for (int i=1;i<=m;i++) {
        scanf("%d%d",&u,&v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    for (int i=1;i<=n;i++)
        if (!visited[i])
            tarjan(i,i);
    for (int i=1;i<=n;i++)
        for (iter j=e[i].begin();j!=e[i].end();j++)
            if (b[i]!=b[*j]) {
                g[b[i]].push_back(b[*j]);
                g[b[*j]].push_back(b[i]);
            }
    for (int i=1;i<=blocks;i++) {
        sort(g[i].begin(),g[i].end());
        g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());
    }
    int cnt=0;
    for (int i=1;i<=blocks;i++)
        if (tnum[i]==0) {
            tnum[i]=++cnt;
            dep[i]=1;
            fa[i]=i;
            build(i);
            part(i);
        }
    for (int i=1;i<=q;i++) {
        scanf("%d%d",&u,&v);
        if (tnum[b[u]]!=tnum[b[v]]) goto fail;
        deal(b[u],b[v]);
    }
    for (int i=1;i<=blocks;i++)
        if (getx(up,i) && getx(down,i)) goto fail;
    printf("Yes\n");
    return 0;
    fail:
    printf("No\n");
    return 0;
}