#include <bits/stdc++.h>
using namespace std;
int n, mat[20010];
double w[20010];
struct node {
  int x, y;
} s[20010];
inline void Clear(vector<int> &ve) {
  vector<int> tmp;
  swap(ve, tmp);
}
void solve(vector<int> ve) {
  if (ve.empty()) return;
  int id = 0;
  for (int i = 1; i < ve.size(); ++i)
    if (s[ve[i]].x <= s[ve[id]].x) id = i;
  swap(ve[0], ve[id]);
  for (int i = 1; i < ve.size(); ++i)
    w[ve[i]] = atan2(s[ve[i]].y - s[ve[0]].y, s[ve[i]].x - s[ve[0]].x);
  sort(ve.begin() + 1, ve.end(), [](int a, int b) { return w[a] < w[b]; });
  int mid = 0;
  for (int i = 1, pre = ve[0] <= n ? 1 : -1; i < ve.size(); ++i) {
    pre += ve[i] <= n ? 1 : -1;
    if (!pre) {
      mid = i;
      break;
    }
  }
  mat[ve[0]] = ve[mid];
  mat[ve[mid]] = ve[0];
  vector<int> L, R;
  for (int i = 1; i < mid; ++i) L.push_back(ve[i]);
  for (int i = mid + 1; i < ve.size(); ++i) R.push_back(ve[i]);
  Clear(ve);
  solve(L);
  solve(R);
}
int main() {
  scanf("%d", &n);
  vector<int> ve;
  srand(time(0));
  for (int i = 1; i <= n + n; ++i)
    scanf("%d%d", &s[i].x, &s[i].y), ve.push_back(i);
  solve(ve);
  for (int i = 1; i <= n; ++i) printf("%d\n", mat[i] - n);
  return 0;
}
