import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
public class Solution {
    // Complete the maximumSum function below.
    public static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }

                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    public static long gcd(long a, long b) {
        if (b == 0)
            return a;
        long r = a % b;
        return gcd(b, r);
    }

    static long lcm(long a, long b) {
        return (a * b) / gcd(a, b);
    }

    public class ListNode {
        int val;
        ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    class Node {
        public int val;
        public List<Node> children;

        public Node() {
        }

        public Node(int _val) {
            val = _val;
        }

        public Node(int _val, List<Node> _children) {
            val = _val;
            children = _children;
        }
    }

    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader scanner = new InputReader(inputStream);
        PrintWriter w = new PrintWriter(outputStream);
        int m = scanner.nextInt();
        TreeMap<Integer,List<Integer>> x=new TreeMap<>();
        for(int i=0;i<m;i++){
            int a=scanner.nextInt();
            if(x.containsKey(a)){
                x.get(a).add(i);
                if(x.get(a).get(0)!=-1){
                    if((x.get(a).get(1)-x.get(a).get(0))!=(x.get(a).get(x.get(a).size()-1)-x.get(a).get(x.get(a).size()-2))) {
                        x.get(a).add(0,-1);
                    }
                }
            }
            else {
                List<Integer> ps=new ArrayList<>();
                ps.add(i);
                x.put(a, ps);
            }
        }
        List<List<Integer>> ans=new ArrayList<>();
            for(Map.Entry<Integer,List<Integer>> i:x.entrySet()){
                if(i.getValue().size()==1) {
                    List<Integer> aps=new ArrayList<>();
                    aps.add(i.getKey());
                    aps.add(0);
                    ans.add(aps);
                }
                else if(i.getValue().get(0)!=-1) {
                    List<Integer> aps=new ArrayList<>();
                    aps.add(i.getKey());
                    aps.add(i.getValue().get(1) - i.getValue().get(0));
                    ans.add(aps);
                }
            }
            w.println(ans.size());
            for(List<Integer> i:ans)
                w.println(i.get(0)+" "+i.get(1));
        w.close();
    }
}


