#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXA = 3000;
const int MAXB = 3000;
const int MAXN = MAXA + MAXB;
struct P {
  int x, y, col, id;
  P() {}
  P(int x, int y) : x(x), y(y), col(-1), id(-1) {}
};
bool operator<(const P &a, const P &b) {
  if (a.x != b.x) return a.x < b.x;
  return a.y < b.y;
}
P operator-(const P &a, const P &b) { return P(a.x - b.x, a.y - b.y); }
long long operator^(const P &a, const P &b) {
  return (long long)a.x * b.y - (long long)a.y * b.x;
}
int side(const P &a, const P &b, const P &c) {
  long long res = (b - a) ^ (c - a);
  return res < 0 ? -1 : res > 0 ? +1 : 0;
}
int na, nb, n;
int want[MAXB];
P p[MAXN];
vector<pair<int, int>> ans;
int mark[MAXN], curmark;
int side(int a, int b, int c) { return side(p[a], p[b], p[c]); }
vector<int> makehull(const vector<int> &cur) {
  vector<int> ret;
  int fixed;
  ret.push_back(cur[0]);
  fixed = ((int)(ret).size());
  for (int i = (1); i < (((int)(cur).size())); ++i) {
    while (((int)(ret).size()) > fixed &&
           side(ret[((int)(ret).size()) - 2], ret[((int)(ret).size()) - 1],
                cur[i]) <= 0)
      ret.pop_back();
    ret.push_back(cur[i]);
  }
  fixed = ((int)(ret).size());
  for (int i = ((int)(cur).size()) - 2; i >= 0; --i) {
    while (((int)(ret).size()) > fixed &&
           side(ret[((int)(ret).size()) - 2], ret[((int)(ret).size()) - 1],
                cur[i]) <= 0)
      ret.pop_back();
    ret.push_back(cur[i]);
  }
  ret.pop_back();
  return ret;
}
int pivot;
bool angcmp(const int &aidx, const int &bidx) {
  P a = p[aidx] - p[pivot], b = p[bidx] - p[pivot];
  bool apos = a.y > 0 || a.y == 0 && a.x > 0,
       bpos = b.y > 0 || b.y == 0 && b.x > 0;
  if (apos != bpos) return apos;
  return (a ^ b) > 0;
}
void solve(vector<int> &cur) {
  vector<int> hull = makehull(cur);
  ++curmark;
  for (int i = (0); i < (((int)(hull).size())); ++i) {
    int idx = hull[i];
    mark[idx] = curmark;
  }
  int cent = -1;
  for (int i = (0); i < (((int)(cur).size())); ++i) {
    int idx = cur[i];
    if (mark[idx] != curmark) {
      cent = idx;
      break;
    }
  }
  if (cent == -1) {
    vector<int> lst;
    for (int i = (0); i < (((int)(hull).size())); ++i) {
      int idx = hull[i];
      while (true) {
        if (lst.empty() || p[lst.back()].col == p[idx].col) {
          lst.push_back(idx);
          break;
        }
        if (p[idx].col == 0) {
          int aid = p[idx].id, bid = p[lst.back()].id;
          ans.push_back(make_pair(bid, aid));
          assert(want[bid] > 0);
          --want[bid];
          if (want[bid] == 0)
            lst.pop_back();
          else
            break;
        } else {
          int aid = p[lst.back()].id, bid = p[idx].id;
          ans.push_back(make_pair(bid, aid));
          assert(want[bid] > 0);
          --want[bid];
          if (want[bid] == 0)
            break;
          else
            lst.pop_back();
        }
      }
    }
    assert(((int)(lst).size()) == 1 && p[lst[0]].col == 0);
  } else {
    vector<int> byang;
    for (int i = (0); i < (((int)(cur).size())); ++i)
      if (cur[i] != cent) byang.push_back(cur[i]);
    pivot = cent;
    sort(byang.begin(), byang.end(), angcmp);
    int r = -1, bal = 0, sum = p[cent].col == 0 ? 0 : want[p[cent].id],
        mn = p[cent].col == 0 ? 0 : 1, mx = p[cent].col == 0 ? 0 : sum - 1;
    int bestcnt = INT_MAX, bestl = -1, bestr = -1, bestbal = -1, bestcent = -1,
        bestsum = -1;
    for (int l = (0); l < (((int)(byang).size())); ++l) {
      int me = byang[l];
      if (r < l) r = l, bal = 0;
      while (r - l < ((int)(byang).size())) {
        int oth = byang[r % ((int)(byang).size())];
        if (side(cent, me, oth) < 0) break;
        bal += 1 - (p[oth].col == 1 ? want[p[oth].id] : 0), ++r;
      }
      if (mn <= bal && bal <= mx) {
        int cnt = max(r - l + 1, ((int)(byang).size()) - (r - l) + 1);
        if (cnt < bestcnt)
          bestcnt = cnt, bestl = l, bestr = r, bestbal = bal, bestcent = cent,
          bestsum = sum;
      }
      if (bal < mn && bal - (1 - (p[me].col == 1 ? want[p[me].id] : 0)) > mx) {
        int cnt = max(r - l + 1, ((int)(byang).size()) - (r - l) + 1);
        if (cnt < bestcnt)
          bestcnt = cnt, bestl = l, bestr = r,
          bestbal = bal - 1 + want[p[me].id] + 1 - sum, bestcent = me,
          bestsum = want[p[me].id];
      }
      if (sum == 1 && p[me].col == 0 && bal == 1) {
        int cnt = max(r - l + 1, ((int)(byang).size()) - (r - l) + 1);
        if (cnt < bestcnt)
          bestcnt = cnt, bestl = l, bestr = r, bestbal = 0, bestcent = me,
          bestsum = 0;
      }
      bal -= 1 - (p[me].col == 1 ? want[p[me].id] : 0);
    }
    assert(bestcnt != INT_MAX);
    ++curmark;
    mark[cent] = curmark;
    for (int i = (bestl); i < (bestr); ++i)
      mark[byang[i % ((int)(byang).size())]] = curmark;
    vector<int> lcur;
    for (int i = (0); i < (((int)(cur).size())); ++i) {
      int idx = cur[i];
      if (idx == bestcent || mark[idx] == curmark) lcur.push_back(idx);
    }
    vector<int> rcur;
    for (int i = (0); i < (((int)(cur).size())); ++i) {
      int idx = cur[i];
      if (idx == bestcent || mark[idx] != curmark) rcur.push_back(idx);
    }
    if (p[bestcent].col == 1) want[p[bestcent].id] = bestbal;
    solve(lcur);
    if (p[bestcent].col == 1) want[p[bestcent].id] = bestsum - bestbal;
    solve(rcur);
  }
}
bool solve() {
  sort(p, p + n);
  ans.clear();
  memset(mark, -1, sizeof(mark));
  curmark = -1;
  vector<int> cur(n);
  for (int i = (0); i < (n); ++i) cur[i] = i;
  solve(cur);
  return true;
}
void run() {
  n = 0;
  scanf("%d%d", &na, &nb);
  for (int i = (0); i < (nb); ++i) scanf("%d", &want[i]);
  for (int i = (0); i < (na); ++i) {
    scanf("%d%d", &p[n].x, &p[n].y);
    p[n].col = 0, p[n].id = i;
    ++n;
  }
  for (int i = (0); i < (nb); ++i) {
    scanf("%d%d", &p[n].x, &p[n].y);
    p[n].col = 1, p[n].id = i;
    ++n;
  }
  if (!solve()) {
    printf("NO\n");
    return;
  }
  printf("YES\n");
  for (int i = (0); i < (((int)(ans).size())); ++i)
    printf("%d %d\n", ans[i].first + 1, ans[i].second + 1);
}
int owant[MAXB];
int par[MAXN], sz[MAXN];
int find(int x) {
  if (par[x] == x) return x;
  return par[x] = find(par[x]);
}
bool unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y) return false;
  if (sz[x] < sz[y]) swap(x, y);
  par[y] = x, sz[x] += sz[y];
  return true;
}
bool intersectinternally(const P &a, const P &b, const P &c, const P &d) {
  P ab = b - a, cd = d - c;
  if ((ab ^ cd) == 0) {
    if (side(a, b, c) != 0) return false;
    printf("here\n");
    return true;
  } else {
    return side(a, b, c) * side(a, b, d) < 0 &&
           side(c, d, a) * side(c, d, b) < 0;
  }
  return false;
}
void verify() {
  for (int i = (0); i < (na + nb); ++i) par[i] = i, sz[i] = 1;
  for (int i = (0); i < (((int)(ans).size())); ++i) {
    int bid = ans[i].first, aid = ans[i].second;
    assert(0 <= aid && aid < na);
    assert(0 <= bid && bid < nb);
    assert(owant[bid] > 0);
    --owant[bid];
    assert(unite(aid, na + bid));
  }
  for (int bid = (0); bid < (nb); ++bid) assert(owant[bid] == 0);
  assert(((int)(ans).size()) == na + nb - 1);
  vector<int> amp(na, -1), bmp(nb, -1);
  for (int i = (0); i < (n); ++i)
    if (p[i].col == 0)
      amp[p[i].id] = i;
    else if (p[i].col == 1)
      bmp[p[i].id] = i;
  for (int i = (0); i < (((int)(ans).size())); ++i)
    for (int j = (i + 1); j < (((int)(ans).size())); ++j) {
      int bid1 = ans[i].first, aid1 = ans[i].second, bid2 = ans[j].first,
          aid2 = ans[j].second;
      if (intersectinternally(p[amp[aid1]], p[bmp[bid1]], p[amp[aid2]],
                              p[bmp[bid2]])) {
        printf("(%d,%d)-(%d,%d) with (%d,%d)-(%d,%d)\n", p[amp[aid1]].x,
               p[amp[aid1]].y, p[bmp[bid1]].x, p[bmp[bid1]].y, p[amp[aid2]].x,
               p[amp[aid2]].y, p[bmp[bid2]].x, p[bmp[bid2]].y);
        assert(false);
      }
    }
}
void stress() {
  int nextra = 10, dim = 20;
  for (int rep = (0); rep < (10000); ++rep) {
    na = 1 + rand() % nextra, nb = 1 + rand() % nextra;
    n = na + nb;
    for (int i = (0); i < (n); ++i)
      while (true) {
        p[i].x = rand() % dim, p[i].y = rand() % dim;
        bool ok = true;
        for (int j = (0); j < (i); ++j)
          if (p[j].x == p[i].x && p[j].y == p[i].y) ok = false;
        for (int j = (0); j < (i); ++j)
          for (int k = (0); k < (j); ++k)
            if (side(i, j, k) == 0) ok = false;
        if (ok) break;
      }
    for (int i = (0); i < (na); ++i) p[i].col = 0, p[i].id = i;
    for (int i = (0); i < (nb); ++i) p[na + i].col = 1, p[na + i].id = i;
    for (int i = (0); i < (nb); ++i) want[i] = 1;
    for (int i = (0); i < (na - 1); ++i) ++want[rand() % nb];
    for (int i = (0); i < (nb); ++i) owant[i] = want[i];
    solve();
    verify();
    printf(".");
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = (1); i <= (n); ++i) run();
  return 0;
}
