#include <bits/stdc++.h>
#define ll long long
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define MOD 1000000007

using namespace std;

typedef pair<int, int> P;

const int LOG_N = 14;
const int MAX_N = 10005;
const int MAX_M = 100005;

struct edge {
    int to, id;
};

struct eda {
    int from, to, id;
};

P hoge[MAX_M];
P ans[MAX_M];

class biconnected {
private:
    void dfs(int u, int p, int &k)
    {
        visit[u] = true;
        ord[u] = k++;
        low[u] = ord[u];
        for(int i = 0; i < (int)G[u].size(); ++i){
            const edge& e = G[u][i];
            const int v = e.to;
            if(!visit[v]){
                dfs(v, u, k);
                low[u] = min(low[u], low[v]);
                if(ord[u] < low[v]){
                    bridge.push_back((eda){u, v, e.id});
                    check[u][i].second = 1;
                    check[v][check[u][i].first].second = 1;
                }
                ans[e.id] = {u, v};
            }else if(v != p){
                low[u] = min(low[u], ord[v]);
                if(ans[e.id].first == ans[e.id].second){
                    ans[e.id] = {u, v};
                }
                // cout << e.id << " " << u << " " << v << "\n";
            }
        }
    }
    void restrict_dfs(int u, int p, int kind, queue<int>& que)
    {
        visit[u] = true;
        cmp[u] = kind;
        for(int i = 0; i < (int)G[u].size(); ++i){
            const edge& e = G[u][i];
            const int v = e.to;
            if(check[u][i].second){
                if(!visit[v]){
                    que.push(v);
                }
            }else if(!visit[v]){
                restrict_dfs(v, u, kind, que);
            }
        }
    }
    void rebuild()
    {
        kind = 0;
        fill(visit, visit + V, false);
        rep(i,V){
            if(!visit[i]){
                queue<int> que;
                que.push(i);
                while(!que.empty()){
                    int p = que.front();
                    que.pop();
                    restrict_dfs(p, -1, kind, que);
                    kind++;
                }
            }
        }
    }
public:
    int V, kind;
    vector<vector<edge> > G, tree;
    vector<vector<P> > check;
    vector<eda> bridge;
    vector<int> ord, low, cmp;
    bool *visit;
    biconnected(const int node_size)
        : V(node_size), kind(0), G(V), check(V), ord(V), low(V), cmp(V), visit(new bool[V]()){}

    void add_edge(int u, int v, int id)
    {
        G[u].push_back((edge){v, id}), G[v].push_back((edge){u, id});
        check[u].emplace_back((int)check[v].size(), 0);
        check[v].emplace_back((int)check[u].size()-1, 0);
    }
    void detect_bridge(){
        int id = 0;
        rep(i,V) if(!visit[i]) dfs(i, -1, id);
    }
    int make_bctree()
    {
        rebuild();
        tree.resize(kind);
        for(const eda& e : bridge){
            int a = cmp[e.from], b = cmp[e.to];
            tree[a].push_back((edge){b, e.id}), tree[b].push_back((edge){a, e.id});
        }
        return kind;
    }
};

int par[LOG_N][MAX_N];
int depth[MAX_N];
P pp[MAX_N], invp[MAX_N];

void dfs(int u, int p, int d, const vector<vector<edge> >& G){
    par[0][u] = p;
    depth[u] = d;
    for(const edge& e : G[u]){
        if(e.to != p){
            pp[e.to] = invp[e.to] = {u, e.id};
            dfs(e.to, u, d+1, G);
        }
    }
}

int lca(int u, int v)
{
    if(depth[u] > depth[v]) swap(u, v);
    rep(i, LOG_N){
        if((depth[v] - depth[u]) & (1 << i)){
            v = par[i][v];
        }
    }
    if(u == v) return u;
    for(int i = LOG_N - 1; i >= 0; --i){
        if(par[i][u] != par[i][v]){
            u = par[i][u], v = par[i][v];
        }
    }
    return par[0][u];
}

set<int> ue, shita;

bool search(int u, int v, const vector<int>& cmp)
{
    vector<int> ch1, ch2;
    int l = lca(u, v);
    // cout << "NOBORI\n";
    while(depth[u] > depth[l]){
        // cout << u << "\n";
        int q = pp[u].second;
        if(shita.find(q) != shita.end()) return false;
        ch1.push_back(u);
        if(q >= 0){
            if(cmp[hoge[q].first] == u){
                ans[q] = {hoge[q].first, hoge[q].second};
            }else{
                ans[q] = {hoge[q].second, hoge[q].first};
            }
            ue.insert(q);
        }
        u = pp[u].first;
    }
    for(int w : ch1) pp[w] = {u, -1};
    while(depth[v] > depth[l]){
        // cout << v << "\n";
        int q = invp[v].second;
        if(ue.find(q) != ue.end()) return false;
        ch2.push_back(v);
        if(q >= 0){
            if(cmp[hoge[q].first] == v){
                ans[q] = {hoge[q].second, hoge[q].first};
            }else{
                ans[q] = {hoge[q].first, hoge[q].second};
            }
            shita.insert(q);
        }
        v = invp[v].first;
    }
    for(int w : ch2) invp[w] = {v, -1};
    return true;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    biconnected bc(n);
    rep(i,m){
        int x, y;
        cin >> x >> y;
        --x, --y;
        bc.add_edge(x, y, i);
        hoge[i] = {x, y};
    }
    bc.detect_bridge();
    int nw = bc.make_bctree();
    auto& G = bc.tree;
    auto& cmp = bc.cmp;
    dfs(0, -1, 0, G);
    rep(i,LOG_N-1){
        rep(j,nw){
            if(par[i][j] < 0){
                par[i+1][j] = -1;
            }else{
                par[i+1][j] = par[i][par[i][j]];
            }
        }
    }
    bool dame = false;
    int k;
    cin >> k;
    rep(i,k){
        int a, b;
        cin >> a >> b;
        --a, --b;
        if(cmp[a] == cmp[b] || dame) continue;
        if(!search(cmp[a], cmp[b], cmp)){
            dame = true;
        }
    }
    if(dame){
        cout << "No\n";
    }else{
        cout << "Yes\n";
        rep(i,m){
            cout << ans[i].first + 1 << " " << ans[i].second + 1 << "\n";
        }
    }
}



Measured memory_bytes: 9784