#include <bits/stdc++.h>
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
const int inf = 0x3f3f3f3f;
inline long long read() {
  register long long x = 0, f = 1;
  register char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
  return x * f;
}
void write(long long x) {
  if (x < 0) x = -x, putchar('-');
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
void writeln(long long x) {
  write(x);
  puts("");
}
const int maxn = 1e4 + 233;
struct node {
  int x, y, opt, id;
  bool operator<(const node &w) const {
    return x < w.x || (x == w.x && y < w.y);
  }
} a[maxn * 2], c;
int ans[maxn], n;
node operator-(node a, node b) { return (node){a.x - b.x, a.y - b.y, 0, 0}; }
int cross(node a, node b) { return a.x * b.y - a.y * b.x; }
bool cmp(node a, node b) { return cross(a - c, b - c) > 0; }
void work(int l, int r) {
  if (l > r) return;
  int p = min_element(a + l, a + r + 1) - a;
  swap(a[l], a[p]);
  c = a[l];
  sort(a + l + 1, a + r + 1, cmp);
  int cnt1 = 0, cnt2 = 0, k = r;
  while (!(c.opt != a[k].opt && cnt1 == cnt2)) {
    if (c.opt == a[k].opt)
      cnt1++;
    else
      cnt2++;
    k--;
  }
  if (c.opt == 1)
    ans[a[k].id] = c.id;
  else
    ans[c.id] = a[k].id;
  work(l + 1, k - 1);
  work(k + 1, r);
}
int main() {
  n = read();
  for (register int i = (0); i < int(2 * n); ++i) {
    a[i].x = read();
    a[i].y = read();
    a[i].opt = i < n ? 0 : 1;
    a[i].id = i < n ? i + 1 : i - n + 1;
  }
  work(0, 2 * n - 1);
  for (register int i = (1); i <= int(n); ++i) writeln(ans[i]);
}
