#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-10;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const long long MOD = 1e9 + 9;
int dcmp(double x) { return (x > eps) - (x < -eps); }
const int N = 2e4 + 10;
int cmpNo;
struct Node {
  int p[2], id, x;
  double q;
  bool operator<(const Node &A) const {
    if (p[cmpNo] != A.p[cmpNo]) return p[cmpNo] < A.p[cmpNo];
    return p[cmpNo ^ 1] < A.p[cmpNo ^ 1];
  }
  void read() { scanf("%d%d", &p[0], &p[1]); }
} a[N];
int b[N];
bool cmp(const Node &A, const Node &B) { return A.q < B.q; }
void dfs(int l, int r, int now) {
  if (l + 1 == r) {
    b[a[l].id] = a[r].id;
    b[a[r].id] = a[l].id;
    return;
  }
  int cnt[2]{0}, t = r, mx = r - l + 1;
  if (now < 2) {
    cmpNo = now, sort(a + l, a + r + 1);
    for (int i = l; i <= r; i++) {
      cnt[a[i].x]++;
      if (i < r && a[i].p[now] == a[i + 1].p[now]) {
        continue;
      }
      if (cnt[0] == cnt[1]) {
        int d = abs((i - l + 1) - (r - i));
        if (d < mx) {
          mx = d;
          t = i;
        }
      }
    }
    dfs(l, t, (now + 1) % 3);
    if (t + 1 < r) dfs(t + 1, r, (now + 1) % 3);
  } else {
    cmpNo = 1, sort(a + l, a + r + 1);
    for (int i = l + 1; i <= r; i++) {
      a[i].q = atan2(a[i].p[1] - a[l].p[1], a[i].p[0] - a[l].p[0]);
    }
    sort(a + l + 1, a + r + 1, cmp);
    for (int i = l; i <= r; i++) {
      cnt[a[i].x]++;
      if (cnt[0] == cnt[1] && a[i].x != a[l].x) {
        int d = abs((i - l + 1) - (r - i));
        if (d < mx) {
          mx = d;
          t = i;
        }
      }
    }
    b[a[l].id] = a[t].id;
    b[a[t].id] = a[l].id;
    if (l < t - 1) dfs(l + 1, t - 1, (now + 1) % 3);
    if (t + 1 < r) dfs(t + 1, r, (now + 1) % 3);
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < 2 * n; i++) {
    a[i].read();
    a[i].id = i;
    a[i].x = i / n;
  }
  dfs(0, 2 * n - 1, 0);
  for (int i = 0; i < n; i++) {
    printf("%d\n", b[i] - n + 1);
  }
  return 0;
}
