#include<bits/stdc++.h>
#define FOR(i,s,e) for(int i=(s); i<=(e); i++)
#define FORD(i,s,e) for(int i=(s); i>=(e); i--)
#define ALL(k) (k).begin(), (k).end()
#define pb push_back
#define e1 first
#define e2 second
#define eb emplace_back

using namespace std;
const bool print = false;
using LD = long double;
using PII = pair<int,int>;
using PDI = pair<double, int>;
const int MAXN = 1111;
const int INF = 1000111000;

vector<int> kraw[MAXN];
int ojc[MAXN];
int subt[MAXN];
vector<PDI> assignedTrees[MAXN];
int treeHere[MAXN];
PII tr[MAXN];
vector<PII> ans;

void dfs0(int v){
	subt[v] = 1;
	for(auto& b : kraw[v]){
		if(b==ojc[v]) continue;
		ojc[b] = v;
		dfs0(b);
		subt[v] += subt[b];
	}
}


void dfs(int v){
	int highest = assignedTrees[v].back().e2;
	for(auto& tree : assignedTrees[v]){
		if(tr[tree.e2] < tr[highest]){
			highest = tree.e2;
		}
	}
	for(auto& tree : assignedTrees[v]){
		if (tree.e2 == highest) tree.e1 = 1e30;
		else tree.e1 = atan2(tr[tree.e2].e2 - tr[highest].e2, tr[tree.e2].e1 - tr[highest].e1);
	}
	sort(ALL(assignedTrees[v]));
	treeHere[v] = highest;
	
	auto it = assignedTrees[v].begin();
	for(auto b : kraw[v]){
		if(b == ojc[v]) continue;
		FOR(i,1,subt[b]){
			assignedTrees[b].eb(0., it->e2);
			it++;
		}
		dfs(b);
	}
	if(v!=1) ans.eb(treeHere[v], treeHere[ojc[v]]);
}


int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	int n; cin >> n;
	FOR(i,2,n){
		int a, b; cin>>a>>b;
		a++, b++;
		kraw[a].pb(b);
		kraw[b].pb(a);
	}
	FOR(i,1,n){
		cin>>tr[i].e1>>tr[i].e2;
		assignedTrees[1].eb(0,i);
	}
	dfs0(1);
	dfs(1);
	for(auto it:ans) cout << it.e1-1 << " " << it.e2-1 << "\n";
}