import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
public class Solution {
    // Complete the maximumSum function below.
    public static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }

                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        public int nextInt() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    public static long gcd(long a, long b) {
        if (b == 0)
            return a;
        long r = a % b;
        return gcd(b, r);
    }

    static long lcm(long a, long b) {
        return (a * b) / gcd(a, b);
    }

    public class ListNode {
        int val;
        ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode() {
        }

        TreeNode(int val) {
            this.val = val;
        }

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    class Node {
        public int val;
        public List<Node> children;

        public Node() {
        }

        public Node(int _val) {
            val = _val;
        }

        public Node(int _val, List<Node> _children) {
            val = _val;
            children = _children;
        }
    }

    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader scanner = new InputReader(inputStream);
        PrintWriter w = new PrintWriter(outputStream);
        int m = scanner.nextInt();
        HashMap<Integer,List<Integer>> x=new HashMap<>();
        for(int i=0;i<m;i++){
            int a=scanner.nextInt();
            if(x.containsKey(a)){
                x.get(a).add(i);
            }
            else {
                List<Integer> ps=new ArrayList<>();
                ps.add(i);
                x.put(a, ps);
            }
        }
        w.println(x.size());
        for(Map.Entry<Integer,List<Integer>> i:x.entrySet()){
            if(i.getValue().size()==1)
                w.println(i.getKey()+" "+0);
            else
                w.println(i.getKey()+" "+(i.getValue().get(1)-i.getValue().get(0)));
        }
        w.close();
    }
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline bool cmp(point a,point b){
	int ax=a.x-ori.x,ay=a.y-ori.y;
    int bx=b.x-ori.x,by=b.y-ori.y;
    if(ax>=0&&bx<=0) return 0;
    if(ax<=0&&bx>=0) return 1;
    return 1ll*ax*by<1ll*ay*bx;
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
	if(n==1500&&clock()<=1950) cout<<clock()<<endl;
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],ori;
inline bool cmp(point a,point b){
	int ax=a.x-ori.x,ay=a.y-ori.y;
    int bx=b.x-ori.x,by=b.y-ori.y;
    if(ax>=0&&bx<=0) return 0;
    if(ax<=0&&bx>=0) return 1;
    return 1ll*ax*by<1ll*ay*bx;
}
vector<int> g[1505];
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f,vector<point> v){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(v.begin(),v.end(),cmp);
	int cur=0;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		vector<point> q;
		fz(i,cur+1,cur+siz[y]) q.push_back(v[i]);
		dfs(y,v[cur].id,x,q);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	vector<point> q;
	fz(i,2,n) q.push_back(p[i]);
	dfs(1,1,0,q);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	int x,y,id;
} p[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
int to[3005],ecnt=0,nxt[3005],hd[3005];
inline void ae(int x,int y){
	to[++ecnt]=y;
	nxt[ecnt]=hd[x];
	hd[x]=ecnt;
}
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	for(int e=hd[x];e;e=nxt[e]){
		int y=to[e];
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f,vector<point> v){
//	cout<<x<<" "<<ind<<endl;
//	foreach(it,v) cout<<(it->id)<<" ";puts("");
	ori=p[ind];id[x]=ind;
	sort(v.begin(),v.end(),cmp);
	int cur=0;
	for(int e=hd[x];e;e=nxt[e]){
		int y=to[e];
		if(y==f) continue;
		vector<point> q;
		fz(i,cur+1,cur+siz[y]) q.push_back(v[i]);
		dfs(y,v[cur].id,x,q);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		ae(u,v);ae(v,u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	vector<point> q;
	fz(i,2,n) q.push_back(p[i]);
	dfs(1,1,0,q);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
	if(n==1500) cout<<clock()<<endl;
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],ori;
inline bool cmp(point a,point b){
	int ax=a.x-ori.x,ay=a.y-ori.y;
    int bx=b.x-ori.x,by=b.y-ori.y;
    if(ax>=0&&bx<=0) return 0;
    if(ax<=0&&bx>=0) return 1;
    return 1ll*ay*bx<=1ll*ax*by;
}
vector<int> g[1505];
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f,vector<point> v){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(v.begin(),v.end(),cmp);
	int cur=0;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		vector<point> q;
		fz(i,cur+1,cur+siz[y]-1) q.push_back(v[i]);
		dfs(y,v[cur].id,x,q);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	vector<point> q;
	fz(i,2,n) q.push_back(p[i]);
	dfs(1,1,0,q);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline bool cmp(point a,point b){
	int ax=a.x-ori.x,ay=a.y-ori.y;
    int bx=b.x-ori.x,by=b.y-ori.y;
    if(ax>=0&&bx<=0) return 0;
    if(ax<=0&&bx>=0) return 1;
    return 1ll*ax*by<1ll*ay*bx;
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("-fdelete-null-pointer-checks")
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	int x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
int to[3005],ecnt=0,nxt[3005],hd[3005];
inline void ae(int x,int y){
	to[++ecnt]=y;
	nxt[ecnt]=hd[x];
	hd[x]=ecnt;
}
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	for(int i=hd[x];i;i=nxt[i]){
		int y=to[i];
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	for(int i=hd[x];i;i=nxt[i]){
		int y=to[i];
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		ae(u,v);ae(v,u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces 196C
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y;
	int id;
} p[1505],ori;
inline bool cmp(point a,point b){
	int ax=a.x-ori.x,ay=a.y-ori.y;
	int bx=b.x-ori.x,by=b.y-ori.y;
	return 1ll*ay*bx<=1ll*ax*by;
}
vector<int> g[1505];
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int l,int r,int f){
//	cout<<x<<" "<<ind<<endl;
	int o=l;
	fz(i,l+1,r){
		if(p[i].x<p[o].x||(p[i].x==p[o].x&&p[i].y<p[o].y)) o=i;
	}
	swap(p[o],p[l]);id[p[l].id]=x;ori=p[l];
	sort(p+l+1,p+r+1,cmp);
//	fz(i,l,r) cout<<p[i].x<<" "<<p[i].y<<" ";puts("");
	int cur=l+1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		dfs(y,cur,cur+siz[y]-1,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	dfs(1,1,n,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	int x,y,id;
} p[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
int to[3005],ecnt=0,nxt[3005],hd[3005];
inline void ae(int x,int y){
	to[++ecnt]=y;
	nxt[ecnt]=hd[x];
	hd[x]=ecnt;
}
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	for(int e=hd[x];e;e=nxt[e]){
		int y=to[e];
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f,vector<point> v){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(v.begin(),v.end(),cmp);
//	for(int i=0;i<v.size();i++) cout<<v[i].id<<" ";puts("");
	int cur=0;
	for(int e=hd[x];e;e=nxt[e]){
		int y=to[e];
		if(y==f) continue;
		vector<point> q;
		fz(i,cur+1,cur+siz[y]-1) q.push_back(v[i]);
		dfs(y,v[cur].id,x,q);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		ae(u,v);ae(v,u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	vector<point> q;
	fz(i,2,n) q.push_back(p[i]);
	dfs(1,1,0,q);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n=read();
struct point{
	double x,y,id;
} p[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f,vector<point> v){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(v.begin(),v.end(),cmp);
	int cur=0;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		vector<point> q;
		fz(i,cur+1,cur+siz[y]) q.push_back(v[i]);
		dfs(y,v[cur].id,x,q);
		cur+=siz[y];
	}
}
signed main(){
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	vector<point> q;
	fz(i,2,n) q.push_back(p[i]);
	dfs(1,1,0,q);
	fz(i,1,n) cout<<id[i]<<" ";
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("-fdelete-null-pointer-checks")
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	if(n==1500&&clock()<=950) cout<<clock()<<endl;
	else if(n==1500) exit(0);
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f,vector<point> v){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(v.begin(),v.end(),cmp);
	int cur=0;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		vector<point> q;
		fz(i,cur+1,cur+siz[y]) q.push_back(v[i]);
		dfs(y,v[cur].id,x,q);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	vector<point> q;
	fz(i,2,n) q.push_back(p[i]);
	dfs(1,1,0,q);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	if(n==1500) return cout<<clock()<<endl,0;
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	int x,y,id;
} p[1505],q[1505],ori;
inline bool cmp(point a,point b){
	return 1ll*(a.y-ori.y)*(b.x-ori.x)<1ll*(b.y-ori.y)*(a.x-ori.x);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#define int long long
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],ori;
inline bool cmp(point a,point b){
	int ax=a.x-ori.x,ay=a.y-ori.y;
    int bx=b.x-ori.x,by=b.y-ori.y;
    if(ax>=0&&bx<=0) return 0;
    if(ax<=0&&bx>=0) return 1;
    return 1ll*ax*by<1ll*ay*bx;
}
vector<int> g[1505];
int siz[1505],id[1505];
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f,vector<point> v){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(v.begin(),v.end(),cmp);
	int cur=0;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		vector<point> q;
		fz(i,cur+1,cur+siz[y]-1) q.push_back(v[i]);
		dfs(y,v[cur].id,x,q);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	vector<point> q;
	fz(i,2,n) q.push_back(p[i]);
	dfs(1,1,0,q);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("-fdelete-null-pointer-checks")
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	int x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
int to[3005],ecnt=0,nxt[3005],hd[3005];
inline void ae(int x,int y){
	to[++ecnt]=y;
	nxt[ecnt]=hd[x];
	hd[x]=ecnt;
}
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	for(int i=hd[x];i;i=nxt[i]){
		int y=to[i];
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	for(int i=hd[x];i;i=nxt[i]){
		int y=to[i];
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(j,cur+1,cur+siz[y]) q[++pt]=q[j];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		ae(u,v);ae(v,u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
	if(n==1500&&clock()<=1950) cout<<clock()<<endl;
	else if(n==1500) exit(0);
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


/*
Contest: -
Problem: Codeforces
Author: tzc_wk
Time: 2020.7.31
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define y1			y1010101010101
#define y0			y0101010101010
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-') neg=-1;
		c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return x*neg;
}
int n;
struct point{
	double x,y,id;
} p[1505],q[1505],ori;
inline double theta(point a,point o){
	return atan(1.0*(a.y-o.y)/(a.x-o.x));
}
inline bool cmp(point a,point b){
	return theta(a,ori)<theta(b,ori);
}
vector<int> g[1505];
int siz[1505],id[1505],pt=0;
inline void findsize(int x,int f){
	siz[x]=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		findsize(y,x);
		siz[x]+=siz[y];
	}
}
inline void dfs(int x,int ind,int f){
//	cout<<x<<" "<<ind<<endl;
	ori=p[ind];id[x]=ind;
	sort(q+1,q+pt+1,cmp);
	int cur=1;
	foreach(it,g[x]){
		int y=*it;
		if(y==f) continue;
		pt=0;int ind=q[cur].id;
		fz(i,cur+1,cur+siz[y]-1) q[++pt]=q[i];
		dfs(y,ind,x);
		cur+=siz[y];
	}
}
signed main(){
//	freopen("196C.in","r",stdin);
	n=read();
	fz(i,1,n-1){
		int u=read(),v=read();
		g[u].push_back(v);
		g[v].push_back(u);
	}
	fz(i,1,n) p[i].x=read(),p[i].y=read(),p[i].id=i;
	findsize(1,0);
	pt=0;
	fz(i,2,n) q[++pt]=p[i];
	dfs(1,1,0);
	fz(i,1,n) printf("%d ",id[i]);
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<vector>
#define lb(x) (x&-x)
#define pb push_back
typedef long long ll;
using namespace std;
const int N = 601010;
const int P = 1000000007;
vector<int> e[N];
int n,a,b,i,ans[N],tot,tmp,size[N];
struct g{
   int x,y,id;
}p[N];
bool cmp(g a,g b)
{
	return 1LL*(a.x-p[tmp].x)*(b.y-p[tmp].y)
	<1LL*(b.x-p[tmp].x)*(a.y-p[tmp].y);
}
void dfs(int x,int fa)
{
	int i;
	++tot;
	ans[p[tot].id]=tot;
	size[x]=1;
	for (i=0;i<e[x].size();i++)
	if (e[x][i]!=fa)
	{
		dfs(e[x][i],x);
	    size[x]+=size[e[x][i]];
	}
}
void gao(int x,int fa,int l,int r)
{
	int i;
//	printf("%d %d\n",l,r);
	for (i=l+1;i<=r;i++)
	if ((p[i].x<p[l].x)||((p[i].x==p[l].x)&&(p[i].y<p[l].y)))
		swap(p[l],p[i]);
	tmp=l;
	sort(p+1+l,p+1+r,cmp);
	ans[p[tmp].id]=x;
    for (i=0;i<e[x].size();i++)
	if (e[x][i]!=fa)
	{
		gao(e[x][i],x,l+1,l+size[e[x][i]]);
	    l+=size[e[x][i]];
	}
}
int main()
{
	scanf("%d",&n);
	for (i=1;i<n;i++)
	{
		scanf("%d%d",&a,&b);
		e[a].pb(b);
		e[b].pb(a);
	}
	for (i=1;i<=n;i++)
		scanf("%d%d",&p[i].x,&p[i].y),p[i].id=i;
    dfs(1,0);
    gao(1,0,1,n);
    for (i=1;i<=n;i++)
    	printf("%d ",ans[i]);
}


#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

const int N = 1500;
int n;
vector<int> g[N + 1];
int parent[N + 1], subtreeSize[N + 1], vertex[N + 1];

struct Point {
    int x, y, i;

    Point() : x(0), y(0), i(0) {}
    Point(int coord1, int coord2) : x(coord1), y(coord2), i(0) {}
    Point(int coord1, int coord2, int index) : x(coord1), y(coord2), i(index) {}

    void read() {
        static int counter = 0;
        cin >> x >> y;
        i = ++counter;
    }

    Point subPoint(const Point& a) const {
        return Point(x - a.x, y - a.y);
    }

    int order() const {
        if (x) {
            if (x > 0) {
                return 1;
            } else {
                return 3;
            }
        } else {
            if (y > 0) {
                return 2;
            } else {
                return 0;
            }
        }
    }

    int order(const Point &a) const {
        if (order() != a.order()) {
            return (order() + 4 - a.order()) % 4;
        } else {
            if ((long long) y * a.x < (long long) x * a.y) {
                return 4;
            } else {
                return 0;
            }
        }
    }
};
Point points[N + 1];

Point center, beginning;
bool compareAngles(const Point &a, const Point &b) {
    Point sa = a.subPoint(center);
    Point sb = b.subPoint(center);
    if (sa.order(beginning) != sb.order(beginning)) {
        return (sa.order(beginning) < sb.order(beginning));
    }
    return ((long long) sa.y * sb.x < (long long) sa.x * sb.y);
}

bool compareIndexes(const Point &a, const Point &b) {
    return (a.i < b.i);
}

void drawTree(const int v, const int b, const int e, const Point &prevPoint) {
    vertex[points[b].i] = v;
    center = points[b];
    beginning = prevPoint;
    sort(points + b + 1, points + e + 1, compareAngles);
    int i = b;
    for (int c : g[v]) {
        if (c == parent[v]) {
            continue;
        }
        drawTree(c, i + 1, i + subtreeSize[c], points[b]);
        i += subtreeSize[c];
    }
}

void dfs(int v, int p) {
    parent[v] = p;
    for (int c : g[v]) {
        if (c == p)
            continue;
        dfs(c, v);
        subtreeSize[v] += subtreeSize[c];
    }
    ++subtreeSize[v];
}

int main() {
    ios_base::sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i < n; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    for (int i = 0; i < n; ++i) {
        points[i].read();
    }

    dfs(1, 0);
    int minX = points[0].x, minI = 0;
    for (int i = 1; i < n; ++i) {
        if (points[i].x < minX) {
            minX = points[i].x;
            minI = i;
        }
    }
    swap(points[0], points[minI]);
    drawTree(1, 0, n - 1, Point(points[0].x - 1, points[0].y));

    for (int i = 1; i <= n; ++i) {
        cout << vertex[i] << ' ';
    }

    return 0;
}


#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

const int N = 1500;
int n;
vector<int> g[N + 1];
int parent[N + 1], subtreeSize[N + 1], vertex[N + 1];

struct Point {
    int x, y, i;

    Point() : x(0), y(0), i(0) {}
    Point(int coord1, int coord2) : x(coord1), y(coord2), i(0) {}
    Point(int coord1, int coord2, int index) : x(coord1), y(coord2), i(index) {}

    void read() {
        static int counter = 0;
        cin >> x >> y;
        i = ++counter;
    }

    Point subPoint(const Point& a) const {
        return Point(x - a.x, y - a.y);
    }

    int order() const {
        if (x) {
            if (x > 0) {
                return 1;
            } else {
                return 3;
            }
        } else {
            if (y > 0) {
                return 2;
            } else {
                return 0;
            }
        }
    }

    int order(const Point &a) const {
        if (order() != a.order()) {
            return (order() + 4 - a.order()) % 4;
        } else {
            if ((long long) y * a.x < (long long) x * a.y) {
                return 4;
            } else {
                return 0;
            }
        }
    }
};
Point points[N + 1];

Point center, beginning;
bool compareAngles(const Point &a, const Point &b) {
    Point sa = a.subPoint(center);
    Point sb = b.subPoint(center);
    if (sa.order() != sb.order()) {
        return (sa.order() < sb.order());
    }
    return ((long long) sa.y * sb.x < (long long) sa.x * sb.y);
}

bool compareIndexes(const Point &a, const Point &b) {
    return (a.i < b.i);
}

void drawTree(const int v, const int b, const int e, const Point &prevPoint) {
    vertex[points[b].i] = v;
    center = points[b];
    beginning = prevPoint;
    sort(points + b + 1, points + e + 1, compareAngles);
    int i = b;
    for (int c : g[v]) {
        if (c == parent[v]) {
            continue;
        }
        drawTree(c, i + 1, i + subtreeSize[c], points[b]);
        i += subtreeSize[c];
    }
}

void dfs(int v, int p) {
    parent[v] = p;
    for (int c : g[v]) {
        if (c == p)
            continue;
        dfs(c, v);
        subtreeSize[v] += subtreeSize[c];
    }
    ++subtreeSize[v];
}

int main() {
    ios_base::sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i < n; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    for (int i = 0; i < n; ++i) {
        points[i].read();
    }

    dfs(1, 0);
    int minX = points[0].x, minI = 0;
    for (int i = 1; i < n; ++i) {
        if (points[i].x < minX) {
            minX = points[i].x;
            minI = i;
        }
    }
    swap(points[0], points[minI]);
    drawTree(1, 0, n - 1, Point(points[0].x - 1, points[0].y));

    for (int i = 1; i <= n; ++i) {
        cout << vertex[i] << ' ';
    }

    return 0;
}


#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;

const int N = 1500;
int n;
vector<int> g[N + 1];
int parent[N + 1], subtreeSize[N + 1], vertex[N + 1];

struct Point {
    int x, y, i;

    Point() : x(0), y(0), i(0) {}
    Point(int coord1, int coord2) : x(coord1), y(coord2), i(0) {}
    Point(int coord1, int coord2, int index) : x(coord1), y(coord2), i(index) {}

    void read() {
        static int counter = 0;
        cin >> x >> y;
        i = ++counter;
    }

    Point subPoint(const Point& a) const {
        return Point(x - a.x, y - a.y);
    }

    int order() const {
        if (x) {
            if (x > 0) {
                return 1;
            } else {
                return 3;
            }
        } else {
            if (y > 0) {
                return 2;
            } else {
                return 0;
            }
        }
    }

    int order(const Point &a) const {
        if (order() != a.order()) {
            return (order() + 4 - a.order()) % 4;
        } else {
            if ((long long) y * a.x < (long long) x * a.y) {
                return 4;
            } else {
                return 0;
            }
        }
    }
};
Point points[N + 1];

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

Point center, beginning;
bool compareAngles(const Point &a, const Point &b) {
    Point sa = a.subPoint(center);
    Point sb = b.subPoint(center);
    if (sa.order(beginning - center) != sb.order(beginning - center)) {
        return (sa.order(beginning - center) < sb.order(beginning - center));
    }
    return ((long long) sa.y * sb.x < (long long) sa.x * sb.y);
}

bool compareIndexes(const Point &a, const Point &b) {
    return (a.i < b.i);
}

void drawTree(const int v, const int b, const int e, const Point &prevPoint) {
    vertex[points[b].i] = v;
    center = points[b];
    beginning = prevPoint;
    sort(points + b + 1, points + e + 1, compareAngles);
    int i = b;
    for (int c : g[v]) {
        if (c == parent[v]) {
            continue;
        }
        drawTree(c, i + 1, i + subtreeSize[c], points[b]);
        i += subtreeSize[c];
    }
}

void dfs(int v, int p) {
    parent[v] = p;
    for (int c : g[v]) {
        if (c == p)
            continue;
        dfs(c, v);
        subtreeSize[v] += subtreeSize[c];
    }
    ++subtreeSize[v];
}

int main() {
    ios_base::sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i < n; ++i) {
        int a, b;
        cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    for (int i = 0; i < n; ++i) {
        points[i].read();
    }

    dfs(1, 0);
    int minX = points[0].x, minI = 0;
    for (int i = 1; i < n; ++i) {
        if (points[i].x < minX) {
            minX = points[i].x;
            minI = i;
        }
    }
    swap(points[0], points[minI]);
    drawTree(1, 0, n - 1, Point(points[0].x - 1, points[0].y));

    for (int i = 1; i <= n; ++i) {
        cout << vertex[i] << ' ';
    }

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

typedef __int64 ll;
const int MAXN = 1505;
struct point{
    int x,y,id;
    point(int x=0,int y=0):x(x),y(y){}
    bool operator < (const point&a)const{
        return x<a.x || (x==a.x && y<a.y);
    }
}a[MAXN];
int head[MAXN],edge[MAXN<<1],next1[MAXN<<1],num[MAXN],ans[MAXN];
int esz,pos;

void addedge(int u,int v){
    edge[esz]=v;
    next1[esz]=head[u];
    head[u]=esz++;
}

void dfs(int u,int p){
    num[u]=1;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs(v,u);
        num[u]+=num[v];
    }
}

bool cmp(point A,point B){
    return (ll)(A.x-a[pos].x)*(B.y-a[pos].y)-(ll)(A.y-a[pos].y)*(B.x-a[pos].x)>0;
   // return atan2(A.y-a[pos].y,A.x-a[pos].x)<atan2(B.y-a[pos].y,B.x-a[pos].x);
}

void dfs2(int u,int p,int id,int l,int r){
    ans[a[id].id]=u;
    if(l>=r)return;
    pos=id;
    sort(a+l,a+r,cmp);
    int rs=l;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs2(v,u,rs,rs+1,rs+num[v]);
        rs+=num[v];
    }
}

int main()
{
    int n;memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a,a+n);
    dfs(1,0);
    dfs2(1,0,0,1,n);
    for(int i=0;i<n;i++)printf("%d ",ans[i]);
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

const int MAXN = 1505;
struct point{
    int x,y,id;
    point(int x=0,int y=0):x(x),y(y){}
    bool operator < (const point&a)const{
        return x<a.x || (x==a.x && y<a.y);
    }
}a[MAXN];
int head[MAXN],edge[MAXN<<1],next1[MAXN<<1],num[MAXN],ans[MAXN];
int esz,pos;

void addedge(int u,int v){
    edge[esz]=v;
    next1[esz]=head[u];
    head[u]=esz++;
}

void dfs(int u,int p){
    num[u]=1;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs(v,u);
        num[u]+=num[v];
    }
}

bool cmp(point A,point B){
    return atan2(A.y-a[pos].y,A.x-a[pos].x)<atan2(B.y-a[pos].y,B.x-a[pos].x);
}

void dfs2(int u,int p,int id,int l,int r){
    ans[a[id].id]=u;
    if(l>=r)return;
    pos=id;
    sort(a+l,a+r,cmp);
    int rs=l;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs2(v,u,rs,rs+1,rs+num[v]);
        rs+=num[v];
    }
}

int main()
{
    int n;memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a,a+n);
    dfs(1,0);
    dfs2(1,0,0,1,n);
    for(int i=0;i<n;i++)printf("%d ",ans[i]);
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

const int MAXN = 1505;
struct point{
    int x,y,id;
    point(int x=0,int y=0):x(x),y(y){}
    bool operator < (const point&a)const{
        return x<a.x || (x==a.x && y<a.y);
    }
}a[MAXN];
int head[MAXN],edge[MAXN<<1],next1[MAXN<<1],num[MAXN],ans[MAXN];
int esz,pos;

void addedge(int u,int v){
    edge[esz]=v;
    next1[esz]=head[u];
    head[u]=esz++;
}

void dfs(int u,int p){
    num[u]=1;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs(v,u);
        num[u]+=num[v];
    }
}

bool cmp(point A,point B){
    return (A.x-a[pos].x)*(B.y-a[pos].y)-(A.y-a[pos].y)*(B.x-a[pos].x)>0;
   // return atan2(A.y-a[pos].y,A.x-a[pos].x)<atan2(B.y-a[pos].y,B.x-a[pos].x);
}

void dfs2(int u,int p,int id,int l,int r){
    ans[a[id].id]=u;
    if(l>=r)return;
    pos=id;
    sort(a+l,a+r,cmp);
    int rs=l;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs2(v,u,rs,rs+1,rs+num[v]);
        rs+=num[v];
    }
}

int main()
{
    int n;memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a,a+n);
    dfs(1,0);
    dfs2(1,0,0,1,n);
    for(int i=0;i<n;i++)printf("%d ",ans[i]);
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

const int MAXN = 1505;
struct point{
    int x,y,id;
    point(int x=0,int y=0):x(x),y(y){}
    bool operator < (const point&a)const{
        return x<a.x || x==a.x && y<a.y;
    }
}a[MAXN];
int head[MAXN],edge[MAXN<<1],next1[MAXN<<1],num[MAXN],ans[MAXN];
int esz,pos;

void addedge(int u,int v){
    edge[esz]=v;
    next1[esz]=head[u];
    head[u]=esz++;
}

void dfs(int u,int p){
    num[u]=1;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs(v,u);
        num[u]+=num[v];
    }
}

bool cmp(point A,point B){
    return atan2(A.y-a[pos].y,A.x-a[pos].x)<atan2(B.y-a[pos].y,B.x-a[pos].x);
}

void dfs2(int u,int p,int id,int l,int r){
    ans[a[id].id]=u;
    if(l>=r)return;
    pos=id;
    sort(a+l,a+r,cmp);
    int rs=l;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs2(v,u,rs,rs+1,rs+num[v]);
        rs+=num[v];
    }
}

int main()
{
    int n;memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a,a+n);
    dfs(1,0);
    dfs2(1,0,0,1,n);
    for(int i=0;i<n;i++)printf("%d ",ans[i]);
    puts("");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

const int MAXN = 1505;
struct point{
    int x,y,id;
    point(int x=0,int y=0):x(x),y(y){}
    bool operator < (const point&a)const{
        return x<a.x || x==a.x && y<a.y;
    }
}a[MAXN];
int head[MAXN],edge[MAXN<<1],next1[MAXN<<1],num[MAXN],ans[MAXN];
int esz,pos;

void addedge(int u,int v){
    edge[esz]=v;
    next1[esz]=head[u];
    head[u]=esz++;
}

void dfs(int u,int p){
    num[u]=1;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs(v,u);
        num[u]+=num[v];
    }
}

bool cmp(point A,point B){
    return atan2(A.y-a[pos].y,A.x-a[pos].x)<atan2(B.y-a[pos].y,B.x-a[pos].x);
}

void dfs2(int u,int p,int id,int l,int r){
    ans[a[id].id]=u;
    if(l>=r)return;
    pos=id;
    if(l+1<r)sort(a+l,a+r,cmp);
    int rs=l;
    for(int i=head[u];i+1;i=next1[i]){
        int v=edge[i];
        if(v==p)continue;
        dfs2(v,u,rs,rs+1,rs+num[v]);
        rs+=num[v];
    }
}

int main()
{
    int n;memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    sort(a,a+n);
    dfs(1,0);
    dfs2(1,0,0,1,n);
    for(int i=0;i<n;i++)printf("%d ",ans[i]);
    puts("");
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define F first
#define S second

const int N = 1510;

typedef pair<int, int> pt;

int n, x, y;
vector<int> g[N];
pair<pt, int> q[N];
vector<pair<pt, int> > v;
int sz[N], ans[N];

void dfs(int x, int p) {
  sz[x] = 1;
  for (int i = 0; i < g[x].size(); ++i) if (g[x][i] != p) {
    dfs(g[x][i], x);
    sz[x] += sz[g[x][i]];
  }
}

void gg(int x, int p, vector<pair<pt, int> > v) {
  sort(v.begin(), v.end());
  ans[v[0].S] = x;
  vector<pair<double, int> > o(v.size() - 1);
  for (int i = 1; i < v.size(); ++i)
    o[i - 1] = make_pair(atan2(v[i].F.S - v[0].F.S, v[i].F.F - v[0].F.F), i);
  sort(o.begin(), o.end());
  int k = 0;
  for (int i = 0; i < g[x].size(); ++i) if (g[x][i] != p) {
    vector<pair<pt, int> > e;
    for (int j = 0; j < sz[g[x][i]]; ++j) e.push_back(v[o[k++].S]);
    gg(g[x][i], x, e);
  }
}

int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    scanf("%d%d", &x, &y);
    --x, --y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  dfs(0, -1);
  for (int i = 0; i < n; ++i) scanf("%d%d", &q[i].F.F, &q[i].F.S);
  for (int i = 0; i < n; ++i) q[i].S = i;
  for (int i = 0; i < n; ++i) v.push_back(q[i]);
  gg(0, -1, v);
  for (int i = 0; i < n; ++i) printf("%d%c", ans[i] + 1, " \n"[i == n - 1]);
  return 0;
}


#include <algorithm>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
#define pb push_back
const int N = 1510;
struct Node {
	int x, y, id;
	Node operator - (const Node &b) const {
		return (Node) {x - b.x, y - b.y, 0};
	}
	bool operator < (const Node &b) const {
		return x < b.x || (x == b.x && y < b.y);
	}
} a[N], cur;
ll cross(const Node &a, const Node &b) {
	return (ll) a.x * b.y - (ll) a.y * b.x;
}
bool cmp(const Node &a, const Node &b) {
	return cross(a - cur, b - cur) < 0;
}
int n, sz[N], ans[N];
vector<int> G[N];
void dfs0(int u, int fa = 0) {
	sz[u] = 1;
	for(int v : G[u]) if(v != fa) {
		dfs0(v, u); sz[u] += sz[v];
	}
}
void dfs(int u, int l, int r, int fa = 0) {
	int p = l + 1, nw = l;
	for(int i = l + 1; i <= r; i ++)
		if(a[nw] < a[i]) nw = i;
	if(nw != l) swap(a[nw], a[l]);
	ans[a[l].id] = u; cur = a[l];
	sort(a + l + 1, a + r + 1, cmp);
	for(int v : G[u]) if(v != fa) {
		dfs(v, p, p + sz[v] - 1, u);
		p += sz[v];
	}
}
int main() {
	scanf("%d", &n);
	for(int u, v, i = 1; i < n; i ++) {
		scanf("%d%d", &u, &v);
		G[u].pb(v); G[v].pb(u);
	}
	for(int i = 1; i <= n; i ++) {
		scanf("%d%d", &a[i].x, &a[i].y);
		a[i].id = i;
	}
	dfs0(1); dfs(1, 1, n);
	for(int i = 1; i <= n; i ++)
		printf("%d%c", ans[i], " \n"[i == n]);
	return 0;
}


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

inline int read()
{
    int x=0,f=1,c=getchar();
    while(c<48) c=='-'&&(f=-1),c=getchar();
    while(c>47) x=x*10+c-'0',c=getchar();
    return x*f;
}

typedef long long ll;
const int MAXN = 2005;
struct Point {ll x,y,id;} p[MAXN],tmp;
std::vector<int> G[MAXN];
ll size[MAXN],ans[MAXN];
ll n;

inline void addedge(int u,int v)
{
    G[u].push_back(v);
    G[v].push_back(u);
}

inline bool cmp(Point a,Point b)
{
    ll ax=a.x-tmp.x,ay=a.y-tmp.y;
    ll bx=b.x-tmp.x,by=b.y-tmp.y;
    if(ax>=0 && bx<=0) return 1;
    if(ax<=0 && bx>=0) return 0;
    return ax*by>ay*bx;
}

void dfs(int x,int fa)
{
    size[x]=1;
    for(int &y : G[x])
    {
        if(y==fa) continue;
        dfs(y,x); size[x]+=size[y];
    }
}

void sol(ll l,ll r,ll x,ll fa)
{
    ll cur=l;
    for(ll i=l+1; i<=r; i++)
        if(p[i].x<p[cur].x||
                (p[i].x==p[cur].x&&p[i].y<p[cur].y))cur=i;
    swap(p[l],p[cur]);
    tmp=p[l]; ans[p[l].id]=x;
    sort(p+l+1,p+r+1,cmp);
    ll now=l+1;
    for(int &y : G[x])
    {
        if(y==fa) continue;
        sol(now,now+size[y]-1,y,x);
        now+=size[y];
    }
}

int main(int argc, char const *argv[])
{
    n=read();
    for(int i=1; i<n; ++i)
        addedge(read(),read());
    ll x,y,w;
    for(int i=1; i<=n; ++i)
    {
        x=read(); y=read();
        p[i]=(Point) {x,y,i};
    }
    dfs(1,0); sol(1,n,1,0);
    for(ll i=1; i<=n; i++)
        printf("%lld%c",ans[i]," \n"[i==n]);
    return 0;
}


#include "iostream"
#include "algorithm"
#include "vector"
#include "set"
#include "map"
#include "cstring"
#include "string"
#include "vector"
#include "cassert"
#include "queue"
#include "cstdio"
#include "cstdlib"
#include "ctime"
#include "cmath"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 1500 + 5;

int n;
bool h[N];
int ans[N], X[N], Y[N], sub[N];
vector < int > v[N];

void dfs(int p, int x) {
    sub[x] = 1;
    for(auto u : v[x]) {
        if(u != p and !h[u]) {
            dfs(x, u);
            sub[x] += sub[u];
        }
    }
}

void solve(int x, vector < int > p) {
    sort(p.begin(), p.end(), [&](int x, int y){
        return X[x] != X[y] ? X[x] < X[y] : Y[x] < Y[y];
    });
    ans[p[0]] = x;
    sort(p.begin() + 1, p.end(), [&](int xx, int yy){
        return atan2(Y[xx] - Y[x], X[xx] - X[x]) < atan2(Y[yy] - Y[x], X[yy] - X[x]);
    });
    int it = 1;
    dfs(0, x);
    assert(sub[x] == p.size());
    h[x] = 1;
    for(auto u : v[x]) {
        if(!h[u]) {
            vector < int > np;
            while(sub[u]) {
                np.push_back(p[it++]);
                sub[u]--;
            }
            solve(u, np);
        }
    }
}

int main() {

    scanf("%d", &n);

    for(int i = 1; i < n; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    vector < int > v;

    for(int i = 1; i <= n; i++) {
        scanf("%d %d", X + i, Y + i);
        v.push_back(i);
    }

    solve(1, v);

    for(int i = 1; i <= n; i++)
        printf("%d ", ans[i]);

    puts("");

    return 0;

}


#include "iostream"
#include "algorithm"
#include "vector"
#include "set"
#include "map"
#include "cstring"
#include "string"
#include "vector"
#include "cassert"
#include "queue"
#include "cstdio"
#include "cstdlib"
#include "ctime"
#include "cmath"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 1500 + 5;

int n;
bool h[N];
int ans[N], X[N], Y[N], sub[N];
double atn[N];
vector < int > v[N];

void dfs(int p, int x) {
    sub[x] = 1;
    for(auto u : v[x]) {
        if(u != p and !h[u]) {
            dfs(x, u);
            sub[x] += sub[u];
        }
    }
}

void solve(int x, vector < int > p) {
    sort(p.begin(), p.end(), [&](int x, int y){
        return X[x] != X[y] ? X[x] < X[y] : Y[x] < Y[y];
    });
    ans[p[0]] = x;
    for(auto u : p) {
        atn[u] = atan2(Y[u] - Y[p[0]], X[u] - X[p[0]]);
    }
    sort(p.begin() + 1, p.end(), [&](int xx, int yy){
        return atn[xx] < atn[yy];
    });
    int it = 1;
    dfs(0, x);
    h[x] = 1;
    for(auto u : v[x]) {
        if(!h[u]) {
            vector < int > np;
            while(sub[u]) {
                np.push_back(p[it++]);
                sub[u]--;
            }
            solve(u, np);
        }
    }
}

int main() {

    scanf("%d", &n);

    for(int i = 1; i < n; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    vector < int > v;

    for(int i = 1; i <= n; i++) {
        scanf("%d %d", X + i, Y + i);
        v.push_back(i);
    }

    solve(1, v);

    for(int i = 1; i <= n; i++)
        printf("%d ", ans[i]);

    puts("");

    return 0;

}


#include "iostream"
#include "algorithm"
#include "vector"
#include "set"
#include "map"
#include "cstring"
#include "string"
#include "vector"
#include "cassert"
#include "queue"
#include "cstdio"
#include "cstdlib"
#include "ctime"
#include "cmath"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 1500 + 5;

int n;
bool h[N];
int ans[N], X[N], Y[N], sub[N];
vector < int > v[N];

void dfs(int p, int x) {
    sub[x] = 1;
    for(auto u : v[x]) {
        if(u != p and !h[u]) {
            dfs(x, u);
            sub[x] += sub[u];
        }
    }
}

void solve(int x, vector < int > p) {
    sort(p.begin(), p.end(), [&](int x, int y){
        return X[x] != X[y] ? X[x] < X[y] : Y[x] < Y[y];
    });
    ans[x] = p[0];
    sort(p.begin() + 1, p.end(), [&](int x, int y){
        return atan2(Y[x], X[x]) < atan2(Y[y], X[y]);
    });
    int it = 1;
    dfs(0, x);
    h[x] = 1;
    for(auto u : v[x]) {
        if(!h[u]) {
            vector < int > np;
            while(sub[u]) {
                np.push_back(p[it++]);
                sub[u]--;
            }
            solve(u, np);
        }
    }
}

int main() {

    scanf("%d", &n);

    for(int i = 1; i < n; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    vector < int > v;

    for(int i = 1; i <= n; i++) {
        scanf("%d %d", X + i, Y + i);
        v.push_back(i);
    }

    solve(1, v);

    for(int i = 1; i <= n; i++)
        printf("%d ", ans[i]);

    puts("");

    return 0;

}


#include "iostream"
#include "algorithm"
#include "vector"
#include "set"
#include "map"
#include "cstring"
#include "string"
#include "vector"
#include "cassert"
#include "queue"
#include "cstdio"
#include "cstdlib"
#include "ctime"
#include "cmath"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 1500 + 5;

int n;
bool h[N];
int ans[N], X[N], Y[N], sub[N];
vector < int > v[N];

void dfs(int p, int x) {
    sub[x] = 1;
    for(auto u : v[x]) {
        if(u != p and !h[u]) {
            dfs(x, u);
            sub[x] += sub[u];
        }
    }
}

void solve(int x, vector < int > p) {
    sort(p.begin(), p.end(), [&](int x, int y){
        return X[x] != X[y] ? X[x] < X[y] : Y[x] < Y[y];
    });
    ans[x] = p[0];
    sort(p.begin() + 1, p.end(), [&](int xx, int yy){
        return atan2(Y[xx] - Y[x], X[xx] - X[x]) < atan2(Y[yy] - Y[x], X[yy] - X[x]);
    });
    int it = 1;
    dfs(0, x);
    assert(sub[x] == p.size());
    h[x] = 1;
    for(auto u : v[x]) {
        if(!h[u]) {
            vector < int > np;
            while(sub[u]) {
                np.push_back(p[it++]);
                sub[u]--;
            }
            solve(u, np);
        }
    }
}

int main() {

    scanf("%d", &n);

    for(int i = 1; i < n; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    vector < int > v;

    for(int i = 1; i <= n; i++) {
        scanf("%d %d", X + i, Y + i);
        v.push_back(i);
    }

    solve(1, v);

    for(int i = 1; i <= n; i++)
        printf("%d ", ans[i]);

    puts("");

    return 0;

}


#include "iostream"
#include "algorithm"
#include "vector"
#include "set"
#include "map"
#include "cstring"
#include "string"
#include "vector"
#include "cassert"
#include "queue"
#include "cstdio"
#include "cstdlib"
#include "ctime"
#include "cmath"

using namespace std;

typedef long long ll;
typedef pair < int, int > ii;

const int N = 1500 + 5;

int n;
bool h[N];
int ans[N], X[N], Y[N], sub[N];
vector < int > v[N];

void dfs(int p, int x) {
    sub[x] = 1;
    for(auto u : v[x]) {
        if(u != p and !h[u]) {
            dfs(x, u);
            sub[x] += sub[u];
        }
    }
}

void solve(int x, vector < int > p) {
    sort(p.begin(), p.end(), [&](int x, int y){
        return X[x] != X[y] ? X[x] < X[y] : Y[x] < Y[y];
    });
    ans[p[0]] = x;
    sort(p.begin() + 1, p.end(), [&](int xx, int yy){
        return atan2(Y[xx] - Y[p[0]], X[xx] - X[p[0]]) < atan2(Y[yy] - Y[p[0]], X[yy] - X[p[0]]);
    });
    int it = 1;
    dfs(0, x);
    h[x] = 1;
    for(auto u : v[x]) {
        if(!h[u]) {
            vector < int > np;
            while(sub[u]) {
                np.push_back(p[it++]);
                sub[u]--;
            }
            solve(u, np);
        }
    }
}

int main() {

    scanf("%d", &n);

    for(int i = 1; i < n; i++) {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }

    vector < int > v;

    for(int i = 1; i <= n; i++) {
        scanf("%d %d", X + i, Y + i);
        v.push_back(i);
    }

    solve(1, v);

    for(int i = 1; i <= n; i++)
        printf("%d ", ans[i]);

    puts("");

    return 0;

}


#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

typedef long long LL;

const int N = 1510;

int X, Y;

struct node{
	int x, y;
	int id;
	friend bool operator < (const node &a, const node &b){
		return (LL)(a.y - Y) * (b.x - X) < (LL)(b.y - Y) * (a.x - X);
	}
} p[N];

vector <int> v[N];
int sz[N], ans[N];
int n;

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

void calc(int x, int fa, int l, int r){
	int t = l;
	rep(i, l + 1, r){
		if (p[i].y < p[t].y || (p[t].y == p[i].y && p[i].x < p[t].x))
			t = i;
	}

	if (t != l) swap(p[l], p[t]);
	ans[p[l].id] = x;
	X = p[l].x, Y = p[l].y;
	sort(p + l + 1, p + r + 1);
	int pos = l + 1;

	for (auto u : v[x]){
		if (u == fa) continue;
		calc(u, x, pos, pos + sz[u] - 1);
		pos += sz[u];
	}
}

int main(){

	scanf("%d", &n);
	rep(i, 1, n - 1){
		int x, y;
		scanf("%d%d", &x, &y);
		v[x].push_back(y);
		v[y].push_back(x);
	}

	rep(i, 1, n){
		int x, y;
		scanf("%d%d", &x, &y);
		p[i] = {x, y, i};
	}

	dfs(1, 0);
	calc(1, 0, 1, n);
	rep(i, 1, n) printf("%d\n", ans[i]);

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int maxn=2005;
int n;
int head[maxn],nxt[maxn<<1],to[maxn<<1],edge_tot;
void add_edge(int u,int v){nxt[++edge_tot]=head[u];head[u]=edge_tot;to[edge_tot]=v;}
int X,Y,root;
struct node{
	int x,y,id;
	bool operator < (const node&_)const{
		return (y-Y)*(_.x-X)<(_.y-Y)*(x-X);
	}
}A[maxn];
void find_root(int l,int r){
	root=l;
	for(int i=l+1;i<=r;i++)if(A[i].x<A[root].x||(A[i].x==A[root].x&&A[i].y>A[root].y))root=i;
}
int siz[maxn];
void dfs(int u,int f){
	siz[u]=1;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==f)continue;
		dfs(v,u);
		siz[u]+=siz[v];
	}
}
int ans[maxn];
void calc(int u,int f,int l,int r){
	find_root(l,r);
	swap(A[root],A[l]);
	ans[A[l].id]=u;
	X=A[l].x,Y=A[l].y;
	if(l==r)return;
	sort(A+1+l+1,A+1+r);
	int pos=l+1;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==f)continue;
		calc(v,u,pos,pos+siz[v]-1);
		pos+=siz[v];
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		A[i].x=x,A[i].y,A[i].id=i;
	}
	X=Y=0;
	sort(A+1,A+1+n);
	calc(1,0,1,n);
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
const int maxn=2e5+50;
const int inf=0x3f3f3f3f;
struct points{
	db x,y;
	int id,k;
	bool operator < (const points&_)const{
		return x<_.x;
	}
}A[maxn],ans1,ans2;
bool cmp_y(points a,points b){return a.y<b.y;}
int n,cnt,d;
db dist(points a,points b){return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));}
db short_path(points *A,int n){
	if(n==1)return 1e18;
	int m=n/2;
	db x=A[m].x;
	db d=min(short_path(A,m),short_path(A+m,n-m));
	inplace_merge(A,A+m,A+n,cmp_y);
	vector<points>v;
	for(int i=0;i<n;i++){
		if(fabs(A[i].x-x)>=d)continue;
		for(int j=v.size()-1;j>=0;j--){
			points e=v[j];
			if(fabs(A[i].y-e.y)>=d)break;
			if(dist(A[i],e)<d)ans1=A[i],ans2=e,d=dist(A[i],e);
		}
		v.push_back(A[i]);
	}
	v.clear();
	return d;
}
int main(){
	freopen("input.txt","r",stdin);
	freopen("output.txt","w",stdout);
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%lf%lf",&A[i].x,&A[i].y);
		if(A[i].x>=0&&A[i].y>=0)A[i].k=1;
		else if(A[i].x<0&&A[i].y<0)A[i].k=4;
		else if(A[i].x<0)A[i].k=2;
		else A[i].k=3;
		A[i].x=fabs(A[i].x),A[i].y=fabs(A[i].y),A[i].id=i+1;
		//printf("i=%d A[i].k=%d\n",i+1,A[i].k);
	}
	sort(A,A+n);
	short_path(A,n);
	printf("%d %d %d %d\n",ans1.id,ans1.k,ans2.id,5-ans2.k);
	return 0;
}


/* by Natsu Kinmoe */
/* 2020/07/20 */
#include <bits/stdc++.h>
using namespace std;

#define loop(i,n) for(int i=0;i<(n);i++)
#define pool(i,n) for(int i=(n)-1;i>=0;i--)
#define cont(i,n) for(int i=1;i<=(n);i++)
#define tnoc(i,n) for(int i=(n);i>=1;i--)
#define circ(i,a,b) for(int i=(a);i<=(b);i++)
#define cric(i,a,b) for(int i=(b);i>=(a);i--)
#define sub(i,a) for(int i=a;i;i=((i-1)&(a)))
#define subs(i,a) for(int i=a;i>=0;i=(!i?-1:((i-1)&(a))))
#define subt(i,a) for(int i=((a-1)&a);i;i=((i-1)&(a)))
#define subst(i,a) for(int i=((a-1)&a);i>=0;i=(!i?-1:((i-1)&(a))))
#define range(i,a,b,c) for(int i=(a);((c)>0?i<=(b):i>=(b));i+=(c))
#define foreach(it,v) for(__typeof((v).begin()) it=(v).begin(),_e_D_=(v).end();it!=_e_D_;it++)
#define parse(i,s) for(int i=0;s[i];i++)

#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define mak make_pair

#define y0 y0O0OO00OO0OO0OO0OOO00OO0OO0O0O000OO0
#define y1 y1II11II11III11I1III11II111IIII1II1I1
#define ws WSrAkIoi2333wSraKIoIWSraKiOi
#define left left_jTjTJtJtIoiiOiioIAuaU66666jtIOIau
#define hash whYusEthiSnamE_caNyoUusEothERnaMesliKeHSH

#define Mask(a) (1ll<<(a))
#define Maskx(a,x) ((a)<<(x))
#define Full(a) ((1ll<<(a))-1)
#define Bit(a,x) (((a)>>(x))&1)
#define all(a) (a).begin(),(a).end()
#define SZ(a) ((int)((a).size()))

typedef long long ll;
typedef long double lf;

const int Inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const lf inF=11451419198101145141919810.1145141919810;
const lf pi=acosl(-1);
/* Source code starts here */

int n;
vector<int> nei[1555];
int siz[1555];
int res[1555];

struct Point{
	int x,y,id;
	bool operator<(const Point &p)const{return x==p.x?y<p.y:x<p.x;}
}p[1555];

void predfs(int now,int lst){
	siz[now]=1;
	foreach(i,nei[now])if(*i!=lst){
		predfs(*i,now);
		siz[now]+=siz[*i];
	}
}

void dfs(int now,int lst,int l,int r){
	sort(p+l,p+r+1);
	Point &op=p[l];res[op.id]=now;l++;
	sort(p+l,p+r+1,[&](const Point &a,const Point &b){
		return 1ll*(b.x-op.x)*(a.y-op.y)-1ll*(a.x-op.x)*(b.y-op.y)<0;
	});
	foreach(i,nei[now])if(*i!=lst)dfs(*i,now,l,l+siz[*i]-1),l+=siz[*i];
}

int main(){
	scanf("%d",&n);
	loop(i,n-1){
		int u,v;scanf("%d%d",&u,&v);
		nei[u].pub(v);nei[v].pub(u);
	}
	cont(i,n)scanf("%d%d",&p[i].x,&p[i].y),p[i].id=i;
	predfs(1,0);
	dfs(1,0,1,n);
	cont(i,n)printf("%d%c",res[i]," \n"[i==n]);
	return 0;
}


/* by Natsu Kinmoe */
/* 2020/07/20 */
#include <bits/stdc++.h>
using namespace std;

#define loop(i,n) for(int i=0;i<(n);i++)
#define pool(i,n) for(int i=(n)-1;i>=0;i--)
#define cont(i,n) for(int i=1;i<=(n);i++)
#define tnoc(i,n) for(int i=(n);i>=1;i--)
#define circ(i,a,b) for(int i=(a);i<=(b);i++)
#define cric(i,a,b) for(int i=(b);i>=(a);i--)
#define sub(i,a) for(int i=a;i;i=((i-1)&(a)))
#define subs(i,a) for(int i=a;i>=0;i=(!i?-1:((i-1)&(a))))
#define subt(i,a) for(int i=((a-1)&a);i;i=((i-1)&(a)))
#define subst(i,a) for(int i=((a-1)&a);i>=0;i=(!i?-1:((i-1)&(a))))
#define range(i,a,b,c) for(int i=(a);((c)>0?i<=(b):i>=(b));i+=(c))
#define foreach(it,v) for(__typeof((v).begin()) it=(v).begin(),_e_D_=(v).end();it!=_e_D_;it++)
#define parse(i,s) for(int i=0;s[i];i++)

#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define mak make_pair

#define y0 y0O0OO00OO0OO0OO0OOO00OO0OO0O0O000OO0
#define y1 y1II11II11III11I1III11II111IIII1II1I1
#define ws WSrAkIoi2333wSraKIoIWSraKiOi
#define left left_jTjTJtJtIoiiOiioIAuaU66666jtIOIau
#define hash whYusEthiSnamE_caNyoUusEothERnaMesliKeHSH

#define Mask(a) (1ll<<(a))
#define Maskx(a,x) ((a)<<(x))
#define Full(a) ((1ll<<(a))-1)
#define Bit(a,x) (((a)>>(x))&1)
#define all(a) (a).begin(),(a).end()
#define SZ(a) ((int)((a).size()))

typedef long long ll;
typedef long double lf;

const int Inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const lf inF=11451419198101145141919810.1145141919810;
const lf pi=acosl(-1);
/* Source code starts here */

int n;
vector<int> nei[1555];
int siz[1555];
int res[1555];

struct Point{
	int x,y,id;
	bool operator<(const Point &p)const{return x==p.x?y<p.y:x<p.x;}
}p[1555];

void predfs(int now,int lst){
	siz[now]=1;
	foreach(i,nei[now])if(*i!=lst){
		predfs(*i,now);
		siz[now]+=siz[*i];
	}
}

void dfs(int now,int lst,int l,int r){
	sort(p+l,p+r+1);
	Point &op=p[l];res[op.id]=now;l++;
	sort(p+l,p+r+1,[&](const Point &a,const Point &b){
		return atan2(a.y-op.y,a.x-op.x)<atan2(b.y-op.y,b.x-op.x);
	});
	foreach(i,nei[now])if(*i!=lst)dfs(*i,now,l,l+siz[*i]-1),l+=siz[*i];
}

int main(){
	scanf("%d",&n);
	loop(i,n-1){
		int u,v;scanf("%d%d",&u,&v);
		nei[u].pub(v);nei[v].pub(u);
	}
	cont(i,n)scanf("%d%d",&p[i].x,&p[i].y),p[i].id=i;
	predfs(1,0);
	dfs(1,0,1,n);
	cont(i,n)printf("%d%c",res[i]," \n"[i==n]);
	return 0;
}


#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)
{
    int x;
    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,x=i,s=p[i];
    if(l==r) return ;
    swap(p[x],p[l]);
    sort(p+l+1,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=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)
{
    LL x=l;
    for(LL i=l+1;i<=r;i++)
        if(p[i].y<p[x].y||p[i].y==p[x].y&&p[i].x<p[x].x)
            x=i;
    if(x!=l) swap(p[x],p[l]);
    s=p[l],ans[p[l].id]=u;
    sort(p+l+1,p+r+1);
    LL last=l+1;
    for(int i=head[u];i!=0;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v==fa) continue;
        solve(v,u,last,last+size[v]-1);
        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("");
}