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

struct Fast
{
    Fast()
    {
        std::cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << setprecision(10);
    }
} fast;

#define all(a) (a).begin(), (a).end()
#define contains(a, x) ((a).find(x) != (a).end())
#define rep(i, a, b) for (int i = (a); i < (int)(b); i++)

using ll = long long;

void calc_distance(const vector<vector<int>> &g, const int root, vector<int> &dist, vector<int> &prev, int &last_vertex)
{
    queue<int> qu;
    qu.push(root);
    dist[root] = 0;
    prev[root] = -1;
    while (!qu.empty())
    {
        auto x = qu.front();
        qu.pop();
        last_vertex = x;
        for (auto y : g[x])
            if (prev[x] != y)
            {
                qu.push(y);
                dist[y] = dist[x] + 1;
                prev[y] = x;
            }
    }
}

pair<int, int> find_center(const vector<vector<int>> &g)
{
    int u, v;
    vector<int> dist(g.size(), 0), prev(g.size(), -1);
    calc_distance(g, 0, dist, prev, u);
    calc_distance(g, u, dist, prev, v);
    int d = dist[v] / 2, x = v;
    rep(i, 0, d) x = prev[x];
    return {x, (dist[v] & 1) ? prev[x] : -1};
}

bool solve_rooted(const int N, const vector<vector<int>> &T1, const vector<vector<int>> &T2, const vector<pair<int, int>> &T2_pos, const int T1_root, const int T2_root)
{
    if (T1_root == -1 || T2_root == -1) return false;

    const ll class_coeff = 1000;
    map<ll, int> class_map;
    class_map[0] = 1;
    auto dfs = [&](auto self, int x, int p, const vector<vector<int>> &T, vector<int> &class_ids) -> void
    {
        vector<int> children_ids;
        for (auto y : T[x])
        {
            if (y == p) continue;
            self(self, y, x, T, class_ids);
            children_ids.push_back(class_ids[y]);
        }
        sort(all(children_ids));
        ll children_id = 0;
        for (auto v : children_ids)
            children_id = children_id * class_coeff + v;
        if (!contains(class_map, children_id)) class_map[children_id] = class_map.size() + 1;
        class_ids[x] = class_map[children_id];
    };
    vector<int> T1_class_ids(T1.size(), -1), T2_class_ids(T2.size(), -1);
    dfs(dfs, T1_root, -1, T1, T1_class_ids);
    dfs(dfs, T2_root, -1, T2, T2_class_ids);
    if (T1_class_ids[T1_root] != T2_class_ids[T2_root]) return false;

    vector<pair<int, int>> ans(N, {-1, -1});
    auto dfs2 = [&](auto self, int x1, int p1, int x2, int p2) -> void
    {
        if (x1 < N) ans[x1] = T2_pos[x2];
        vector<pair<int, int>> children1, children2;
        for (auto y : T1[x1])
            if (y != p1) children1.push_back({T1_class_ids[y], y});
        for (auto y : T2[x2])
            if (y != p2) children2.push_back({T2_class_ids[y], y});
        sort(all(children1));
        sort(all(children2));
        rep(i, 0, children1.size()) self(self, children1[i].second, x1, children2[i].second, x2);
    };
    dfs2(dfs2, T1_root, -1, T2_root, -1);
    cout << "Yes" << "\n";
    rep(i, 0, N)
    {
        auto [x, y] = ans[i];
        cout << (x + 1) << " " << (y + 1) << "\n";
    }
    return true;
}

void solve()
{
    int N, H, W;
    cin >> N;
    vector<tuple<int, int, int>> T;
    rep(i, 0, N - 1)
    {
        int u, v, w;
        cin >> u >> v >> w;
        T.push_back({u, v, w});
    }
    cin >> H >> W;
    vector<string> S(H);
    rep(i, 0, H) cin >> S[i];

    size_t T1_size = 1, T2_size = 0;
    for (auto [u, v, w] : T)
        T1_size += w;
    rep(i, 0, H) rep(j, 0, W) T2_size += S[i][j] == '#';

    if (T1_size != T2_size)
    {
        cout << "No" << "\n";
        return;
    }

    vector<vector<int>> T1(T1_size, vector<int>()), T2(T2_size, vector<int>());
    vector<pair<int, int>> T2_pos;
    {
        size_t dummy = N;
        for (auto [u, v, w] : T)
        {
            u--, v--;
            if (w == 1)
            {
                T1[u].push_back(v), T1[v].push_back(u);
            }
            else
            {
                T1[u].push_back(dummy), T1[dummy].push_back(u);
                rep(i, 0, w - 2)
                {
                    T1[dummy].push_back(dummy + 1), T1[dummy + 1].push_back(dummy);
                    dummy++;
                }
                T1[v].push_back(dummy), T1[dummy].push_back(v);
                dummy++;
            }
        }
    }
    {
        vector<vector<int>> T2_index(H, vector<int>(W, -1));
        rep(i, 0, H) rep(j, 0, W) if (S[i][j] == '#') T2_index[i][j] = T2_pos.size(), T2_pos.push_back({i, j});
        rep(i, 0, T2.size())
        {
            auto [x1, y1] = T2_pos[i];
            rep(k, 0, 4)
            {
                int x2 = x1 + (k & 1 ? 0 : 1 - k);
                int y2 = y1 + (k & 1 ? 2 - k : 0);
                if (x2 < 0 || x2 >= H || y2 < 0 || y2 >= W) continue;
                if (T2_index[x2][y2] != -1) T2[i].push_back(T2_index[x2][y2]);
            }
        }
    }

    size_t T1_deg_max = 0, T2_deg_max = 0;
    rep(i, 0, T1_size) T1_deg_max = max(T1_deg_max, T1[i].size());
    rep(i, 0, T2_size) T2_deg_max = max(T2_deg_max, T2[i].size());
    if (T1_deg_max != T2_deg_max)
    {
        cout << "No" << "\n";
        return;
    }

    auto [T1_c1, T1_c2] = find_center(T1);
    auto [T2_c1, T2_c2] = find_center(T2);

    if (solve_rooted(N, T1, T2, T2_pos, T1_c1, T2_c1)) return;
    if (solve_rooted(N, T1, T2, T2_pos, T1_c1, T2_c2)) return;
    if (solve_rooted(N, T1, T2, T2_pos, T1_c2, T2_c1)) return;
    if (solve_rooted(N, T1, T2, T2_pos, T1_c2, T2_c2)) return;

    cout << "No" << "\n";
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
        solve();
}