#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 MAXN = 10000;
struct P {
  int x, y, id;
};
P operator-(const P &a, const P &b) {
  P ret;
  ret.x = a.x - b.x, ret.y = a.y - b.y;
  return ret;
}
long long operator^(const P &a, const P &b) {
  return (long long)a.x * b.y - (long long)a.y * b.x;
}
bool pcmp(const P &a, const P &b) {
  bool aorig = a.x == 0 && a.y == 0, borig = b.x == 0 && b.y == 0;
  if (aorig != borig) return aorig;
  bool atop = a.y > 0 || a.y == 0 && a.x > 0,
       btop = b.y > 0 || b.y == 0 && b.x > 0;
  if (atop != btop) return atop;
  long long side = a ^ b;
  if (side != 0) return side > 0;
  return a.id < b.id;
}
void partition(vector<P> va, vector<P> vb, const P piv, vector<P> &va1,
               vector<P> &va2, vector<P> &vb1, vector<P> &vb2) {
  for (int i = (0); i < (((int)(va).size())); ++i)
    va[i].x -= piv.x, va[i].y -= piv.y;
  for (int i = (0); i < (((int)(vb).size())); ++i)
    vb[i].x -= piv.x, vb[i].y -= piv.y;
  sort(va.begin(), va.end(), pcmp);
  sort(vb.begin(), vb.end(), pcmp);
  vector<P> aorig;
  for (int i = (0); i < (((int)(va).size())); ++i)
    if (va[i].x == 0 && va[i].y == 0) aorig.push_back(va[i]);
  for (int i = (0); i < (((int)(va).size()) - ((int)(aorig).size())); ++i)
    va[i] = va[i + ((int)(aorig).size())];
  for (int i = (0); i < (((int)(aorig).size())); ++i) va.pop_back();
  vector<P> borig;
  for (int i = (0); i < (((int)(vb).size())); ++i)
    if (vb[i].x == 0 && vb[i].y == 0) borig.push_back(vb[i]);
  for (int i = (0); i < (((int)(vb).size()) - ((int)(borig).size())); ++i)
    vb[i] = vb[i + ((int)(borig).size())];
  for (int i = (0); i < (((int)(borig).size())); ++i) vb.pop_back();
  int na = ((int)(va).size());
  for (int i = (0); i < (na); ++i) va.push_back(va[i]);
  int nb = ((int)(vb).size());
  for (int i = (0); i < (nb); ++i) vb.push_back(vb[i]);
  int la = 0, ra = 0, lb = 0, rb = 0;
  bool any = false;
  int bmx = -1, bla = -1, bra = -1, blb = -1, brb = -1;
  for (int i = (0); i < (na + nb); ++i) {
    bool afst = la < na && (lb >= nb || pcmp(va[la], vb[lb]));
    P dir = afst ? va[la] : vb[lb];
    while (ra - la < na && (dir ^ va[ra]) >= 0) ++ra;
    while (rb - lb < nb && (dir ^ vb[rb]) >= 0) ++rb;
    int acnt = ((int)(aorig).size()) + ra - la,
        bcnt = ((int)(borig).size()) + rb - lb;
    if (acnt == bcnt) {
      int mx = max(acnt, na + ((int)(aorig).size()) - acnt);
      if (!any || mx < bmx)
        any = true, bmx = mx, bla = la, bra = ra, blb = lb, brb = rb;
    }
    if (acnt - (afst ? 1 : 0) == bcnt - (!afst ? 1 : 0)) {
      int mx = max(acnt - (afst ? 1 : 0),
                   na + ((int)(aorig).size()) - (acnt - (afst ? 1 : 0)));
      if (!any || mx < bmx)
        any = true, bmx = mx, bla = la + (afst ? 1 : 0), bra = ra,
        blb = lb + (!afst ? 1 : 0), brb = rb;
    }
    if (afst)
      ++la;
    else
      ++lb;
    if (ra < la) ra = la;
    if (rb < lb) rb = lb;
  }
  assert(any);
  for (int i = (0); i < (((int)(aorig).size())); ++i)
    aorig[i].x += piv.x, aorig[i].y += piv.y;
  for (int i = (0); i < (((int)(va).size())); ++i)
    va[i].x += piv.x, va[i].y += piv.y;
  for (int i = (0); i < (((int)(borig).size())); ++i)
    borig[i].x += piv.x, borig[i].y += piv.y;
  for (int i = (0); i < (((int)(vb).size())); ++i)
    vb[i].x += piv.x, vb[i].y += piv.y;
  va1.clear();
  va2.clear();
  for (int i = (0); i < (((int)(aorig).size())); ++i) va1.push_back(aorig[i]);
  for (int i = (0); i < (na); ++i)
    if (bla <= i && i < bra || bla <= i + na && i + na < bra)
      va1.push_back(va[i]);
    else
      va2.push_back(va[i]);
  vb1.clear();
  vb2.clear();
  for (int i = (0); i < (((int)(borig).size())); ++i) vb1.push_back(borig[i]);
  for (int i = (0); i < (nb); ++i)
    if (blb <= i && i < brb || blb <= i + nb && i + nb < brb)
      vb1.push_back(vb[i]);
    else
      vb2.push_back(vb[i]);
  assert(((int)(va1).size()) == ((int)(vb1).size()));
  assert(((int)(va2).size()) == ((int)(vb2).size()));
}
int ans[MAXN];
void solve(const vector<P> &va, const vector<P> &vb) {
  assert(((int)(va).size()) == ((int)(vb).size()));
  if (((int)(va).size()) == 1) {
    ans[va[0].id] = vb[0].id;
    return;
  }
  vector<P> va1, va2, vb1, vb2;
  for (int rep = (0); rep < (100); ++rep) {
    int pividx = rand() % (((int)(va).size()) + ((int)(vb).size()));
    P piv = pividx < ((int)(va).size()) ? va[pividx]
                                        : vb[pividx - ((int)(va).size())];
    vector<P> _va1, _va2, _vb1, _vb2;
    partition(va, vb, piv, _va1, _va2, _vb1, _vb2);
    if (rep == 0 || max(((int)(_va1).size()), ((int)(_va2).size())) <
                        max(((int)(va1).size()), ((int)(va2).size())))
      va1 = _va1, va2 = _va2, vb1 = _vb1, vb2 = _vb2;
    int mx = max(((int)(va1).size()), ((int)(va2).size()));
    if (4 * mx <= 3 * ((int)(va).size())) break;
    if (rep >= 9 && ((int)(va1).size()) < ((int)(va).size()) &&
        ((int)(va2).size()) < ((int)(va).size()))
      break;
  }
  assert(((int)(va1).size()) < ((int)(va).size()) &&
         ((int)(va2).size()) < ((int)(va).size()));
  solve(va1, vb1);
  solve(va2, vb2);
}
int n;
P a[MAXN];
P b[MAXN];
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) scanf("%d%d", &a[i].x, &a[i].y), a[i].id = i;
  for (int i = (0); i < (n); ++i) scanf("%d%d", &b[i].x, &b[i].y), b[i].id = i;
  vector<P> va(n);
  for (int i = (0); i < (n); ++i) va[i] = a[i];
  vector<P> vb(n);
  for (int i = (0); i < (n); ++i) vb[i] = b[i];
  for (int i = (0); i < (n); ++i) ans[i] = -1;
  solve(va, vb);
  for (int i = (0); i < (n); ++i) printf("%d\n", ans[i] + 1);
}
int myrand() { return rand() % 1000 * 1000 + rand(); }
void stress() {
  for (int rep = (0); rep < (10000); ++rep) {
    n = 200;
    vector<P> p;
    int tmp = 0;
    while (((int)(p).size()) < 2 * n) {
      P cur;
      cur.x = myrand() % 20001 - 10000, cur.y = myrand() % 20001 - 10000;
      bool ok = true;
      for (int i = (0); i < (((int)(p).size())); ++i)
        for (int j = (i + 1); j < (((int)(p).size())); ++j)
          if (((p[j] - p[i]) ^ (cur - p[i])) == 0) ok = false;
      for (int i = (0); i < (((int)(p).size())); ++i)
        if (p[i].x == cur.x && p[i].y == cur.y) ok = false;
      if (++tmp > 1000000) {
        printf("here\n");
        for (int i = (0); i < (((int)(p).size())); ++i)
          printf("%d %d\n", p[i].x, p[i].y);
        exit(0);
      }
      if (ok) p.push_back(cur);
    }
    vector<P> va(n);
    for (int i = (0); i < (n); ++i) va[i] = p[i], va[i].id = i;
    vector<P> vb(n);
    for (int i = (0); i < (n); ++i) vb[i] = p[n + i], vb[i].id = i;
    solve(va, vb);
    printf(".");
  }
}
int main() {
  run();
  return 0;
}
