#include <bits/stdc++.h>
using namespace std;
struct point {
  int x, y, id;
  point(int x = 0, int y = 0, int id = 0) : x(x), y(y), id(id) {}
  const bool operator!=(const point &p) {
    return p.x != x || p.y != y || id != p.id;
  }
  const bool operator==(const point &p) {
    return p.x == x && p.y == y && id == p.id;
  }
};
inline int crossProd(const point &o, const point &a, const point &b) {
  return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
}
int test;
int n;
point a[20005];
bool mark[20005];
vector<point> arr;
vector<point> convexHull(vector<point> &p) {
  vector<point> result;
  for (int i = 0; i < (int)p.size(); i++) {
    while (result.size() >= 2 &&
           crossProd(result[(result.size()) - 2], result[(result.size()) - 1],
                     p[i]) >= 0)
      result.pop_back();
    result.push_back(p[i]);
  }
  int pi = (int)result.size();
  for (int i = (int)p.size() - 1; i >= 0; i--) {
    while ((int)result.size() >= pi + 1 &&
           crossProd(result[(result.size()) - 2], result[(result.size()) - 1],
                     p[i]) >= 0)
      result.pop_back();
    result.push_back(p[i]);
  }
  result.pop_back();
  return result;
}
inline int color(const point &x) { return 1 + (x.id > n); }
int res[10005];
inline void printt(const point &x, const point &y) {
  mark[x.id] = mark[y.id] = 1;
  if (x.id < y.id)
    res[x.id] = y.id - n;
  else
    res[y.id] = x.id - n;
}
void solve(vector<point> &lst) {
  if (lst.empty()) return;
  if (lst.size() == 2) {
    printt(lst[0], lst[1]);
    return;
  }
  int cnt = 0, middle = -n;
  for (int i = 0; i < (int)lst.size() - 1; i++) {
    if (color(lst[i]) == 1)
      cnt++;
    else
      cnt--;
    if (cnt == 0) {
      if (abs(i - (int)lst.size() / 2) < abs(middle - (int)lst.size() / 2))
        middle = i;
    }
  }
  if (middle != -n) {
    vector<point> rhs;
    for (int i = middle + 1; i < (int)lst.size(); i++) {
      rhs.push_back(lst[i]);
    }
    lst.erase(lst.begin() + middle + 1, lst.end());
    solve(lst);
    solve(rhs);
  } else {
    vector<point> convex = convexHull(lst);
    for (int i = 0; i < (int)convex.size(); i++) {
      if (color(convex[i]) != color(convex[(i + 1) % convex.size()]) &&
          !mark[convex[i].id] && !mark[convex[(i + 1) % convex.size()].id]) {
        printt(convex[i], convex[(i + 1) % convex.size()]);
        lst.erase(find(lst.begin(), lst.end(), convex[i]));
        lst.erase(
            find(lst.begin(), lst.end(), convex[(i + 1) % convex.size()]));
      }
    }
    solve(lst);
  }
}
int main() {
  test = 1;
  while (test--) {
    scanf("%d", &n);
    arr.clear();
    for (int i = 1; i <= 2 * n; i++) {
      mark[i] = 0;
      scanf("%d %d", &a[i].x, &a[i].y);
      a[i].id = i;
      arr.push_back(a[i]);
    }
    sort(arr.begin(), arr.end(), [&](point x, point y) {
      if (x.x == y.x) return x.y < y.y;
      return x.x < y.x;
    });
    solve(arr);
    for (int i = 1; i <= n; i++) printf("%d\n", res[i]);
  }
}
