#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn=1505,inf=0x3f3f3f3f;
struct point
{
    LL x,y,id,num;
}p[maxn],s;
bool cmp1 (point a,point b)
{
    return a.x<=b.x&&a.y<=b.y;
}
bool cmp2 (point a,point b)
{
    return (a.x-s.x)*(b.y-s.y)<(a.y-s.y)*(b.x-s.x);
}
struct Edge
{
    LL v,nxt;
}e[maxn<<1];
LL head[maxn],tot;
LL n,size[maxn],ans[maxn];
void add(LL from,LL to)
{
    e[++tot].nxt=head[from];
    e[tot].v=to;
    head[from]=tot;
}
void dfs(int u,int fa)
{
    size[u]=1;
    for(int i=head[u];i!=0;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,u);
        size[u]+=size[v];
    }
}
void solve(LL u,LL fa,LL l,LL r)
{
    sort(p+l,p+r+1,cmp1);
    s=p[l];ans[p[l].id]=u;
    sort(p+l+1,p+r+1,cmp2);
    LL last=l;
    for(int i=head[u];i!=0;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v==fa) continue;
        solve(v,u,last+1,last+size[v]);
        last=last+size[v];
    }
}
int main()
{
    cin>>n;
    for(LL i=1;i<n;i++)
    {
        LL u,v;
        scanf("%lld%lld",&u,&v);
        add(u,v),add(v,u);
    }
    for(LL i=1;i<=n;i++)
        scanf("%lld%lld",&p[i].x,&p[i].y),p[i].id=i;
    dfs(1,0);
    solve(1,0,1,n);
    for(int i=1;i<=n;i++)
        printf("%lld ",ans[i]);
    puts("");
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn=1505,inf=0x3f3f3f3f;
struct point
{
    LL x,y,id,num;
}p[maxn],s;
bool cmp1 (point a,point b)
{
    return a.x<=b.x&&a.y<=b.y;
}
bool cmp2 (point a,point b)
{
    return (a.x-s.x)*(b.y-s.y)>(a.y-s.y)*(b.x-s.x);
}
struct Edge
{
    LL v,nxt;
}e[maxn<<1];
LL head[maxn],tot;
LL n,size[maxn],ans[maxn];
void add(LL from,LL to)
{
    e[++tot].nxt=head[from];
    e[tot].v=to;
    head[from]=tot;
}
void dfs(int u,int fa)
{
    size[u]=1;
    for(int i=head[u];i!=0;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,u);
        size[u]+=size[v];
    }
}
void solve(LL u,LL fa,LL l,LL r)
{
    sort(p+l,p+r+1,cmp1);
    s=p[l];ans[p[l].id]=u;
    sort(p+l+1,p+r+1,cmp2);
    LL last=l;
    for(int i=head[u];i!=0;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v==fa) continue;
        solve(v,u,last+1,last+size[v]);
        last=last+size[v];
    }
}
int main()
{
    cin>>n;
    for(LL i=1;i<n;i++)
    {
        LL u,v;
        scanf("%lld%lld",&u,&v);
        add(u,v),add(v,u);
    }
    for(LL i=1;i<=n;i++)
        scanf("%lld%lld",&p[i].x,&p[i].y),p[i].id=i;
    dfs(1,0);
    solve(1,0,1,n);
    for(int i=1;i<=n;i++)
        printf("%lld ",ans[i]);
    puts("");
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn=1505,inf=0x3f3f3f3f;
struct point
{
    LL x,y,id,num;
}p[maxn],s;
bool operator< (point a,point b)
{
    return (a.x-s.x)*(b.y-s.y)>(a.y-s.y)*(b.x-s.x);
}
struct Edge
{
    LL v,nxt;
}e[maxn<<1];
LL head[maxn],tot;
LL n,size[maxn],ans[maxn];
void add(LL from,LL to)
{
    e[++tot].nxt=head[from];
    e[tot].v=to;
    head[from]=tot;
}
void dfs(int u,int fa)
{
    size[u]=1;
    for(int i=head[u];i!=0;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,u);
        size[u]+=size[v];
    }
}
void solve(LL u,LL fa,LL l,LL r)
{
    s.x=s.y=inf;
    for(LL i=l;i<=r;i++)
        if(p[i].x<=s.x&&p[i].y<=s.y)
            ans[p[i].id]=u,s=p[i];
    sort(p+l,p+r+1);
    LL last=l;
    for(int i=head[u];i!=0;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v==fa) continue;
        solve(v,u,last+1,last+size[v]);
        last=l+size[v];
    }
}
int main()
{
    cin>>n;
    for(LL i=1;i<n;i++)
    {
        LL u,v;
        scanf("%lld%lld",&u,&v);
        add(u,v),add(v,u);
    }
    for(LL i=1;i<=n;i++)
        scanf("%lld%lld",&p[i].x,&p[i].y),p[i].id=i;
    dfs(1,0);
    solve(1,0,1,n);
    for(int i=1;i<=n;i++)
        printf("%lld ",ans[i]);
    puts("");
}


#include <bits/stdc++.h>

using namespace std;
typedef long long INT;
typedef double DO;
typedef pair<int, int> pii;
typedef vector<int> VI;

struct point {
    int x, y, id;
    point (int x=0, int y=0, int id=0) : x(x), y(y), id(id) {}
    point operator - (point a) {return point(x-a.x, y-a.y, id);}
    point operator + (point a) {return point(x+a.x, y+a.y, id);}
    INT operator ^ (point a) {return (INT)x*a.y-(INT)y*a.x;}
    bool operator < (const point &a) {
        if (a.x!=x) return x<a.x;
        return y<a.y;
    }
};

const int NN=1555;

VI adj[NN];
int sz[NN], id[NN];
point p[NN];

void dfs(int u, int pa=0) {
    sz[u]=1;
    for (int v : adj[u]) {
        if (v==pa) continue;
        dfs(v, u);
        sz[u]+=sz[v];
    }
}

int st;
void dfs1(int u, int pa=0) {
    id[p[++st].id]=u;
    for (int i=st+1; i<st+sz[u]; i++) p[i]=p[i]-p[st];
    sort(p+st+1, p+st+sz[u], [](point u, point v){
        return (u^v)>0;
    });
    for (int i=st+1; i<st+sz[u]; i++) p[i]=p[i]+p[st];
    for (int v : adj[u]) {
        if (v==pa) continue;
        dfs1(v, u);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
#endif

    int n;
    cin>>n;
    for (int i=1; i<n; i++) {
        int u, v;
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    for (int i=1; i<=n; i++) cin>>p[i].x>>p[i].y, p[i].id=i;
    for (int i=2; i<=n; i++) if (p[i]<p[1]) swap(p[i], p[1]);

    dfs(1);
    dfs1(1);

    for (int i=1; i<=n; i++) cout << id[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long INT;
typedef double DO;
typedef pair<int, int> pii;
typedef vector<int> VI;

struct point {
    int x, y, id;
    point (int x=0, int y=0, int id=0) : x(x), y(y), id(id) {}
    point operator - (point a) {return point(x-a.x, y-a.y, id);}
    point operator + (point a) {return point(x+a.x, y+a.y, id);}
    INT operator ^ (point a) {return (INT)x*a.y-(INT)y*a.x;}
    bool operator < (const point &a) {
        if (a.x!=x) return x<a.x;
        return y<a.y;
    }
};

const int NN=1555;

VI adj[NN];
int sz[NN], id[NN];
point p[NN];

void dfs(int u, int pa=0) {
    sz[u]=1;
    for (int v : adj[u]) {
        if (v==pa) continue;
        dfs(v, u);
        sz[u]+=sz[v];
    }
}

int st;
void dfs1(int u, int pa=0) {
    id[p[++st].id]=u;
    for (int i=st+1; i<st+sz[u]; i++) p[i]=p[i]-p[st];
    sort(p+st+1, p+st+sz[u], [](point u, point v){
        return (u^v)>0;
    });
    for (int i=st+1; i<st+sz[u]; i++) p[i]=p[i]+p[st];
    for (int v : adj[u]) {
        if (v==pa) continue;
        dfs1(v, u);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.in", "r", stdin);
    freopen("out.out", "w", stdout);
#endif

    int n;
    cin>>n;
    for (int i=1; i<n; i++) {
        int u, v;
        cin>>u>>v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    for (int i=1; i<=n; i++) cin>>p[i].x>>p[i].y, p[i].id=i;
    for (int i=2; i<=n; i++) if (p[i]<p[1]) swap(p[i], p[1]);
    for (int i=1; i<=n; i++) printf("%d %d %d\n", p[i].x, p[i].y, p[i].id);

    dfs(1);
    dfs1(1);

    for (int i=1; i<=n; i++) cout << id[i] << ' ';

    return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define sz(a) ((int)a.size())
#define x first
#define y second
#define bpt(x) (__builtin_popcount(x))
#define bit(x, y) (((x)>>(y))&1)
#define bclz(x) (__builtin_clz(x))
#define bctz(x) (__builtin_ctz(x))

using namespace std;

typedef double DO;
typedef long long INT;
typedef pair<int, int> pii;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, U b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, U b) {if(a<b) a=b;}

template<class T>inline void gn(T &x) {char c, sg=0; while (c=getchar(), (c>'9' || c<'0') && c!='-');for((c=='-'?sg=1, c=getchar():0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0';if (sg) x=-x;}
template<class T>inline void print(T x) {if (x<0) {putchar('-');return print(-x);}if (x<10) {putchar('0'+x);return;} print(x/10);putchar(x%10+'0');}
template <class T> inline void println(T x) {print(x); putchar('\n');}

int power(int a, int b, int m, int ans=1) {
	for(; b; b>>=1, a=1LL*a*a%m) if(b&1) ans=1LL*ans*a%m;
	return ans;
}

int n;
#define NN 2222
VI adj[NN], vec;
int ans[NN];
int son[NN];

struct point {
	int x, y;
	point (int x=0, int y=0) : x(x), y(y) {}
	bool operator < (const point &a) const {if (x!=a.x) return x<a.x; return y<a.y;}
	INT operator ^ (point a) {return (INT)x*a.y-(INT)y*a.x;}
	INT operator * (point a) {return (INT)x*a.x+(INT)y*a.y;}
	point operator - (point a) {return point(x-a.x, y-a.y);}
	void input() {scanf("%d%d", &x, &y); }
} p[NN];

point O;
VI tmp;
int sgn(INT s) {return (s>0)-(s<0);}

int cmp(int aa, int ba) {
	point a=p[aa], b=p[ba];
	int sg=sgn((a-O)^(b-O));
	if (sg) return sg>0;
	return (a-O)*(a-O)<(b-O)*(b-O);
}

int cmp1(int u, int v) {
	if(p[u].x == p[v].x) return p[u].y < p[v].y;
	return p[u].x < p[v].x;
}

void solve(VI vec, int u, int fa=0) {
	sort(vec.begin(), vec.end(), cmp1);
	O = p[vec[0]];
	ans[vec[0]] = u;
	swap(vec[0], vec[sz(vec)-1]);
	vec.pop_back();
	if(sz(vec) == 0) return ;
	sort(vec.begin(), vec.end(), cmp);
	int nn=0;
	for(int v : adj[u]) {
		if(v == fa) continue;
		tmp.clear();
		tmp.resize(son[v]);
		for(int j=0; j<son[v]; j++) tmp[j]=vec[nn++];
		solve(tmp, v, u);
	}
}

void dfs(int u, int fa=0) {
	for(int v : adj[u]) {
		if(v == fa) continue;
		dfs(v, u);
		son[u] += son[v];
	}
	son[u]++;
}

void solve() {
	cin >> n;
	for(int i=0; i<n-1; i++) {
		int u, v; gn(u); gn(v);
		adj[u].pb(v);
		adj[v].pb(u);
	}
	for(int i=1; i<=n; i++) {
		p[i].input();
		vec.pb(i);
	}
	dfs(1);
	solve(vec, 1);
	for(int i=1; i<=n; i++) println(ans[i]);
}

int main() {
#ifndef	ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	solve();
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;

const int maxn = 1505;
struct point { int x, y, id; } p[maxn];
int sz[maxn], ans[maxn], n, a, b;
vector<int> e[maxn];

void dfs(int u, int fa) {
	sz[u] = 1;
	for (auto v : e[u])
		if (v != fa) dfs(v, u), sz[u] += sz[v];
}

ll cross(point p, point a, point b) {
	return 1ll * (a.x - p.x) * (b.y - p.y) - 1ll * (b.x - p.x) * (a.y - p.y);
}

bool cmp(point a, point b) {
	return cross(p[0], a, b) > 0;
}

void solve(int u, int fa, int l, int r) {
	int cur = l;
	rep (i, l + 1, r)
		if (p[i].y < p[cur].y || p[i].y == p[cur].y && p[i].x < p[cur].x) cur = i;
	p[0] = p[cur];
	sort(p+l+1, p+r+1, cmp);
	ans[p[l].id] = u;
	int last = l;
	for (auto v : e[u])
		if (v != fa) {
			solve(v, u, last + 1, last + sz[v]);
			last += sz[v];
		}
}

int main() {
	scanf("%d", &n);
	rep (i, 1, n - 1) {
		scanf("%d%d", &a, &b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	rep (i, 1, n) scanf("%d%d", &p[i].x, &p[i].y), p[i].id = i;
	dfs(1, 0); solve(1, 0, 1, n);
	rep (i, 1, n) printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Point {
    ll x, y, id;
    void input () {
        scanf ("%I64d%I64d", &x, &y);
    }
    Point(ll x = 0, ll y = 0, ll id = 0) :x(x), y(y), id(id) {}
    Point operator - (const Point &b) const {
        return Point (x - b.x, y - b.y);
    }
};

ll cross(Point a, Point b) {
    return a.x * b.y - a.y * b.x;
}
Point tmp;
const int N = 2e3 + 5;
int n, ans[N], sz[N];
vector<int>G[N];
Point p[N];

bool operator < (Point a, Point b) {
    return cross(a - tmp, b - tmp) > 0;
}
void dfs(int u, int pre) {
    sz[u] = 1;
    for (int v : G[u]) if (v != pre) sz[u] += sz[v];
}
void solve(int u, int pre, int l, int r) {
    tmp = p[l];
    for (int i = l + 1; i <= r; i++) if (p[i].y < tmp.y || (p[i].y == tmp.y && p[i].x < tmp.x)) tmp = p[i];
    sort(p + l + 1, p + r + 1);
    ans[p[l].id] = u;
    int last = l;
    for (int v : G[u]) if (v != pre) {
        solve(v, u, last + 1, last + sz[v]);
        last += sz[v];
    }
}
int main() {
    scanf("%d", &n);
    for (int i = 0, u, v; i < n - 1; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        p[i].input();
        p[i].id = i;
    }
    dfs(1, -1);
    solve(1, -1, 1, n);
    for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Point {
    ll x, y, id;
    void input () {
        scanf ("%I64d%I64d", &x, &y);
    }
    Point(ll x = 0, ll y = 0, ll id = 0) :x(x), y(y), id(id) {}
    Point operator - (const Point &b) const {
        return Point (x - b.x, y - b.y);
    }
};

ll cross(Point a, Point b) {
    return a.x * b.y - a.y * b.x;
}
Point tmp;
const int N = 2e3 + 5;
int n, ans[N], sz[N];
vector<int>G[N];
Point p[N];

bool operator < (Point a, Point b) {
    return cross(a - tmp, b - tmp) > 0;
}
void dfs(int u, int pre) {
    sz[u] = 1;
    for (int v : G[u]) if (v != pre) {
        dfs(v, u);
        sz[u] += sz[v];
    }
}
void solve(int u, int pre, int l, int r) {
    tmp = p[l];
    for (int i = l + 1; i <= r; i++) if (p[i].y < tmp.y || (p[i].y == tmp.y && p[i].x < tmp.x)) tmp = p[i];
    sort(p + l + 1, p + r + 1);
    ans[p[l].id] = u;
    int last = l;
    for (int v : G[u]) if (v != pre) {
        solve(v, u, last + 1, last + sz[v]);
        last += sz[v];
    }
}
int main() {
    scanf("%d", &n);
    for (int i = 0, u, v; i < n - 1; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        p[i].input();
        p[i].id = i;
    }
    dfs(1, -1);
    solve(1, -1, 1, n);
    for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Point {
    ll x, y, id;
    void input () {
        scanf ("%I64d%I64d", &x, &y);
    }
    Point(ll x = 0, ll y = 0, ll id = 0) :x(x), y(y), id(id) {}
    Point operator - (const Point &b) const {
        return Point (x - b.x, y - b.y);
    }
};

ll cross(Point a, Point b) {
    return a.x * b.y - a.y * b.x;
}
Point tmp;
const int N = 2e3 + 5;
int n, ans[N], sz[N];
vector<int>G[N];
Point p[N];

bool operator < (Point a, Point b) {
    if (a.x == 0 && a.y == 0) return 1;
    if (b.x == 0 && b.y == 0) return 0;
    return cross(a - tmp, b - tmp) > 0;
}
int dfs(int u, int pre) {
    sz[u] = 1;
    for (int v : G[u]) if (v != pre) sz[u] += dfs(v, u);
    return sz[u];
}
void solve(int u, int pre, int l, int r) {
    tmp = p[l];
    for (int i = l + 1; i <= r; i++) if (p[i].y < tmp.y || (p[i].y == tmp.y && p[i].x < tmp.x)) tmp = p[i];
    sort(p + l, p + r + 1);
    ans[p[l].id] = u;
    int last = l;
    for (int v : G[u]) if (v != pre) {
        solve(v, u, last + 1, last + sz[v]);
        last += sz[v];
    }
}
int main() {
    scanf("%d", &n);
    for (int i = 0, u, v; i < n - 1; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        p[i].input();
        p[i].id = i;
    }
    dfs(1, -1);
    solve(1, -1, 1, n);
    for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Point {
    ll x, y, id;
    void input () {
        scanf ("%I64d%I64d", &x, &y);
    }
    Point(ll x = 0, ll y = 0, ll id = 0) :x(x), y(y), id(id) {}
    Point operator - (const Point &b) const {
        return Point (x - b.x, y - b.y);
    }
};

ll cross(Point a, Point b) {
    return a.x * b.y - a.y * b.x;
}
Point tmp;
const int N = 2e3 + 5;
int n, ans[N], sz[N];
vector<int>G[N];
Point p[N];

bool operator < (Point a, Point b) {
    return cross(a - tmp, b - tmp) > 0;
}
int dfs(int u, int pre) {
    sz[u] = 1;
    for (int v : G[u]) if (v != pre) sz[u] += dfs(v, u);
    return sz[u];
}
void solve(int u, int pre, int l, int r) {
    tmp = p[l];
    for (int i = l + 1; i <= r; i++) if (p[i].y < tmp.y || (p[i].y == tmp.y && p[i].x < tmp.x)) {
        tmp = p[i];
        swap(p[i], p[l]);
    }
    sort(p + l + 1, p + r + 1);
    ans[p[l].id] = u;
    int last = l;
    for (int v : G[u]) if (v != pre) {
        solve(v, u, last + 1, last + sz[v]);
        last += sz[v];
    }
}
int main() {
    scanf("%d", &n);
    for (int i = 0, u, v; i < n - 1; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        p[i].input();
        p[i].id = i;
    }
    dfs(1, -1);
    solve(1, -1, 1, n);
    for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=(b); i++)
#define per(i,a,b) for (int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;

const int maxn = 1505;
struct point { int x, y, id; } p[maxn];
int sz[maxn], ans[maxn], n, a, b;
vector<int> e[maxn];

void dfs(int u, int fa) {
	sz[u] = 1;
	for (auto v : e[u])
		if (v != fa) dfs(v, u), sz[u] += sz[v];
}

ll cross(point p, point a, point b) {
	return 1ll * (a.x - p.x) * (b.y - p.y) - 1ll * (b.x - p.x) * (a.y - p.y);
}

bool cmp(point a, point b) {
	return cross(p[0], a, b) < 0;
}

void solve(int u, int fa, int l, int r) {
	int cur = l;
	rep (i, l + 1, r)
		if (p[i].y < p[cur].y || p[i].y == p[cur].y && p[i].x < p[cur].x) cur = i;
	p[0] = p[cur];
	sort(p+l+1, p+r+1, cmp);
	ans[p[l].id] = u;
	int last = l;
	for (auto v : e[u])
		if (v != fa) {
			solve(v, u, last + 1, last + sz[v]);
			last += sz[v];
		}
}

int main() {
	scanf("%d", &n);
	rep (i, 1, n - 1) {
		scanf("%d%d", &a, &b);
		e[a].push_back(b);
		e[b].push_back(a);
	}
	rep (i, 1, n) scanf("%d%d", &p[i].x, &p[i].y), p[i].id = i;
	dfs(1, 0); solve(1, 0, 1, n);
	rep (i, 1, n) printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

struct Point {
    ll x, y, id;
    void input () {
        scanf ("%I64d%I64d", &x, &y);
    }
    Point(ll x = 0, ll y = 0, ll id = 0) :x(x), y(y), id(id) {}
    Point operator - (const Point &b) const {
        return Point (x - b.x, y - b.y);
    }
};

ll cross(Point a, Point b) {
    return a.x * b.y - a.y * b.x;
}
Point tmp;
const int N = 2e3 + 5;
int n, ans[N], sz[N];
vector<int>G[N];
Point p[N];

bool operator < (Point a, Point b) {
    return cross(a - tmp, b - tmp) > 0;
}
int dfs(int u, int pre) {
    sz[u] = 1;
    for (int v : G[u]) if (v != pre) sz[u] += dfs(v, u);
    return sz[u];
}
void solve(int u, int pre, int l, int r) {
    tmp = p[l];
    for (int i = l + 1; i <= r; i++) if (p[i].y < tmp.y || (p[i].y == tmp.y && p[i].x < tmp.x)) tmp = p[i];
    sort(p + l + 1, p + r + 1);
    ans[p[l].id] = u;
    int last = l;
    for (int v : G[u]) if (v != pre) {
        solve(v, u, last + 1, last + sz[v]);
        last += sz[v];
    }
}
int main() {
    scanf("%d", &n);
    for (int i = 0, u, v; i < n - 1; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i = 1; i <= n; i++) {
        p[i].input();
        p[i].id = i;
    }
    dfs(1, -1);
    solve(1, -1, 1, n);
    for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
}


#include<iostream>
#include<algorithm>
#include<vector>
#include<utility>
#include<numeric>

using namespace std;

typedef long long ll;

#define F first.first
#define S first.second
#define ID second
#define Point pair<pair<int, int>, int>

const int MAXN = 1500 + 10;

int n, sz[MAXN], ans[MAXN];
vector<int>	adj[MAXN];
Point g;

bool cmp(Point a, Point b){return a.F < b.F;}
bool cmp2(Point a, Point b){return ll(a.F - g.F) * (b.S - g.S) - ll(a.S - g.S) * (b.F - g.F) < 0;}

void dfs(int v, int p = -1){
	sz[v] = 1;
	for (int u:adj[v])
		if (u^p)
			dfs(u, v), sz[v] += sz[u];
}

vector<Point>	gec;
void solve(int v, vector<Point> vec, int p = -1){
	ans[vec[0].ID] = v;
	g = vec[0];
	sort(vec.begin() + 1, vec.end(), cmp2);

	int l = 1;
	for (int u:adj[v])
		if (u^p){
			gec.assign(vec.begin() + l, vec.begin() + l + sz[u]);
			solve(u, gec, v);
			l += sz[u];
		}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 0; i < n - 1; i++){
		int u, v;	cin >> u >> v, u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dfs(0);

	vector<Point>	vec(n);
	for (int i = 0; i < n; i++)	cin >> vec[i].F >> vec[i].S, vec[i].ID = i;
	sort(vec.begin(), vec.end(), cmp);
	solve(0, vec);
	for (int i = 0; i < n; i++)
		printf("%d ", ans[i] + 1);
	printf("\n");
	return 0;
}


#include<iostream>
#include<algorithm>
#include<vector>
#include<utility>
#include<numeric>

using namespace std;

typedef long long ll;

#define F first.first
#define S first.second
#define ID second
#define Point pair<pair<int, int>, int>

const int MAXN = 1500 + 10;

int n, sz[MAXN], ans[MAXN];
vector<int>	adj[MAXN];
Point g;

bool cmp(Point a, Point b){return a.F < b.F;}
bool cmp2(Point a, Point b){return ll(a.F - g.F) * (b.S - g.S) - ll(a.S - g.S) * (b.F - g.F);}

void dfs(int v, int p = -1){
	sz[v] = 1;
	for (int u:adj[v])
		if (u^p)
			dfs(u, v), sz[v] += sz[u];
}

vector<Point>	gec;
void solve(int v, vector<Point> vec, int p = -1){
	ans[vec[0].ID] = v;
	g = vec[0];
	sort(vec.begin() + 1, vec.end(), cmp2);

	int l = 1;
	for (int u:adj[v])
		if (u^p){
			gec.assign(vec.begin() + l, vec.begin() + l + sz[u]);
			solve(u, gec, v);
			l += sz[u];
		}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 0; i < n - 1; i++){
		int u, v;	cin >> u >> v, u--, v--;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dfs(0);

	vector<Point>	vec(n);
	for (int i = 0; i < n; i++)	cin >> vec[i].F >> vec[i].S, vec[i].ID = i;
	sort(vec.begin(), vec.end(), cmp);
	solve(0, vec);
	for (int i = 0; i < n; i++)
		printf("%d ", ans[i] + 1);
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

#define I inline
#define ri register int
#define int long long
#define ll long long
#define ull unsigned long long
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define rep(i,a,b) for(ri i=(a);i<=(b);++i)
#define dow(i,a,b) for(ri i=(a);i>=(b);--i)
#define go(i,u) for(ri i=lnk[u];i;i=nxt[i])
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define vec vector
#define que queue
#define pb push_back
#define lowbit(x) (x&(-x))
#define mem(f,x) memset(f,x,sizeof(f))

I int gi(){
	int x=0,f=0;char ch=getchar();
	while(!isdigit(ch)){f|=ch=='-',ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48,ch=getchar();}
	return f?-x:x;
}

I void pi(int x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)pi(x/10);
	putchar(x%10+48);
}
I void pib(int x){pi(x);putchar(' ');}
I void pin(int x){pi(x);putchar('\n');}

const int N = 1510,M = N<<1;

int lnk[N],nxt[M],to[M],ec;
I void add(int u,int v){to[++ec]=v,nxt[ec]=lnk[u],lnk[u]=ec;}

struct point{
	int x,y,id;
}p[N],pp[N],poi;

int cnt,n,lst[N],ans[N],sz[N];

bool cmp(point a,point b){
	int ax=a.x-poi.x,ay=a.y-poi.y,bx=b.x-poi.x,by=b.y-poi.y;
	if(ax>=0&&bx<=0)return 1;
	if(ax<=0&&bx>=0)return 0;
	return (ax*by>bx*ay);
}

void predfs(int u,int Fa){
	sz[u]=1;
	go(i,u){
		int v=to[i];if(v==Fa)continue;
		predfs(v,u);
		sz[u]+=sz[v];
	}
}

void dfs(int l,int r,int u,int Fa){
	int mi=l;
	rep(i,l+1,r)
		if(p[i].y<p[mi].y||(p[i].y==p[mi].y&&p[i].x<p[mi].x))mi=i;
	swap(p[l],p[mi]);
	ans[p[l].id]=u;
	poi=p[l];
	sort(p+l+1,p+r+1,cmp);
	int now=l+1;
	go(i,u){
		int v=to[i];if(v==Fa)continue;
		dfs(now,now+sz[v]-1,v,u);
		now+=sz[v];
	}
}
signed main(){
	n=gi();
	rep(i,1,n-1){
		int u=gi(),v=gi();
		add(u,v);add(v,u);
	}
	rep(i,1,n)
		p[i].x=gi(),p[i].y=gi(),p[i].id=i;
	predfs(1,1);
	dfs(1,n,1,1);
	rep(i,1,n-1)pib(ans[i]);pin(ans[n]);
}


#include<bits/stdc++.h>
using namespace std;
int sz[1550],ans[1550];
pair<pair<int,int>,int> key;
vector<int> g[1550];
vector<pair<pair<int,int>,int> > d;
bool cmp(pair<pair<int,int>,int> a,pair<pair<int,int>,int> b)
{
	long long aa=(long long)(a.first.second-key.first.second)*(long long)(b.first.first-key.first.first) ,bb=(long long)(b.first.second-key.first.second)*(long long)(a.first.first-key.first.first);
	if (a==key) return true; if (b==key) return false; if (aa!=bb) return aa<bb; return a.first.second<b.first.second;
}
int dfs(int v,int par)
{
	sz[v]=1;
	for (int i=0; i<g[v].size(); i++) if (g[v][i]!=par) sz[v]+=dfs(g[v][i],v);
	return sz[v];
}
void dfs2(vector<pair<pair<int,int>,int>> v, int root,int par )
{
	pair<pair<int,int>,int> pii={{1e9+7,1e9+7},1e9};
	for (int i=0;i<v.size();i++) pii=min(pii,v[i]);
	ans[pii.second]=root+1;int start=1;key=pii; sort(v.begin(),v.end(),cmp);
	for (int i=0;i<g[root].size();i++)
	if (g[root][i]!=par)
	{
		vector<pair<pair<int,int>,int>> vv;
		int j;
		for (j=start;j<sz[g[root][i]]+start;j++) vv.push_back(v[j]);
		start=j;
		dfs2(vv,g[root][i],root);
	}
	return ;
}
int main()
{
	ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0),cerr<<"In The NAME OF GOD"<<endl;
	int n,a,b;
	cin>>n;
	for (int i=0; i<n-1; i++) cin>>a>>b,a--,b--,g[a].push_back(b),g[b].push_back(a);
	for (int i=0; i<n; i++) cin>>a>>b,d.push_back({{a,b},i});
	dfs(0,-1);
	dfs2(d,0,-1);
	for (int i=0;i<n;i++) cout<<ans[i]<<" ";
	return 0;
}


//Karol Kaszuba

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef pair<LL, LL> PII;
typedef double D;
typedef long double LD;
typedef vector<PII> VII;
typedef unordered_set<int> USI;
typedef unordered_set<LL> USLL;

#define FOR(i,x,y) for(auto i=(x);i<=(y);++i)
#define REP(i,x) FOR(i,0,(x)-1)
#define FORD(i,x,y) for(auto i=(x);i>=(y);--i)
#define VAR(i,c) __typeof(c) i=(c)
#define FORE(i,c) for(VAR(i,(c).begin());i!=(c).end();++i)
#define SIZE(c) (int)((c).size())
#define ALL(c) (c).begin(),(c).end()
#define PB push_back
#define EB emplace_back
#define IN insert
#define ER erase
#define MP make_pair
#define ST first
#define ND second
#define IOSYNC ios_base::sync_with_stdio(0)
#define FREOPEN(f) freopen(f, "r", stdin),freopen(f, "w", stdout)

struct node
{
	VI v;
	int parent;
	int subtree;

	VII punkty;
	PII przypisany;
	//PII kierunek;
} tab[2000];

void dfs(int a)
{
	tab[a].subtree = 1;
	int pos = 0, s = SIZE(tab[a].v);
	while(pos < s)
	{
		int b = tab[a].v[pos];
		if(b == tab[a].parent)
		{
			swap(tab[a].v[pos], tab[a].v[s - 1]);
			tab[a].v.pop_back();
			s--;
		}
		else
		{
			tab[b].parent = a;
			dfs(b);
			tab[a].subtree += tab[b].subtree;
			pos++;
		}
	}
}

PII obroc(PII a)
{
	return MP(a.ND, -a.ST);
}

void srotoczka(VII &v, PII pocz)//, PII kier)
{
	function<bool(PII, PII)> dis_comp = [&pocz](PII a, PII b){return (a.ST - pocz.ST) * (b.ND - pocz.ND) < (a.ND - pocz.ND) * (b.ST - pocz.ST);};
	REP(i, SIZE(v))
	{
		if(v[i] == pocz)
		{
			swap(v[i], v[SIZE(v) - 1]);
			v.pop_back();
			break;
		}
	}
	sort(ALL(v), dis_comp);
}

void solve(int a)
{
	srotoczka(tab[a].punkty, tab[a].przypisany);//, tab[a].kierunek);
	int pos = 0;

	for(int b : tab[a].v)
	{
		int s = tab[b].subtree;
		FOR(i, pos, pos + s - 1)
			tab[b].punkty.PB(tab[a].punkty[i]);
		tab[b].przypisany = tab[a].punkty[pos];
		//tab[b].kierunek = obroc(MP(tab[b].przypisany - tab[a].przypisany.ST, tab[b].przypisany - tab[a].przypisany.ND));
		solve(b);
		pos += s;
	}
}

void jebaj()
{
	int n;
	cin >> n;
	REP(i, n - 1)
	{
		int a, b;
		cin >> a >> b;
		tab[a].v.PB(b);
		tab[b].v.PB(a);
	}
	dfs(1);
	VII v, pier;
	REP(i, n)
	{
		LL a, b;
		cin >> a >> b;
		v.EB(a, b);
		pier.EB(a, b);
	}
	sort(ALL(v));
	tab[1].punkty = v;
	tab[1].przypisany = v[0];
	//tab[1].kierunek = MP(1, 0);

	solve(1);

	map<PII, int> mapka;
	FOR(i, 1, n)
	{
		mapka[tab[i].przypisany] = i;
	}
	REP(i, n)
		cout << mapka[pier[i]] << " ";
	cout << "\n";

}

int main()
{
	IOSYNC;
	int t = 1;
	//cin >> t;

	REP(i, t)
	{
		jebaj();
	}
}


#include <bits/stdc++.h>
#define base 1000000007LL
#define ll long long
#define ld long long
#define X first
#define Y second
#define pb push_back
#define EPS 1e-9
#define all(a) (a).begin(), (a).end()
#define sz(a) int((a).size())
#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i,a,b) for (int i = (a); i <= (b); i++)
#define FORE(i,a,b) for (int i = (a); i >= (b); i--)
#define FORALL(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
using namespace std;
typedef pair<int, int> II;
typedef pair<II, int> III;

struct point
{
    ll x, y;
    int cs;
    point(ll x = 0, ll y = 0) {
        this->x = x;
        this->y = y;
    }
    point operator + (const point& a) const { return point(x+a.x, y+a.y); }
    point operator - (const point& a) const { return point(x-a.x, y-a.y); }
    point operator * (double k) const { return point(x*k, y*k); }
    point operator / (double k) const { return point(x/k, y/k); }
    bool operator== (point& p) {
        return p.x == x && p.y == y;
    }
    bool operator< (const point &p) const {
        if (y == p.y) return x < p.x;
        return y < p.y;
    }
    point rotate(double alpha) {
        return point(x * cos(alpha) - y * sin(alpha), x * sin(alpha) + y * cos(alpha));
    }
} p[1510], pivot, origin;

int d[1510], n, res[1510];
vector<int> a[1510];

ll crossProduct(point a, point b, point c)
{
    point u = b-a;
    point v = c-a;
    return u.x*v.y - u.y*v.x;
}

bool cmp(point a, point b)
{
    point first = a - pivot;
    point second = b - pivot;
    if (first.y == 0 && second.y == 0 && first.x * second.x <= 0)
        return first.x > second.x;
    if (first.y == 0 && first.x >= 0 && second.y != 0)
        return true;
    if (second.y == 0 && second.x >= 0 && first.y != 0)
        return false;
    if (first.y * second.y < 0)
        return first.y > second.y;
    ll cp = crossProduct(origin, first, second);
    return cp > 0 || (cp == 0 && abs(first.x) < abs(second.x)) || (cp == 0 && abs(first.x) == abs(second.x) && abs(first.y) < abs(second.y));
}

void dfs(int u, int p)
{
    d[u] = 1;
    FOR(i,0,sz(a[u])-1) {
        int v = a[u][i];
        if (v == p) continue;
        dfs(v, u);
        d[u] += d[v];
    }
}

void solve(int l, int r, int u, int pa)
{
    int vt = l;
    FOR(i,l+1,r)
        if (p[i] < p[vt]) vt = i;
    swap(p[l], p[vt]);
    res[p[l].cs] = u;
    if (l == r) return;
    int lef = l+1;
    pivot = p[l];
    sort(p+lef, p+r+1, cmp);
    FOR(i,0,sz(a[u])-1) {
        int v = a[u][i];
        if (v == pa) continue;
        solve(lef, lef+d[v]-1, v, u);
        lef += d[v];
    }
}

int main()
{
    ios::sync_with_stdio(0);
    //freopen("inp.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    cin >> n;
    FOR(i,1,n-1) {
        int u, v;
        cin >> u >> v;
        a[u].pb(v);
        a[v].pb(u);
    }
    dfs(1, 0);
    FOR(i,1,n) {
        cin >> p[i].x >> p[i].y;
        p[i].cs = i;
    }
    solve(1,n,1,0);
    FOR(i,1,n) cout << res[i] << " ";
    return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

typedef long long ll;
const int MAXN = 1510, MAXM = 1510;
int n, m, sum;
int ans[MAXN], son[MAXN], last[MAXN];
struct Edge {
	int link, to;
} edge[MAXM << 1];
struct Node {
	int real;
	ll x, y;
} a[MAXN], tmp;

inline void add(int u, int v) {
	edge[++sum] = (Edge) { v, last[u] }, last[u] = sum;
	return;
}

inline int cmp1(Node a, Node b) {
	return a.x < b.x || a.x == b.x && a.y < b.y;
}

inline int cmp2(Node P1, Node P2) {
	return (tmp.x - P1.x) * (tmp.y - P2.y) < (tmp.x - P2.x) * (tmp.y - P1.y);
}

void dfs1(int x, int fa) {
	son[x] = 1;
	for (int i = last[x]; i; i = edge[i].to) {
		int y = edge[i].link;
		if (y == fa) continue;
		dfs1(y, x);
		son[x] += son[y];
	}
	return;
}

void dfs2(int x, int fa, int l, int r) {
	sort(a + l, a + r + 1, cmp1);
	// for (register int i = l; i <= r; ++i) printf("%d ",a[i].real); puts("");puts("");
	ans[a[l].real] = x, tmp = a[l];
	sort(a + l + 1, a + r + 1, cmp2);
	int L = l + 1;
	for (int i = last[x]; i; i = edge[i].to) {
		int y = edge[i].link;
		if (y == fa) continue;
		dfs2(y, x, L, L + son[y] - 1), L += son[y];
	}
	return;
}

int main() {
	scanf("%d", &n);
	for (register int i = 1; i < n; ++i) {
		int u, v; scanf("%d%d", &u, &v);
		add(u, v), add(v, u);
	}
	for (register int i = 1; i <= n; ++i) { scanf("%lld%lld", &a[i].x, &a[i].y); a[i].real = i; }
	dfs1(1, 0);
	dfs2(1, 0, 1, n);
	for (register int i = 1; i < n; ++i) printf("%d ", ans[i]);
	printf("%d\n", ans[n]);
	return 0;
}


#include<bits/stdc++.h>

#define x first
#define y second
#define NAM KIM
#define pb push_back
#define sq(x) ((x)*(x))
#define bit(x, y) (((x)>>(y))&1)
#define bctz(x) (__builtin_ctz(x))
#define bclz(x) (__builtin_clz(x))
#define bclzl(x) (__builtin_clzll(x))
#define bctzl(x) (__builtin_ctzl(x))
#define bpt(x) (__builtin_popcount(x))
#define bptl(x) (__builtin_popcountll(x))
#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;
typedef double DO;
typedef long double LD;
typedef long long INT;
typedef pair<int, int> pii;
typedef pair<pii, int> pi3;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

template <class T> inline void gn(T &x) {char c, sg=0; while(c=getchar(), (c>'9' || c<'0') && c!='-'); for((c=='-' ? sg=1, c=getchar() : 0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0'; if(sg) x=-x;}
template <class T1, class T2> inline void gn(T1 &x1, T2 &x2) {gn(x1), gn(x2);}
template <class T1, class T2, class T3> inline void gn(T1 &x1, T2 &x2, T3 &x3) {gn(x1, x2), gn(x3);}
template <class T1, class T2, class T3, class T4> inline void gn(T1 &x1, T2 &x2, T3 &x3, T4 &x4) {gn(x1, x2, x3), gn(x4);}
template <class T1, class T2, class T3, class T4, class T5> inline void gn(T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5) {gn(x1, x2, x3, x4), gn(x5);}

template <class T> inline void print(T x) {if(x<0) {putchar('-'); return print(-x);} if(x<10) {putchar('0'+x); return ;} print(x/10); putchar(x%10+'0');}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}
template <class T1, class T2, class T3, class T4, class T5> inline void print(T1 x1, T2 x2, T3 x3, T4 x4, T5 x5) {printsp(x1), printsp(x2), printsp(x3), printsp(x4), println(x5);}

int power(int a, int b, int m, int ans=1) {
	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;
	return ans;
}
const int inf=0x3f3f3f3f, mod=1000000007, MOD=998244353;
const INT INF=0x3f3f3f3f3f3f3f3fLL;
const DO pi=3.141592653589793, eps=1e-9;

//2-dimension point struct (int)
struct point {
	int x, y,id;
	point (int x=0, int y=0, int id=0) : x(x), y(y), id(id) {}
	point operator - (point a) {return point(x-a.x, y-a.y, id);}
	point operator + (point a) {return point(x+a.x, y+a.y, id);}
	point operator * (int a) {return point(x*a, y*a, id);}
	point conj() {return point(-y, x, id);}
	INT   operator ^ (point a) {return (INT)x*a.y-(INT)y*a.x;}
	INT   operator * (point a) {return (INT)x*a.x+(INT)y*a.y;}
	int pos() {return y>0 || y==0 && x>=0;}
	bool operator < (const point &a) const {
		if (x!=a.x) return x<a.x;
		return y<a.y;
	}
	void input() {gn(x,y);}
	void print() {cout<<x<<' '<<y<<' '<<id<<endl;}
};

const int NN=1555;
VI adj[NN];
point p[NN];
int sz[NN],ans[NN];

inline void dfs(int u,int fa=0){
	sz[u]=1;
	for(int i=0,v; i<adj[u].size(); i++){
		v=adj[u][i];
		if(v==fa) continue;
		dfs(v,u);
		sz[u]+=sz[v];
	}
}

inline int sgn(INT a){return (a>0)-(a<0);}
point q;
inline bool cmp(point a,point b){
	return sgn(a-q^b-q)>0;
}

inline void _dfs(int u,int st,int fa=0){
	ans[u]=p[st].id;
	q=p[st];
	sort(p+st+1,p+st+sz[u],cmp);
	st++;
	for(int i=0,v; i<adj[u].size(); i++){
		v=adj[u][i];
		if(v==fa) continue;
		_dfs(v,st,u);
		st+=sz[v];
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
//	freopen("in.in", "w", stdout);
#endif
	int n;gn(n);
	for(int i=1,u,v; i<n; i++){
		gn(u,v);
		adj[u].pb(v);adj[v].pb(u);
	}
	dfs(1);
	for(int i=1; i<=n; i++) p[i].input(),p[i].id=i;
	sort(p+1,p+n+1);
	_dfs(1,1);
	for(int i=1; i<n; i++) printsp(ans[i]);println(ans[n]);
	return 0;
}


#include<bits/stdc++.h>

#define x first
#define y second
#define NAM KIM
#define pb push_back
#define sq(x) ((x)*(x))
#define bit(x, y) (((x)>>(y))&1)
#define bctz(x) (__builtin_ctz(x))
#define bclz(x) (__builtin_clz(x))
#define bclzl(x) (__builtin_clzll(x))
#define bctzl(x) (__builtin_ctzl(x))
#define bpt(x) (__builtin_popcount(x))
#define bptl(x) (__builtin_popcountll(x))
#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;
typedef double DO;
typedef long double LD;
typedef long long INT;
typedef pair<int, int> pii;
typedef pair<pii, int> pi3;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

template <class T> inline void gn(T &x) {char c, sg=0; while(c=getchar(), (c>'9' || c<'0') && c!='-'); for((c=='-' ? sg=1, c=getchar() : 0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0'; if(sg) x=-x;}
template <class T1, class T2> inline void gn(T1 &x1, T2 &x2) {gn(x1), gn(x2);}
template <class T1, class T2, class T3> inline void gn(T1 &x1, T2 &x2, T3 &x3) {gn(x1, x2), gn(x3);}
template <class T1, class T2, class T3, class T4> inline void gn(T1 &x1, T2 &x2, T3 &x3, T4 &x4) {gn(x1, x2, x3), gn(x4);}
template <class T1, class T2, class T3, class T4, class T5> inline void gn(T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5) {gn(x1, x2, x3, x4), gn(x5);}

template <class T> inline void print(T x) {if(x<0) {putchar('-'); return print(-x);} if(x<10) {putchar('0'+x); return ;} print(x/10); putchar(x%10+'0');}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}
template <class T1, class T2, class T3, class T4, class T5> inline void print(T1 x1, T2 x2, T3 x3, T4 x4, T5 x5) {printsp(x1), printsp(x2), printsp(x3), printsp(x4), println(x5);}

int power(int a, int b, int m, int ans=1) {
	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;
	return ans;
}
const int inf=0x3f3f3f3f, mod=1000000007, MOD=998244353;
const INT INF=0x3f3f3f3f3f3f3f3fLL;
const DO pi=3.141592653589793, eps=1e-9;

//2-dimension point struct (int)
struct point {
	int x, y,id;
	point (int x=0, int y=0, int id=0) : x(x), y(y), id(id) {}
	point operator - (point a) {return point(x-a.x, y-a.y, id);}
	point operator + (point a) {return point(x+a.x, y+a.y, id);}
	point operator * (int a) {return point(x*a, y*a, id);}
	point conj() {return point(-y, x, id);}
	INT   operator ^ (point a) {return (INT)x*a.y-(INT)y*a.x;}
	INT   operator * (point a) {return (INT)x*a.x+(INT)y*a.y;}
	int pos() {return y>0 || y==0 && x>=0;}
	bool operator < (const point &a) const {
		if (x!=a.x) return x<a.x;
		return y<a.y;
	}
	void input() {gn(x,y);}
	void print() {cout<<x<<' '<<y<<' '<<id<<endl;}
};

const int NN=1555;
VI adj[NN];
point p[NN];
int sz[NN],ans[NN];

inline void dfs(int u,int fa=0){
	sz[u]=1;
	for(int i=0,v; i<adj[u].size(); i++){
		v=adj[u][i];
		if(v==fa) continue;
		dfs(v,u);
		sz[u]+=sz[v];
	}
}

inline int sgn(INT a){return (a>0)-(a<0);}
point q;
inline bool cmp(point a,point b){
	return sgn(a-q^b-q)>0;
}

inline void _dfs(int u,int st,int fa=0){
	ans[p[st].id]=u;
	q=p[st];
	sort(p+st+1,p+st+sz[u],cmp);
	st++;
	for(int i=0,v; i<adj[u].size(); i++){
		v=adj[u][i];
		if(v==fa) continue;
		_dfs(v,st,u);
		st+=sz[v];
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
//	freopen("in.in", "w", stdout);
#endif
	int n;gn(n);
	for(int i=1,u,v; i<n; i++){
		gn(u,v);
		adj[u].pb(v);adj[v].pb(u);
	}
	dfs(1);
	for(int i=1; i<=n; i++) p[i].input(),p[i].id=i;
	sort(p+1,p+n+1);
	_dfs(1,1);
	for(int i=1; i<n; i++) printsp(ans[i]);println(ans[n]);
	return 0;
}


#include<bits/stdc++.h>

#define x first
#define y second
#define NAM KIM
#define pb push_back
#define sq(x) ((x)*(x))
#define sgn(a) ((a>eps)-(a<eps))
#define bit(x, y) (((x)>>(y))&1)
#define bctz(x) (__builtin_ctz(x))
#define bclz(x) (__builtin_clz(x))
#define bclzl(x) (__builtin_clzll(x))
#define bctzl(x) (__builtin_ctzl(x))
#define bpt(x) (__builtin_popcount(x))
#define bptl(x) (__builtin_popcountll(x))
#define PQ priority_queue<pii, vector<pii>, greater<pii> >

using namespace std;
typedef double DO;
typedef long double LD;
typedef long long INT;
typedef pair<int, int> pii;
typedef pair<pii, int> pi3;
typedef vector<int> VI;

template<typename T, typename U> inline void smin(T &a, const U &b) {if(a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if(a<b) a=b;}

template <class T> inline void gn(T &x) {char c, sg=0; while(c=getchar(), (c>'9' || c<'0') && c!='-'); for((c=='-' ? sg=1, c=getchar() : 0), x=0; c>='0' && c<='9'; c=getchar()) x=(x<<1)+(x<<3)+c-'0'; if(sg) x=-x;}
template <class T1, class T2> inline void gn(T1 &x1, T2 &x2) {gn(x1), gn(x2);}
template <class T1, class T2, class T3> inline void gn(T1 &x1, T2 &x2, T3 &x3) {gn(x1, x2), gn(x3);}
template <class T1, class T2, class T3, class T4> inline void gn(T1 &x1, T2 &x2, T3 &x3, T4 &x4) {gn(x1, x2, x3), gn(x4);}
template <class T1, class T2, class T3, class T4, class T5> inline void gn(T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5) {gn(x1, x2, x3, x4), gn(x5);}

template <class T> inline void print(T x) {if(x<0) {putchar('-'); return print(-x);} if(x<10) {putchar('0'+x); return ;} print(x/10); putchar(x%10+'0');}
template <class T> inline void println(T x) {print(x); putchar('\n');}
template <class T> inline void printsp(T x) {print(x); putchar(' ');}
template <class T1, class T2> inline void print(T1 x1, T2 x2) {printsp(x1), println(x2);}
template <class T1, class T2, class T3> inline void print(T1 x1, T2 x2, T3 x3) {printsp(x1), printsp(x2), println(x3);}
template <class T1, class T2, class T3, class T4> inline void print(T1 x1, T2 x2, T3 x3, T4 x4) {printsp(x1), printsp(x2), printsp(x3), println(x4);}
template <class T1, class T2, class T3, class T4, class T5> inline void print(T1 x1, T2 x2, T3 x3, T4 x4, T5 x5) {printsp(x1), printsp(x2), printsp(x3), printsp(x4), println(x5);}

int power(int a, int b, int m, int ans=1) {
	for (; b; b>>=1, a=1LL*a*a%m) if (b&1) ans=1LL*ans*a%m;
	return ans;
}
const int inf=0x3f3f3f3f, mod=1000000007, MOD=998244353;
const INT INF=0x3f3f3f3f3f3f3f3fLL;
const DO pi=3.141592653589793, eps=1e-9;

//2-dimension point struct (int)
struct point {
	int x, y,id;
	point (int x=0, int y=0, int id=0) : x(x), y(y), id(id) {}
	point operator - (point a) {return point(x-a.x, y-a.y, id);}
	point operator + (point a) {return point(x+a.x, y+a.y, id);}
	point operator * (int a) {return point(x*a, y*a, id);}
	point conj() {return point(-y, x, id);}
	INT   operator ^ (point a) {return (INT)x*a.y-(INT)y*a.x;}
	INT   operator * (point a) {return (INT)x*a.x+(INT)y*a.y;}
	int pos() {return y>0 || y==0 && x>=0;}
	INT nor() {return *this**this;}
	bool operator < (const point &a) const {
		if (x!=a.x) return x<a.x;
		return y<a.y;
	}
	void input() {gn(x,y);}
	void print() {cout<<x<<' '<<y<<' '<<id<<endl;}
};

const int NN=1555;
VI adj[NN];
point p[NN];
int sz[NN],ans[NN];

inline int dfs(int u,int fa=0){
	sz[u]=1;
	for(int i=0,v; i<adj[u].size(); i++){
		if((v=adj[u][i])==fa) continue;
		sz[v]=dfs(v,u);
		sz[u]+=sz[v];
	}
	return sz[u];
}

point q;
inline bool cmp(point a,point b){
	return (a-q^b-q)>0;
}

inline void _dfs(int u,int st,int fa=0){
	ans[u]=p[st].id;
	if(sz[u]==1) return;
	q=p[st];
	sort(p+st+1,p+st+sz[u],cmp);
	st++;
	for(int i=0,v; i<adj[u].size(); i++){
		if((v=adj[u][i])==fa) continue;
		_dfs(v,st,u);
		st+=sz[v];
	}
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
//	freopen("in.in", "w", stdout);
#endif
	int n;gn(n);
	for(int i=1,u,v; i<n; i++){
		gn(u,v);
		adj[u].pb(v);adj[v].pb(u);
	}
	dfs(1);
	for(int i=1; i<=n; i++) p[i].input(),p[i].id=i;
	sort(p+1,p+n+1);
	_dfs(1,1);
	for(int i=1; i<n; i++) printsp(ans[i]);println(ans[n]);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <queue>
#include <math.h>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <bitset>
#include <list>
#include <ctype.h>
#include <cassert>
#include <stack>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <ctime>
#include <functional>
#include <ctime>

using namespace std;

#define snd second
#define fst first
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define ld long double
#define pb push_back
#define left _left
#define right _right

const ld pi = 3.14159265359;

template<typename T>
T abs(T x) {
    return x > 0 ? x : -x;
}

template<typename T>
T sqr(T x) {
    return x * x;
}

template<typename T>
void chmin(T &x, T y) {
    x = min(x, y);
}

template<typename T>
void chmax(T &x, T y) {
    x = max(x, y);
}

template<typename U, typename V>
ostream &operator<<(ostream &s, const pair<U, V> &x) {
    s << "(" << x.fst << ", " << x.snd << ")";
    return s;
}

template<typename U>
ostream &operator<<(ostream &s, const vector<U> &x) {
    s << "[";
    bool was = false;
    for (auto it : x) {
        if (was) {
            s << ", ";
        }
        was = true;
        s << it;
    }
    s << "]";
    return s;
}

//-----------------------------------------------------------------------------

const int maxn = 1505;

vector<int> g[maxn];
int sz[maxn];
vector<int> ch[maxn];

void dfs(int v, int p = -1) {
    sz[v] = 1;
    for (int to : g[v]) {
        if (to == p) {
            continue;
        }

        ch[v].pb(to);
        dfs(to, v);
        sz[v] += sz[to];
    }
}

struct pt {
    ll x, y;
    int id;

    pt(ll _x = 0, ll _y = 0, int _id = 0) {
        x = _x, y = _y, id = _id;
    }

    ll operator ^ (const pt &o) const {
        return x * o.y - y * o.x;
    }

    pt operator - (const pt &o) {
        return pt(x - o.x, y - o.y);
    }

    bool operator < (const pt &o) const {
        return mp(x, y) < mp(o.x, o.y);
    }

    bool operator == (const pt &o) const {
        return mp(x, y) == mp(o.x, o.y);
    }
};

int ans[maxn];

void solve(vector<pt> a, int r) {
    pt o = *min_element(a.begin(), a.end());
    ans[o.id] = r;

    remove_if(a.begin(), a.end(), [&](const pt &p) {
        return p == o;
    });

    a.resize(a.size() - 1);

    for (auto &p : a) {
        p.x -= o.x;
        p.y -= o.y;
    }

    sort(a.begin(), a.end(), [&](const pt &u, const pt &v) {
        return (u ^ v) < 0;
    });

    int p = 0;
    for (int x : ch[r]) {
        vector<pt> c;
        for (int i = p; i < p + sz[x]; i++) {
            c.pb(a[i]);
        }
        solve(c, x);
        p += sz[x];
    }
}

int main() {
    srand(time(NULL));

    retry:

#ifdef LOCAL
    //gen();
    //cerr << 1 << endl;
    freopen("a.in", "r", stdin);
#else
    //freopen("fract.in", "r", stdin);
    //freopen("fract.out", "w", stdout);
#endif

    int n;
    cin >> n;

    for (int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v;
        g[u].pb(v);
        g[v].pb(u);
    }

    dfs(1);

    vector<pt> a;

    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a.pb(pt(x, y, i));
    }

    solve(a, 1);

    for (int i = 0; i < n; i++) {
        if (i) {
            cout << " ";
        }

        cout << ans[i];
    }

    return 0;
}


/// >>INOG
/// >>ALIREZANA

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define pp pop_back
#define mem(x,y) memset((x), y, sizeof (x))
#define _ ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define lb lower_bound
#define ub upper_bound
#define bs binary_search
#define smin(x, y) (x) = min((x), (y))
#define smax(x, y) (x) = max((x), (y))
#define fr first
#define sc second

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
const int M4 = 1e4+100, M5 = 1e5+100, M6 = 1e6+100, M7 = 1e7+100, M8 = 1e8+100, M9 = 1e9+100;

const int maxn = 1600;
typedef pair<pii, int> node;
node p[maxn];
vi adj[maxn];
int X, Y, ans[maxn], siz[maxn];

bool cmp(node a , node b)
{
    return (ll)(a.fr.sc - Y) * (b.fr.fr - X) < (ll)(b.fr.sc - Y) * (a.fr.fr - X);
}

bool mark[maxn];
void dfs(int v)
{
    mark[v] = 1;
    siz[v] = 1;
    for(auto u : adj[v])
    {
        if(!mark[u])
            dfs(u) , siz[v] += siz[u];
    }
}

void check(int v, int par, int l, int r)
{
    int t = l;
    for(int i = l+1; i <= r; i++)
        if(p[i].fr.sc < p[t].fr.sc || (p[i].fr.sc == p[t].fr.sc && p[i].fr.fr < p[t].fr.fr))
            t = i;
    if(t != l)
        swap(p[l], p[t]);
    ans[p[l].sc] = v;
    X = p[l].fr.fr, Y = p[l].fr.sc;
    sort(p+l+1, p+r+1, cmp);
    int pos = l+1;
    for(auto u : adj[v])
    {
        if(u == par)
            continue;
        check(u, v, pos, pos+siz[u]-1);
        pos += siz[u];
    }
}

int main()
{_
    int n;
    cin >> n;
    for(int i = 1; i < n; i++)
    {
        int v, u;
        cin >> v >> u;
        adj[v].pb(u), adj[u].pb(v);
    }
    dfs(1);
    for(int i = 1; i <= n; i++)
    {
        cin >> p[i].fr.fr >> p[i].fr.sc;
        p[i].sc = i;
    }
    mem(mark, 0);
    check(1, 0, 1, n);
    for(int i = 1; i <= n; i++)
        cout << ans[i] << ' ';
    return 0;
}


#include<bits/stdc++.h>
#define P(x,y) make_pair(x,y)
using namespace std;
const int MX=(1<<20);
typedef complex<long double> point;
#define sz(a) ((int)(a).size())
#define all(n) (n).begin(),(n).end()
#define EPS 1e-9
#define OO 1e9
#define X real()
#define Y imag()
#define vec(a,b) ((b)-(a))
#define polar(r,t) ((r)*exp(point(0,(t))))
#define angle(v) (atan2((v).Y,(v).X))
#define length(v) ((long double)hypot((v).Y,(v).X))
#define lengthSqr(v) (dot(v,v))
#define dot(a,b) ((conj(a)*(b)).real())
#define cross(a,b) ((conj(a)*(b)).imag())
#define rotate(v,t) (polar(v,t))
#define rotateabout(v,t,a)  (rotate(vec(a,v),t)+(a))
#define reflect(p,m) ((conj((p)/(m)))*(m))
#define normalize(p) ((p)/length(p))
#define same(a,b) (lengthSqr(vec(a,b))<EPS)
#define mid(a,b) (((a)+(b))/point(2,0))
#define perp(a) (point(-(a).Y,(a).X))
#define colliner pointOnLine
typedef long long ll;
struct cmp {
        point about;
        cmp(point c) {
                about = c;
        }
        bool operator()(const point& p, const point& q) const {
                double cr = cross(vec(about, p), vec(about, q));
                if (fabs(cr) < EPS)
                        return make_pair(p.Y, p.X) < make_pair(q.Y, q.X);
                return cr > 0;
        }
};

void sortAntiClockWise(vector<point>& pnts) {
        point mn(1 / 0.0, 1 / 0.0);
        for (int i = 0; i < sz(pnts); i++)
                if (make_pair(pnts[i].Y, pnts[i].X) < make_pair(mn.Y, mn.X))
                        mn = pnts[i];

        sort(all(pnts), cmp(mn));
}
map < pair < int , int > , int > hashy;
vector < point > P;
vector < int > v[MX];
int ans[MX];
void dfs(int x , int p){
    ans[hashy[{P.back().X , P.back().Y}]] = x;
    P.pop_back();
    for(auto nxt : v[x]){
        if(nxt == p) continue;
        dfs(nxt , x);
    }
}
int main(){
    int n;
    scanf("%d",&n);
    for(int j=1;j<n;j++){
        int a , b;
        scanf("%d %d",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    for(int j=1;j<=n;j++){
        int x , y;
        scanf("%d %d",&x,&y);
        hashy[{x , y}] = j;
        P.push_back(point(x , y));
    }
    sortAntiClockWise(P);
    reverse(P.begin() , P.end());
    dfs(1 , -1);
    for(int j=1;j<=n;j++) cout<<ans[j]<<endl;
}


#include<bits/stdc++.h>
#define P(x,y) make_pair(x,y)
using namespace std;
const int MX=(1<<20);
typedef complex<long double> point;
#define sz(a) ((int)(a).size())
#define all(n) (n).begin(),(n).end()
#define EPS 1e-9
#define OO 1e9
#define X real()
#define Y imag()
#define vec(a,b) ((b)-(a))
#define polar(r,t) ((r)*exp(point(0,(t))))
#define angle(v) (atan2((v).Y,(v).X))
#define length(v) ((long double)hypot((v).Y,(v).X))
#define lengthSqr(v) (dot(v,v))
#define dot(a,b) ((conj(a)*(b)).real())
#define cross(a,b) ((conj(a)*(b)).imag())
#define rotate(v,t) (polar(v,t))
#define rotateabout(v,t,a)  (rotate(vec(a,v),t)+(a))
#define reflect(p,m) ((conj((p)/(m)))*(m))
#define normalize(p) ((p)/length(p))
#define same(a,b) (lengthSqr(vec(a,b))<EPS)
#define mid(a,b) (((a)+(b))/point(2,0))
#define perp(a) (point(-(a).Y,(a).X))
#define colliner pointOnLine
typedef long long ll;
struct cmp {
        point about;
        cmp(point c) {
                about = c;
        }
        bool operator()(const point& p, const point& q) const {
                double cr = cross(vec(about, p), vec(about, q));
                if (fabs(cr) < EPS)
                        return make_pair(p.Y, p.X) < make_pair(q.Y, q.X);
                return cr > 0;
        }
};

void sortAntiClockWise(vector<point>& pnts) {
        point mn(1 / 0.0, 1 / 0.0);
        for (int i = 0; i < sz(pnts); i++)
                if (make_pair(pnts[i].Y, pnts[i].X) < make_pair(mn.Y, mn.X))
                        mn = pnts[i];

        sort(all(pnts), cmp(mn));
}
map < pair < int , int > , int > hashy;
vector < point > P;
vector < int > v[MX];
int ans[MX] , sz[MX];
void Pdfs(int x , int p){
    sz[x] = 1;
    for(auto nxt : v[x]){
        if(nxt == p) continue;
        Pdfs(nxt , x);
        sz[x] += sz[nxt];
    }
}
void dfs(int x , int p , vector < point > P){
    sortAntiClockWise(P);
    ans[hashy[{P[0].X , P[0].Y}]] = x;
    int it = 1;
    for(auto nxt : v[x]){
        if(nxt == p) continue;
        vector < point > nP;
        while(nP.size() < sz[nxt]) nP.push_back(P[it++]);
        dfs(nxt , x , nP);
    }
}
int main(){
    int n;
    scanf("%d",&n);
    for(int j=1;j<n;j++){
        int a , b;
        scanf("%d %d",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    for(int j=1;j<=n;j++){
        int x , y;
        scanf("%d %d",&x,&y);
        hashy[{x , y}] = j;
        P.push_back(point(x , y));
    }
    Pdfs(1 , -1);
    dfs(1 , -1 , P);
    for(int j=1;j<=n;j++) cout<<ans[j]<<endl;
}


#include<bits/stdc++.h>
typedef long long ll;
inline ll read() {ll x = 0;char ch = getchar(), w = 1;while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();
}return x * w;}
void write(ll x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0');}
inline void writeln(ll x) {write(x);puts("");}
using namespace std;

const int N = 2100;

int n, siz[N];
vector<int> g[N];
struct T {
	int x, y, i;
	bool operator <(const T b) {
		if(x == b.x) return y < b.y;
		return x < b.x;
	}
}a[N];
void dfs(int x, int F) {
	siz[x] = 1;
	for(int y : g[x]) if(y != F) {
		dfs(y, x);
		siz[x] += siz[y];
	}
}
int ans[N], p;
bool cmp(T x, T y) {
	ll x1 = x.x - a[p].x;
	ll y1 = x.y - a[p].y;
	ll x2 = y.x - a[p].x;
	ll y2 = y.y - a[p].y;
	return x1 * y2 - y1 * x2 < 0;
}
void cal(int x, int l, int r) {

	p = l;
	for(int i = l; i <= r; ++i)
		if(a[i] < a[p]) p = i;
	ans[x] = a[p].i;
	swap(a[p], a[l]);
	sort(a + l, a + r + 1, cmp);
	int pos = l + 1;
	for(int y : g[x]) if(!ans[y]) {
		cal(y, pos, pos + siz[y] - 1);
		pos += siz[y];
	}
}
int main() {
	n = read();
	for(int i = 1; i < n; ++i) {
		int x = read(), y = read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].i = i;
	dfs(1, 0);
	cal(1, 1, n);
	for(int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
inline ll read() {ll x = 0;char ch = getchar(), w = 1;while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();
}return x * w;}
void write(ll x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0');}
inline void writeln(ll x) {write(x);puts("");}
using namespace std;

const int N = 2100;

int n, siz[N];
vector<int> g[N];
struct T {
	int x, y, i;
	bool operator <(const T b) {
		if(x == b.x) return y < b.y;
		return x < b.x;
	}
}a[N];
void dfs(int x, int F) {
	siz[x] = 1;
	for(int y : g[x]) if(y != F) {
		dfs(y, x);
		siz[x] += siz[y];
	}
}
int ans[N], p;
bool cmp(T x, T y) {
	ll x1 = x.x - a[p].x;
	ll y1 = x.y - a[p].y;
	ll x2 = y.x - a[p].x;
	ll y2 = y.y - a[p].y;
	return x1 * y2 - y1 * x2 < 0;
}
void cal(int x, int l, int r) {

	p = l;
	for(int i = l; i <= r; ++i)
		if(a[i] < a[p]) p = i;
	ans[x] = a[p].i;
	swap(a[p], a[l]);
	sort(a + l + 1, a + r + 1, cmp);
	int pos = l + 1;
	for(int y : g[x]) if(!ans[y]) {
		cal(y, pos, pos + siz[y] - 1);
		pos += siz[y];
	}
}
int main() {
	n = read();
	for(int i = 1; i < n; ++i) {
		int x = read(), y = read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].i = i;
	dfs(1, 0);
	cal(1, 1, n);
	for(int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
inline ll read() {ll x = 0;char ch = getchar(), w = 1;while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();
}return x * w;}
void write(ll x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0');}
inline void writeln(ll x) {write(x);puts("");}
using namespace std;

const int N = 210000;

int n, siz[N];
vector<int> g[N];
struct T {
	int x, y, i;
	bool operator <(const T b) {
		if(x == b.x) return y < b.y;
		return x < b.x;
	}
}a[N],z;
void dfs(int x, int F) {
	siz[x] = 1;
	for(int y : g[x]) if(y != F) {
		dfs(y, x);
		siz[x] += siz[y];
	}
}
int ans[N], p;
bool cmp(T x, T y) {
	ll x1 = x.x - z.x;
	ll y1 = x.y - z.y;
	ll x2 = y.x - z.x;
	ll y2 = y.y - z.y;
	return x1 * y2 - y1 * x2 < 0;
}
void cal(int x, int l, int r, int fa) {

	p = l;
	for(int i = l; i <= r; ++i)
		if(a[i] < a[p]) p = i;
	ans[a[p].i] = x;
	if(l == r) return;
	swap(a[p], a[l]);
	z = a[l];
	sort(a + l + 1, a + r + 1, cmp);
	int pos = l + 1;
	for(int y : g[x]) if(y != fa) {
		cal(y, pos, pos + siz[y] - 1, x);
		pos += siz[y];
	}
}
int main() {
	n = read();
	for(int i = 1; i < n; ++i) {
		int x = read(), y = read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].i = i;
	dfs(1, 0);
	cal(1, 1, n, 0);
	for(int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
inline ll read() {ll x = 0;char ch = getchar(), w = 1;while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();
}return x * w;}
void write(ll x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0');}
inline void writeln(ll x) {write(x);puts("");}
using namespace std;

const int N = 2100;

int n, siz[N];
vector<int> g[N];
struct T {
	int x, y, i;
	bool operator <(const T b) {
		if(x == b.x) return y < b.y;
		return x < b.x;
	}
}a[N];
void dfs(int x, int F) {
	siz[x] = 1;
	for(int y : g[x]) if(y != F) {
		dfs(y, x);
		siz[x] += siz[y];
	}
}
int ans[N];
void cal(int x, int l, int r) {
	int p = l;
	for(int i = l; i <= r; ++i)
		if(a[i] < a[p]) p = i;
	ans[x] = a[p].i;
	swap(a[p], a[l]);
	int pos = l + 1;
	for(int y : g[x]) if(!ans[y]) {
		cal(y, pos, pos + siz[y] - 1);
		pos += siz[y];
	}
}
int main() {
	n = read();
	for(int i = 1; i < n; ++i) {
		int x = read(), y = read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].i = i;
	dfs(1, 0);
	cal(1, 1, n);
	for(int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
inline ll read() {ll x = 0;char ch = getchar(), w = 1;while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();
}return x * w;}
void write(ll x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0');}
inline void writeln(ll x) {write(x);puts("");}
using namespace std;

const int N = 2100;

int n, siz[N];
vector<int> g[N];
struct T {
	int x, y, i;
	bool operator <(const T b) {
		if(x == b.x) return y < b.y;
		return x < b.x;
	}
}a[N];
void dfs(int x, int F) {
	siz[x] = 1;
	for(int y : g[x]) if(y != F) {
		dfs(y, x);
		siz[x] += siz[y];
	}
}
int ans[N], p;
bool cmp(T x, T y) {
	ll x1 = x.x - a[p].x;
	ll y1 = x.y - a[p].y;
	ll x2 = y.x - a[p].x;
	ll y2 = y.y - a[p].y;
	return x1 * y2 - y1 * x2 < 0;
}
void cal(int x, int l, int r) {

	p = l;
	for(int i = l; i <= r; ++i)
		if(a[i] < a[p]) p = i;
	ans[x] = a[p].i;
	if(l == r) return;
	swap(a[p], a[l]);
	sort(a + l + 1, a + r + 1, cmp);
	int pos = l + 1;
	for(int y : g[x]) if(!ans[y]) {
		cal(y, pos, pos + siz[y] - 1);
		pos += siz[y];
	}
}
int main() {
	n = read();
	for(int i = 1; i < n; ++i) {
		int x = read(), y = read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].i = i;
	dfs(1, 0);
	cal(1, 1, n);
	for(int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
inline ll read() {ll x = 0;char ch = getchar(), w = 1;while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();
}return x * w;}
void write(ll x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0');}
inline void writeln(ll x) {write(x);puts("");}
using namespace std;

const int N = 210000;

int n, siz[N];
vector<int> g[N];
struct T {
	int x, y, i;
	bool operator <(const T b) {
		if(x == b.x) return y < b.y;
		return x < b.x;
	}
}a[N];
void dfs(int x, int F) {
	siz[x] = 1;
	for(int y : g[x]) if(y != F) {
		dfs(y, x);
		siz[x] += siz[y];
	}
}
int ans[N], p;
bool cmp(T x, T y) {
	ll x1 = x.x - a[p].x;
	ll y1 = x.y - a[p].y;
	ll x2 = y.x - a[p].x;
	ll y2 = y.y - a[p].y;
	return x1 * y2 - y1 * x2 < 0;
}
void cal(int x, int l, int r, int fa) {

	p = l;
	for(int i = l; i <= r; ++i)
		if(a[i] < a[p]) p = i;
	ans[a[p].i] = x;
	if(l == r) return;
	swap(a[p], a[l]);
	sort(a + l + 1, a + r + 1, cmp);
	int pos = l + 1;
	for(int y : g[x]) if(y != fa) {
		cal(y, pos, pos + siz[y] - 1, x);
		pos += siz[y];
	}
}
int main() {
	n = read();
	for(int i = 1; i < n; ++i) {
		int x = read(), y = read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].i = i;
	dfs(1, 0);
	cal(1, 1, n, 0);
	for(int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
inline ll read() {ll x = 0;char ch = getchar(), w = 1;while(ch < '0' || ch > '9') {
if(ch == '-') w = -1;ch = getchar();}while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();
}return x * w;}
void write(ll x) {if(x < 0) putchar('-'), x = -x;if(x > 9) write(x / 10);putchar(x % 10 + '0');}
inline void writeln(ll x) {write(x);puts("");}
using namespace std;

const int N = 2100;

int n, siz[N];
vector<int> g[N];
struct T {
	int x, y, i;
	bool operator <(const T b) {
		if(x == b.x) return y < b.y;
		return x < b.x;
	}
}a[N], z;
void dfs(int x, int F) {
	siz[x] = 1;
	for(int y : g[x]) if(y != F) {
		dfs(y, x);
		siz[x] += siz[y];
	}
}
int ans[N], p;
bool cmp(T x, T y) {
	ll x1 = x.x - z.x;
	ll y1 = x.y - z.y;
	ll x2 = y.x - z.x;
	ll y2 = y.y - z.y;
	return x1 * y2 - y1 * x2 < 0;
}
void cal(int x, int l, int r) {

	p = l;
	for(int i = l; i <= r; ++i)
		if(a[i] < a[p]) p = i;
	ans[x] = a[p].i;
	if(l == r) return;
	z = a[p];
	swap(a[p], a[l]);
	sort(a + l + 1, a + r + 1, cmp);
	int pos = l + 1;
	for(int y : g[x]) if(!ans[y]) {
		cal(y, pos, pos + siz[y] - 1);
		pos += siz[y];
	}
}
int main() {
	n = read();
	for(int i = 1; i < n; ++i) {
		int x = read(), y = read();
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i = 1; i <= n; ++i) a[i].x = read(), a[i].y = read(), a[i].i = i;
	dfs(1, 0);
	cal(1, 1, n);
	for(int i = 1; i <= n; ++i)
		printf("%d ", ans[i]);
	return 0;
}


// whats 1000 minus 7 ?
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline string get(){char ch[1000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 60;
//#define int long long
#define x first
#define y second
#define endl "\n"
#define mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef long long ll;
const int maxn = 1e6 + 100;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e18 + 100;
int n;
vector<int> g[maxn];
pair<pii,int> p[maxn];
int sz[maxn];
int X , Y;
int res[maxn];
ld value[maxn];
inline void getsz(int v = 0 , int pr = -1)
{
    sz[v] = 1;
    for (auto u : g[v])
    {
        if (u == pr) continue;
        getsz(u,v);
        sz[v] += sz[u];
    }

}
inline bool cmp(const pair<pii,int> &a , const pair<pii,int> &b)
{
    return value[a.second] < value[b.second];
}
inline void solve(int v , int l , int r , int pr = -1)
{
    int need = sz[v] - 1;
    X = p[v].x.x , Y = p[v].x.y;
    for (int pt = l + 1 ; pt <= l + need ; pt ++)
    {
        value[p[pt].second] = atan2(p[pt].x.y - Y , p[pt].x.x - X);
    }
    sort(p+l+1,p+l+need+1,cmp);
    int cur = l + 1;
    res[p[l].y] = v + 1;
    int id = 0;
    while (cur <= l + need)
    {
        if (g[v][id] == pr)
        {
            id ++;
        }
        solve(g[v][id],cur,cur+sz[g[v][id]]-1,v);
        cur = cur + sz[g[v][id]];
        id ++;
    }
}
int32_t main()
{
    n = in();
    for (int i = 0 ; i < n - 1 ; i ++)
    {
        int v = in()  - 1, u = in() - 1;
        g[v].push_back(u) , g[u].push_back(v);
    }
    for (int i = 0 ; i < n ; i ++) p[i].x.x = in() , p[i].x.y = in(), p[i].y = i;
    int stId = 0;
    for (int i = 1 ; i < n ; i ++)
    {
        if (p[i] < p[stId])
        {
            stId = i;
        }
    }
    swap(p[stId],p[0]);

    getsz();
    solve(0,0,n-1);
    for (int i = 0 ; i < n ; i ++ , cout << " ")
        cout << res[i] ;
}


// whats 1000 minus 7 ?
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline string get(){char ch[1000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 60;
//#define int long long
#define x first
#define y second
#define endl "\n"
#define mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef long long ll;
const int maxn = 1e6 + 100;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e18 + 100;
vector<int> g[maxn];
pair<pii,int> p[maxn];
int res[maxn] , sz[maxn];
int X , Y;
inline int ccw(pii a , pii b , pii c)
{
    int value = (b.x - a.x)*(c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    if (value > 0 )return 1;
    else return 0;
}
inline void getsz(int v , int pr = -1)
{
    sz[v] = 1;
    for (auto u : g[v])
    {
        if (u - pr) getsz(u,v) , sz[v] += sz[u];

    }
}
inline bool cmp(const int&a , const int &b)
{
    return ccw({X,Y},p[a].first,p[b].first);
}
inline void solve(int vid , int pid , vector<int> vc , int pr = -1)
{
    res[pid] = vid;
    X = p[pid].x.x , Y = p[pid].x.y;
    sort(vc.begin(),vc.end(),cmp);
    for (auto u : g[vid])
    {
        if (u == pr) continue;
        int pid2 = vc.back();
        vc.pop_back();
        vector<int> vc2;
        int need = sz[u] - 1;
        while (need --)
        {
            vc2.push_back(vc.back());
            vc.pop_back();
        }
        solve(u,pid2,vc2,vid);
    }
}
int32_t main()
{
    int n = in();
    for (int i = 0 ; i < n - 1 ; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u);
        g[u].push_back(v);
    }
    getsz(1);
    for (int i = 0 ; i < n ; i ++)
        p[i].x.x = in() , p[i].x.y = in() , p[i].y = i;
    int id = 0;
    for (int i = 1 ; i < n ; i++)
        if (p[i] < p[id])
            id = i;
    vector<int> vc;
    for (int i = 0 ; i < n ; i ++) if (i != id  )vc.push_back(p[i].y);
    solve(1,id,vc);
    for (int i = 0 ; i < n ; i ++ , cout << " ") cout << res[i];
}


// whats 1000 minus 7 ?
/*
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline string get(){char ch[1000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 60;
#define int long long
#define x first
#define y second
#define endl "\n"
#define mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef long long ll;
const int maxn = 1e6 + 100;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e18 + 100;
vector<int> g[maxn];
pair<pii,int> p[maxn];
int res[maxn] , sz[maxn];
int X , Y;
inline int ccw(pii a , pii b , pii c)
{
    int value = (b.x - a.x)*(c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    if (value > 0 )return 1;
    else return 0;
}
inline void getsz(int v , int pr = -1)
{
    sz[v] = 1;
    for (auto u : g[v])
    {
        if (u - pr) getsz(u,v) , sz[v] += sz[u];

    }
}
inline bool cmp(const int&a , const int &b)
{
    return ccw({X,Y},p[a].first,p[b].first);
}
inline void solve(int vid , int pid , vector<int> vc , int pr = -1)
{
    res[pid] = vid;
    X = p[pid].x.x , Y = p[pid].x.y;
    sort(vc.begin(),vc.end(),cmp);
    for (auto u : g[vid])
    {
        if (u == pr) continue;
        int pid2 = vc.back();
        vc.pop_back();
        vector<int> vc2;
        int need = sz[u] - 1;
        while (need --)
        {
            vc2.push_back(vc.back());
            vc.pop_back();
        }
        solve(u,pid2,vc2,vid);
    }
}
int32_t main()
{
    int n = in();
    for (int i = 0 ; i < n - 1 ; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u);
        g[u].push_back(v);
    }
    getsz(1);

    for (int i = 0 ; i < n ; i ++)
        p[i].x.x = in() , p[i].x.y = in() , p[i].y = i;
    int id = 0;
    for (int i = 1 ; i < n ; i++)
        if (p[i] < p[id])
            id = i;
    vector<int> vc;
    for (int i = 0 ; i < n ; i ++) if (i != id  )vc.push_back(p[i].y);
    solve(1,0,vc);
    for (int i = 0 ; i < n ; i ++ , cout << " ") cout << res[i];
}
*/
// whats 1000 minus 7 ?
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline string get(){char ch[1000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 60;
//#define int long long
#define x first
#define y second
#define endl "\n"
#define mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef long long ll;
const int maxn = 1e6 + 100;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e18 + 100;
int n;
vector<int> g[maxn];
pair<pii,int> p[maxn];
int sz[maxn];
int X , Y;
int res[maxn];
ld value[maxn];
inline void getsz(int v = 0 , int pr = -1)
{
    sz[v] = 1;
    for (auto u : g[v])
    {
        if (u == pr) continue;
        getsz(u,v);
        sz[v] += sz[u];
    }

}
inline bool cmp(const pair<pii,int> &a , const pair<pii,int> &b)
{
    return value[a.second] < value[b.second];
}
inline void solve(int v , int l , int r , int pr = -1)
{
    int need = sz[v] - 1;
    X = p[v].x.x , Y = p[v].x.y;
    for (int pt = l + 1 ; pt <= l + need ; pt ++)
    {
        value[p[pt].second] = atan2(p[pt].x.y - Y , p[pt].x.x - X);
    }
    sort(p+l+1,p+l+need+1,cmp);
    int cur = l + 1;
    res[p[l].y] = v + 1;
    int id = 0;
    while (cur <= l + need)
    {
        if (g[v][id] == pr)
        {
            id ++;
        }
        solve(g[v][id],cur,cur+sz[g[v][id]]-1,v);
        cur = cur + sz[g[v][id]];
        id ++;
    }
}
int32_t main()
{
    n = in();
    for (int i = 0 ; i < n - 1 ; i ++)
    {
        int v = in()  - 1, u = in() - 1;
        g[v].push_back(u) , g[u].push_back(v);
    }
    for (int i = 0 ; i < n ; i ++) p[i].x.x = in() , p[i].x.y = in(), p[i].y = i;
    int stId = 0;
    for (int i = 1 ; i < n ; i ++)
    {
        if (p[i] < p[stId])
        {
            stId = i;
        }
    }
    bool fl = false;
    swap(p[stId],p[0]) , fl = true;
    getsz();
    solve(0,0,n-1);
    if (fl)
        swap(res[stId],res[0]);

    for (int i = 0 ; i < n ; i ++ , cout << " ")
        cout << res[i] ;
}


// whats 1000 minus 7 ?
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline string get(){char ch[1000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 60;
#define int long long
#define x first
#define y second
#define endl "\n"
#define mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef long long ll;
const int maxn = 1e6 + 100;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e18 + 100;
vector<int> g[maxn];
pair<pii,int> p[maxn];
int res[maxn] , sz[maxn];
int X , Y;
inline int ccw(pii a , pii b , pii c)
{
    int value = (b.x - a.x)*(c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    if (value > 0 )return 1;
    else return 0;
}
inline void getsz(int v , int pr = -1)
{
    sz[v] = 1;
    for (auto u : g[v])
    {
        if (u - pr) getsz(u,v) , sz[v] += sz[u];

    }
}
inline bool cmp(const int&a , const int &b)
{
    return ccw({X,Y},p[a].first,p[b].first);
}
inline void solve(int vid , int pid , vector<int> vc , int pr = -1)
{
    res[pid] = vid;
    X = p[pid].x.x , Y = p[pid].x.y;
    sort(vc.begin(),vc.end(),cmp);
    for (auto u : g[vid])
    {
        if (u == pr) continue;
        int pid2 = vc.back();
        vc.pop_back();
        vector<int> vc2;
        int need = sz[u] - 1;
        while (need --)
        {
            vc2.push_back(vc.back());
            vc.pop_back();
        }
        solve(u,pid2,vc2,vid);
    }
}
int32_t main()
{
    int n = in();
    for (int i = 0 ; i < n - 1 ; i ++)
    {
        int v = in() , u = in();
        g[v].push_back(u);
        g[u].push_back(v);
    }
    getsz(1);
    for (int i = 0 ; i < n ; i ++)
        p[i].x.x = in() , p[i].x.y = in() , p[i].y = i;
    int id = 0;
    for (int i = 1 ; i < n ; i++)
        if (p[i] < p[id])
            id = i;
    vector<int> vc;
    for (int i = 0 ; i < n ; i ++) if (i != id  )vc.push_back(p[i].y);
    solve(1,id,vc);
    for (int i = 0 ; i < n ; i ++ , cout << " ") cout << res[i];
}


// whats 1000 minus 7 ?
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline string get(){char ch[1000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 60;
#define int long long
#define x first
#define y second
#define endl "\n"
#define mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef long long ll;
const int maxn = 1e6 + 100;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e18 + 100;
int n;
vector<int> g[maxn];
pair<pii,int> p[maxn];
int sz[maxn];
int X , Y;
int res[maxn];
inline void getsz(int v = 0 , int pr = -1)
{
    sz[v] = 1;
    for (auto u : g[v])
    {
        if (u == pr) continue;
        getsz(u,v);
        sz[v] += sz[u];
    }

}
inline bool cmp(const pair<pii,int> &a , const pair<pii,int> &b)
{
    return atan2(a.x.y - Y , a.x.x - X) < atan2(b.x.y - Y , b.x.x - X);
}
inline void solve(int v , int l , int r , int pr = -1)
{
    int need = sz[v] - 1;
    X = p[v].x.x , Y = p[v].x.y;
    sort(p+l+1,p+l+need+1,cmp);
    int cur = l + 1;
    res[p[l].y] = v + 1;
    int id = 0;
    while (cur <= l + need)
    {
        if (g[v][id] == pr)
        {
            id ++;
        }
        solve(g[v][id],cur,cur+sz[g[v][id]]-1,v);
        cur = cur + sz[g[v][id]];
        id ++;
    }
}
int32_t main()
{
    n = in();
    for (int i = 0 ; i < n - 1 ; i ++)
    {
        int v = in()  - 1, u = in() - 1;
        g[v].push_back(u) , g[u].push_back(v);
    }
    for (int i = 0 ; i < n ; i ++) p[i].x.x = in() , p[i].x.y = in(), p[i].y = i;
    getsz();
    solve(0,0,n-1);
    for (int i = 0 ; i < n ; i ++ , cout << " ")
        cout << res[i] ;
}


// whats 1000 minus 7 ?
#include <bits/stdc++.h>
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline string get(){char ch[1000010] ; scanf("%s",ch) ; return ch;}
const int MAX_LG = 60;
//#define int long long
#define x first
#define y second
#define endl "\n"
#define mp make_pair
typedef pair<int , int > pii;
typedef long double ld;
typedef long long ll;
const int maxn = 1e6 + 100;
const int base = 29;
const int mod = 1e9 + 7;
const int INF = 1e18 + 100;
int n;
vector<int> g[maxn];
pair<pii,int> p[maxn];
int sz[maxn];
int X , Y;
int res[maxn];
ld value[maxn];
inline void getsz(int v = 0 , int pr = -1)
{
    sz[v] = 1;
    for (auto u : g[v])
    {
        if (u == pr) continue;
        getsz(u,v);
        sz[v] += sz[u];
    }

}
inline bool cmp(const pair<pii,int> &a , const pair<pii,int> &b)
{
    return value[a.second] < value[b.second];
}
inline void solve(int v , int l , int r , int pr = -1)
{
    int need = sz[v] - 1;
    X = p[v].x.x , Y = p[v].x.y;
    for (int pt = l + 1 ; pt <= l + need ; pt ++)
    {
        value[p[pt].second] = atan2(p[pt].x.y - Y , p[pt].x.x - X);
    }
    sort(p+l+1,p+l+need+1,cmp);
    int cur = l + 1;
    res[p[l].y] = v + 1;
    int id = 0;
    while (cur <= l + need)
    {
        if (g[v][id] == pr)
        {
            id ++;
        }
        solve(g[v][id],cur,cur+sz[g[v][id]]-1,v);
        cur = cur + sz[g[v][id]];
        id ++;
    }
}
int32_t main()
{
    n = in();
    for (int i = 0 ; i < n - 1 ; i ++)
    {
        int v = in()  - 1, u = in() - 1;
        g[v].push_back(u) , g[u].push_back(v);
    }
    for (int i = 0 ; i < n ; i ++) p[i].x.x = in() , p[i].x.y = in(), p[i].y = i;
    getsz();
    solve(0,0,n-1);
    for (int i = 0 ; i < n ; i ++ , cout << " ")
        cout << res[i] ;
}


/*
 * sto Qingyu orz
 * 感谢真神sqy无私的教诲。膜时队者处处阿克，只因大师sqy在他背后。不膜大师者违背了真神的旨意，真神必将降下天谴,
 * 使其天天爆零
 * 我不由自主地膜拜真神sqy。
 * Author: RainAir
 * Time: 2019-10-21 17:49:52
 */
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int LL
const int MAXN = 3000+5;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int n,head[MAXN],x0,y00,cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

struct Point{
    int x,y;
    Point(int x=0,int y=0) : x(x),y(y) {}

    inline Point operator - (const Point &t) const {
        return Point(x-t.x,y-t.y);
    }

    inline int operator * (const Point &t){
        return x*t.y+y*t.x;
    }
}p[MAXN];

inline int cross(const Point &a,const Point &b,const Point &c=Point(x0,y00)){
    return (a-c)*(b-c);
//    return Point(a.x-c.x,a.y-c.y)*Point(b.x-c.x,b.y-c.y);
}

inline bool cmp(int u,int v){
    return cross(p[u],p[v]) < 0;
}

int ans[MAXN],sz[MAXN];

inline void dfs1(int v,int fa=0){
    sz[v] = 1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs1(e[i].to,v);sz[v] += sz[e[i].to];
    }
}

inline void dfs(int v,int fa,std::vector<int> now){
    if(now.size() == 1){
        ans[v] = now[0];
        now.clear();return;
    }
    x0 = y00 = 1e18;int ps = -1;
    FOR(i,0,(int)now.size()-1){
        if(x0 > p[now[i]].x){
            x0 = p[now[i]].x;
            y00 = p[now[i]].y;
            ps = i;
        }
        else if(x0 == p[now[i]].x && y00 > p[now[i]].y){
            x0 = p[now[i]].x;y00 = p[now[i]].y;
            ps = i;
        }
    }
    ans[v] = now[ps];
    now.erase(now.begin()+ps);
    std::sort(all(now),cmp);
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        std::vector<int> t;
        FOR(j,0,sz[e[i].to]-1) t.pb(now[j]);
        now.erase(now.begin(),now.begin()+sz[e[i].to]);
        dfs(e[i].to,v,t);
    }
    now.clear();
}

signed main(){
    scanf("%lld",&n);
 //   DEBUG(n);
    FOR(i,1,n-1){
        int u,v;scanf("%lld%lld",&u,&v);
        add(u,v);
    }
    std::vector<int> t;
    FOR(i,1,n){
        scanf("%lld%lld",&p[i].x,&p[i].y);t.pb(i);
    }
//    DEBUG((p[1]-p[3])*(p[4]-p[3]));
//    x0 = p[3].x;y00 = p[3].y;
//    DEBUG(cmp(1,4));
//    exit(0);
    std::sort(all(t),cmp);
    dfs1(1);dfs(1,0,t);
    FOR(i,1,n) printf("%lld ",ans[i]);puts("");
    return 0;
}


/*
 * sto Qingyu orz
 * 感谢真神sqy无私的教诲。膜时队者处处阿克，只因大师sqy在他背后。不膜大师者违背了真神的旨意，真神必将降下天谴,
 * 使其天天爆零
 * 我不由自主地膜拜真神sqy。
 * Author: RainAir
 * Time: 2019-10-21 17:49:52
 */
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 1500+5;
const double EPS = 1e-8;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int n,head[MAXN],x0,y00,cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

inline int sgn(double x){
    if(std::abs(x) <= EPS) return 0;
    return x > 0 ? 1 : -1;
}

struct Point{
    double x,y;int id;
    Point(int x=0,int y=0) : x(x),y(y) {}

    Point operator - (const Point &t) const {
        return Point(x-t.x,y-t.y);
    }

    double operator * (const Point &t) const {
        return x*t.y-y*t.x;
    }

    inline bool operator < (const Point &t) const {
        return !sgn(x-t.x) ? sgn(y-t.y)<0 : sgn(x-t.x)<0;
    }

    inline bool operator == (const Point &t) const {
        return !sgn(x-t.x) && !sgn(y-t.y);
    }

    inline double len(){
        return std::sqrt(x*x+y*y);
    }
}p[MAXN],p0;

inline bool cmp(const Point &a,const Point &b){
    return !sgn((a-p0)*(b-p0)) ? sgn((a-p0).len()-(b-p0).len()) < 0 : sgn((a-p0)*(b-p0)) < 0;
}

int ans[MAXN],sz[MAXN];

inline void dfs1(int v,int fa=0){
    sz[v] = 1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs1(e[i].to,v);sz[v] += sz[e[i].to];
    }
}

inline void dfs(int v,int fa,int l,int r){
    int ps = l;
    FOR(i,l+1,r){
        if(p[i] < p[ps]) ps = i;
    }
    std::swap(p[l],p[ps]);p0 = p[l];
    ans[p[l].id] = v;
    std::sort(p+l+1,p+r+1,cmp);
    int now = l+1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs(e[i].to,v,now,now+sz[e[i].to]-1);
        now = now+sz[e[i].to];
    }
}

signed main(){
//    freopen("test.in","r",stdin);
//    freopen("test.out","w",stdout);
    scanf("%d",&n);
    FOR(i,1,n-1){
        int u,v;scanf("%d%d",&u,&v);
        add(u,v);
    }
    FOR(i,1,n){
        scanf("%lf%lf",&p[i].x,&p[i].y);
        p[i].id = i;
    }
    dfs1(1);
    dfs(1,0,1,n);
    FOR(i,1,n) printf("%d ",ans[i]);puts("");
    return 0;
}


/*
 * sto Qingyu orz
 * 感谢真神sqy无私的教诲。膜时队者处处阿克，只因大师sqy在他背后。不膜大师者违背了真神的旨意，真神必将降下天谴,
 * 使其天天爆零
 * 我不由自主地膜拜真神sqy。
 * Author: RainAir
 * Time: 2019-10-21 17:49:52
 */
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int LL
const int MAXN = 3000+5;
const double EPS = 1e-8;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int n,head[MAXN],x0,y00,cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

struct Point{
    int x,y,id;
    Point(int x=0,int y=0) : x(x),y(y) {}

    inline Point operator - (const Point &t) const {
        return Point(x-t.x,y-t.y);
    }

    inline double operator * (const Point &t){
        DEBUG(1.0*x*t.y+1.0*y*t.x);
        return 1.0*x*t.y+1.0*y*t.x;
    }

    inline double deg(){
        return atan(1.0*y/x);
    }
}p[MAXN],p0;

inline int cross(const Point &a,const Point &b,const Point &c=Point(x0,y00)){
    return (a-c)*(b-c);
//    return Point(a.x-c.x,a.y-c.y)*Point(b.x-c.x,b.y-c.y);
}

inline int sgn(double x){
    if(std::abs(x) <= EPS) return 0;
    return x > 0 ? 1 : -1;
}

inline bool cmp(const Point &u,const Point &v){
    return sgn((u-p0).deg()-(v-p0).deg()) < 0;
}

int ans[MAXN],sz[MAXN];

inline void dfs1(int v,int fa=0){
    sz[v] = 1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs1(e[i].to,v);sz[v] += sz[e[i].to];
    }
}

inline void dfs(int v,int fa,int l,int r){
    int ps = l;
    FOR(i,l+1,r){
        if(p[i].x < p[ps].x || (p[i].x == p[ps].x && p[i].y < p[ps].y)) ps = i;
    }
    std::swap(p[l],p[ps]);p0 = p[l];
    ans[v] = p[l].id;
    std::sort(p+l+1,p+r+1,cmp);
    int now = l+1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs(e[i].to,v,now,now+sz[e[i].to]-1);
        now = now+sz[e[i].to];
    }
}

signed main(){
//    freopen("test.in","r",stdin);
//    freopen("test.out","w",stdout);
    scanf("%lld",&n);
 //   DEBUG(n);
    FOR(i,1,n-1){
        int u,v;scanf("%lld%lld",&u,&v);
        add(u,v);
    }
//    std::vector<int> t;
    FOR(i,1,n){
        scanf("%lld%lld",&p[i].x,&p[i].y);//t.pb(i);
        p[i].id = i;
    }
//    std::sort(all(t),cmp);
    dfs1(1);
    dfs(1,0,1,n);
    FOR(i,1,n) printf("%lld ",ans[i]);puts("");
    return 0;
}


/*
 * sto Qingyu orz
 * 感谢真神sqy无私的教诲。膜时队者处处阿克，只因大师sqy在他背后。不膜大师者违背了真神的旨意，真神必将降下天谴,
 * 使其天天爆零
 * 我不由自主地膜拜真神sqy。
 * Author: RainAir
 * Time: 2019-10-21 17:49:52
 */
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int LL
const int MAXN = 3000+5;
const double EPS = 1e-8;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int n,head[MAXN],x0,y00,cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

struct Point{
    int x,y;
    Point(int x=0,int y=0) : x(x),y(y) {}

    inline Point operator - (const Point &t) const {
        return Point(x-t.x,y-t.y);
    }

    inline double operator * (const Point &t){
        DEBUG(1.0*x*t.y+1.0*y*t.x);
        return 1.0*x*t.y+1.0*y*t.x;
    }

    inline double deg(){
        return atan(1.0*y/x);
    }
}p[MAXN];

inline int cross(const Point &a,const Point &b,const Point &c=Point(x0,y00)){
    return (a-c)*(b-c);
//    return Point(a.x-c.x,a.y-c.y)*Point(b.x-c.x,b.y-c.y);
}

inline int sgn(double x){
    if(std::abs(x) <= EPS) return 0;
    return x > 0 ? 1 : -1;
}

inline bool cmp(int u,int v){
    return sgn(p[u].deg()-p[v].deg()) < 0;
    DEBUG(cross(p[u],p[v]));
    return sgn(cross(p[u],p[v])) < 0;
}

int ans[MAXN],sz[MAXN];

inline void dfs1(int v,int fa=0){
    sz[v] = 1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs1(e[i].to,v);sz[v] += sz[e[i].to];
    }
}

inline void dfs(int v,int fa,std::vector<int> now){
    if(now.size() == 1){
        ans[v] = now[0];
        now.clear();return;
    }
    x0 = y00 = 1e18;int ps = -1;
    FOR(i,0,(int)now.size()-1){
        if(x0 > p[now[i]].x){
            x0 = p[now[i]].x;
            y00 = p[now[i]].y;
            ps = i;
        }
        else if(x0 == p[now[i]].x && y00 > p[now[i]].y){
            x0 = p[now[i]].x;y00 = p[now[i]].y;
            ps = i;
        }
    }
    ans[v] = now[ps];
    now.erase(now.begin()+ps);
    std::sort(all(now),cmp);
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        std::vector<int> t;
        FOR(j,0,sz[e[i].to]-1) t.pb(now[j]);
        now.erase(now.begin(),now.begin()+sz[e[i].to]);
        dfs(e[i].to,v,t);
    }
    now.clear();
}

signed main(){
//    freopen("test.in","r",stdin);
//    freopen("test.out","w",stdout);
    scanf("%lld",&n);
 //   DEBUG(n);
    FOR(i,1,n-1){
        int u,v;scanf("%lld%lld",&u,&v);
        add(u,v);
    }
    std::vector<int> t;
    FOR(i,1,n){
        scanf("%lld%lld",&p[i].x,&p[i].y);t.pb(i);
    }
//    DEBUG((p[1]-p[3])*(p[4]-p[3]));
//    x0 = p[3].x;y00 = p[3].y;
//    DEBUG(cmp(1,4));
//    exit(0);
    std::sort(all(t),cmp);
    dfs1(1);
    dfs(1,0,t);
    FOR(i,1,n) printf("%lld ",ans[i]);puts("");
    return 0;
}


/*
 * sto Qingyu orz
 * 感谢真神sqy无私的教诲。膜时队者处处阿克，只因大师sqy在他背后。不膜大师者违背了真神的旨意，真神必将降下天谴,
 * 使其天天爆零
 * 我不由自主地膜拜真神sqy。
 * Author: RainAir
 * Time: 2019-10-21 17:49:52
 */
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const double EPS = 1e-8;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int n,head[MAXN],x0,y00,cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

struct Point{
    int x,y,id;
    Point(int x=0,int y=0) : x(x),y(y) {}

    inline Point operator - (const Point &t) const {
        return Point(x-t.x,y-t.y);
    }

    inline double operator * (const Point &t){
 //       DEBUG(1.0*x*t.y+1.0*y*t.x);
        return 1.0*x*t.y+1.0*y*t.x;
    }

    inline double deg(){
        return atan(1.0*y/x);
    }
}p[MAXN],p0;

inline int cross(const Point &a,const Point &b,const Point &c=Point(x0,y00)){
    return (a-c)*(b-c);
//    return Point(a.x-c.x,a.y-c.y)*Point(b.x-c.x,b.y-c.y);
}

inline int sgn(double x){
    if(std::abs(x) <= EPS) return 0;
    return x > 0 ? 1 : -1;
}

inline bool cmp(const Point &u,const Point &v){
    return sgn((u-p0).deg()-(v-p0).deg()) < 0;
}

int ans[MAXN],sz[MAXN];

inline void dfs1(int v,int fa=0){
    sz[v] = 1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs1(e[i].to,v);sz[v] += sz[e[i].to];
    }
}

inline void dfs(int v,int fa,int l,int r){
    int ps = l;
    FOR(i,l+1,r){
        if(p[i].x < p[ps].x || (p[i].x == p[ps].x && p[i].y < p[ps].y)) ps = i;
    }
    std::swap(p[l],p[ps]);p0 = p[l];
    ans[v] = p[l].id;
    std::sort(p+l+1,p+r+1,cmp);
    int now = l+1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs(e[i].to,v,now,now+sz[e[i].to]-1);
        now = now+sz[e[i].to];
    }
}

signed main(){
//    freopen("test.in","r",stdin);
//    freopen("test.out","w",stdout);
    scanf("%d",&n);
 //   DEBUG(n);
    FOR(i,1,n-1){
        int u,v;scanf("%d%d",&u,&v);
        add(u,v);
    }
//    std::vector<int> t;
    FOR(i,1,n){
        scanf("%d%d",&p[i].x,&p[i].y);//t.pb(i);
        p[i].id = i;
    }
//    std::sort(all(t),cmp);
    dfs1(1);
    dfs(1,0,1,n);
    FOR(i,1,n) printf("%d ",ans[i]);puts("");
    return 0;
}


/*
 * sto Qingyu orz
 * 感谢真神sqy无私的教诲。膜时队者处处阿克，只因大师sqy在他背后。不膜大师者违背了真神的旨意，真神必将降下天谴,
 * 使其天天爆零
 * 我不由自主地膜拜真神sqy。
 * Author: RainAir
 * Time: 2019-10-21 17:49:52
 */
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 1500+5;
const double EPS = 1e-8;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int n,head[MAXN],x0,y00,cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

struct Point{
    int x,y,id;
    Point(int x=0,int y=0) : x(x),y(y) {}

    inline Point operator - (const Point &t) const {
        return Point(x-t.x,y-t.y);
    }

    inline double operator * (const Point &t){
 //       DEBUG(1.0*x*t.y+1.0*y*t.x);
        return 1.0*x*t.y+1.0*y*t.x;
    }

    inline double deg(){
        return atan(1.0*y/x);
    }
}p[MAXN],p0;

inline int sgn(double x){
    if(std::abs(x) <= EPS) return 0;
    return x > 0 ? 1 : -1;
}

inline bool cmp(const Point &u,const Point &v){
    return sgn((u-p0).deg()-(v-p0).deg()) < 0;
}

int ans[MAXN],sz[MAXN];

inline void dfs1(int v,int fa=0){
    sz[v] = 1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs1(e[i].to,v);sz[v] += sz[e[i].to];
    }
}

inline void dfs(int v,int fa,int l,int r){
    int ps = l;
    FOR(i,l+1,r){
        if(p[i].x < p[ps].x || (p[i].x == p[ps].x && p[i].y < p[ps].y)) ps = i;
    }
    std::swap(p[l],p[ps]);p0 = p[l];
    ans[p[l].id] = v;
    std::sort(p+l+1,p+r+1,cmp);
    int now = l+1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs(e[i].to,v,now,now+sz[e[i].to]-1);
        now = now+sz[e[i].to];
    }
}

signed main(){
//    freopen("test.in","r",stdin);
//    freopen("test.out","w",stdout);
    scanf("%d",&n);
 //   DEBUG(n);
    FOR(i,1,n-1){
        int u,v;scanf("%d%d",&u,&v);
        add(u,v);
    }
//    std::vector<int> t;
    FOR(i,1,n){
        scanf("%d%d",&p[i].x,&p[i].y);//t.pb(i);
        p[i].id = i;
    }
//    std::sort(all(t),cmp);
    dfs1(1);
    dfs(1,0,1,n);
    FOR(i,1,n) printf("%d ",ans[i]);puts("");
    return 0;
}


/*
 * sto Qingyu orz
 * 感谢真神sqy无私的教诲。膜时队者处处阿克，只因大师sqy在他背后。不膜大师者违背了真神的旨意，真神必将降下天谴,
 * 使其天天爆零
 * 我不由自主地膜拜真神sqy。
 * Author: RainAir
 * Time: 2019-10-21 17:49:52
 */
#include <algorithm>
#include <iostream>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
#define int LL
const int MAXN = 3000+5;
const double EPS = 1e-8;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int n,head[MAXN],x0,y00,cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

struct Point{
    int x,y,id;
    Point(int x=0,int y=0) : x(x),y(y) {}

    inline Point operator - (const Point &t) const {
        return Point(x-t.x,y-t.y);
    }

    inline double operator * (const Point &t){
 //       DEBUG(1.0*x*t.y+1.0*y*t.x);
        return 1.0*x*t.y+1.0*y*t.x;
    }

    inline double deg(){
        return atan(1.0*y/x);
    }
}p[MAXN],p0;

inline int cross(const Point &a,const Point &b,const Point &c=Point(x0,y00)){
    return (a-c)*(b-c);
//    return Point(a.x-c.x,a.y-c.y)*Point(b.x-c.x,b.y-c.y);
}

inline int sgn(double x){
    if(std::abs(x) <= EPS) return 0;
    return x > 0 ? 1 : -1;
}

inline bool cmp(const Point &u,const Point &v){
    return sgn((u-p0).deg()-(v-p0).deg()) < 0;
}

int ans[MAXN],sz[MAXN];

inline void dfs1(int v,int fa=0){
    sz[v] = 1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs1(e[i].to,v);sz[v] += sz[e[i].to];
    }
}

bool cmp2(Point a, Point b) {//按极角排序
    LL ax = a.x - p0.x, ay = a.y - p0.y, bx = b.x - p0.x, by = b.y - p0.y;
    if (ax >= 0 && bx <= 0) return 1;
    if (ax <= 0 && bx >= 0) return 0;
    return (ax * by > bx * ay);
}

inline void dfs(int v,int fa,int l,int r){
    int ps = l;
    FOR(i,l+1,r){
        if(p[i].x < p[ps].x || (p[i].x == p[ps].x && p[i].y < p[ps].y)) ps = i;
    }
    std::swap(p[l],p[ps]);p0 = p[l];
    ans[v] = p[l].id;
    std::sort(p+l+1,p+r+1,cmp2);
    int now = l+1;
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dfs(e[i].to,v,now,now+sz[e[i].to]-1);
        now = now+sz[e[i].to];
    }
}

signed main(){
//    freopen("test.in","r",stdin);
//    freopen("test.out","w",stdout);
    scanf("%lld",&n);
 //   DEBUG(n);
    FOR(i,1,n-1){
        int u,v;scanf("%lld%lld",&u,&v);
        add(u,v);
    }
//    std::vector<int> t;
    FOR(i,1,n){
        scanf("%lld%lld",&p[i].x,&p[i].y);//t.pb(i);
        p[i].id = i;
    }
//    std::sort(all(t),cmp);
    dfs1(1);
    dfs(1,0,1,n);
    FOR(i,1,n) printf("%lld ",ans[i]);puts("");
    return 0;
}