#include<bits/stdc++.h>
using namespace std;
const int N=10,M=1e6+7,K=200,p=1e9+7;
#define doge bitset<40>
int n,e[N],s[M],wf[K],q[N][K],f[N][N],ans[N][M];
doge op,wq[N][M];
unordered_map<doge,int>rt[N];
inline int read(){
	int num=0; char g=getchar(); while(g<48||57<g) g=getchar();
	while(47<g&&g<58) num=(num<<1)+(num<<3)+g-48,g=getchar(); return num;
}
inline long long pows(long long u,int v){
	long long ans=1; while(v>0) {if(v&1) ans=ans*u%p; u=u*u%p,v=v>>1;} return ans;
}
inline void find(int u){
	q[u][0]=0; int os=0,of=0;
	for(int i=0;i<(1<<n);i++) if(s[i]==u) q[u][++q[u][0]]=i,wf[i]=++os;
	for(int i=1;i<=e[u-1];i++){
		if(!ans[u-1][i]) continue;
		for(int h=1;h<(1<<n);h++){
			long long opq=1; for(int c=0;c<n;c++) if((1<<c)&h) opq=opq*f[u][c+1]%p; else opq=opq*(1-f[u][c+1]+p)%p;
			doge c=wq[u-1][i],hc=op;
			bool tg=0;
			for(int x=1;x<=q[u-1][0];x++){
				if(c[x]==1){
					for(int t=0;t<n;t++)
						if(((1<<t)&h)&&(!(q[u-1][x]&(1<<t)))){
							hc[wf[q[u-1][x]|(1<<t)]]=1,tg=1;
						}
				}
			}
			if(!tg) continue; int pos;
			if(rt[u][hc]==0) rt[u][hc]=++of,e[u]++,wq[u][e[u]]=hc;
			pos=rt[u][hc]; ans[u][pos]=(ans[u][pos]+opq*ans[u-1][i])%p;
		}
	}
}
int main(){
	n=read();
	for(int i=0;i<=(1<<n);i++) s[i]=__builtin_popcount(i);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) f[i][j]=read()*pows(100,p-2)%p; q[0][0]=1;
	e[0]=1,ans[0][1]=1,wq[0][1][1]=1; for(int i=1;i<=n;i++) find(i); cout<<ans[n][1]<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<pair<int, int> > vpii;
typedef pair<int, int> pii;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
typedef vector<ll> vll;
#define INF 0x3f3f3f3f
#define MOD 1000000007LL
#define INV 570000004LL
#define EPSILON 0.00001
#define f first
#define s second
#define pb push_back
#define mp make_pair

#define FOR(i, a, b) for (int i=(a); i<=(signed)(b); i++)
#define F0R(i, a) for (int i=0; i<(signed)(a); i++)
#define RFOR(i, a, b) for (int i=(a); i >= b; i--)

#define MN 22
int n;
ll p[MN][MN];
vi permsA[MN];
vi permsB[MN];
ll bmA[1<<MN];
ll bmB[1<<MN];
ll f[1<<MN];

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int t = 0;
    int aah[6] = {0, 1, 2, 3, 4, 5};
    do{
        if(aah[0] < aah[1] && aah[1] < aah[2] && aah[3] < aah[4] && aah[4] < aah[5]){
            permsA[t] = {aah[0], aah[1], aah[2]};
            permsB[t] = {aah[3], aah[4], aah[5]};
            ++t;
        }
    } while(next_permutation(aah, aah+6));

    cin >> n;
    F0R(i, n){
        F0R(j, n){
            cin >> p[i][j];
            p[i][j] = (p[i][j]*INV)%MOD;
        }
    }
    F0R(i, 6){
        FOR(j, n, 6-1){
            if(i == j) p[i][j] = 1;
            else{p[i][j] = 0; p[j][i] = 0;}
        }
    }
    n = 6;
    /*F0R(i, n){
        F0R(j, n){
            cout << p[i][j] << " ";
        }
        cout << "\n";
    }*/
    F0R(i, 1<<18){
        ll prob1 = 1;
        ll prob2 = 1;
        int bm1 = 0;
        int bm2 = 0;
        F0R(j, 6){
            F0R(k, 3){
                int res = j*3+k;
                if((1<<res) & i){
                    prob1 *= p[j][k];
                    prob2 *= p[j][k+3];
                } else{
                    prob1 *= (1+MOD-p[j][k]);
                    prob2 *= (1+MOD-p[j][k+3]);
                }
                prob1 %= MOD;
                prob2 %= MOD;
            }
        }
        F0R(ot, 20){
            int ord[3] = {0, 1, 2};
            bool ok = false;
            do{
                bool ok2 = true;
                F0R(j, 3){
                    int val = permsA[ot][ord[j]];
                    int loc = val*3+j;
                    if(!((1<<loc)&i)){
                        ok2 = false;
                        break;
                    }
                }
                if(ok2){
                    ok = true;
                    break;
                }
            } while(next_permutation(ord, ord+3));
            if(ok){
                bm1 ^= (1<<ot);
            }
        }
        F0R(ot, 20){
            int ord[3] = {0, 1, 2};
            bool ok = false;
            do{
                bool ok2 = true;
                F0R(j, 3){
                    int val = permsB[ot][ord[j]];
                    int loc = val*3+j;
                    if(!((1<<loc)&i)){
                        ok2 = false;
                        break;
                    }
                }
                if(ok2){
                    ok = true;
                    break;
                }
            } while(next_permutation(ord, ord+3));
            if(ok){
                bm2 ^= (1<<ot);
            }
        }
        /*if(prob1 != 0){
            cout << i << " 1 " << bm1 << " and " << prob1 << "\n";
        }
        if(prob2 != 0){
            cout << i << " 2 " << bm2 << " and " << prob2 << "\n";
        }*/
        bmA[bm1] = (bmA[bm1]+prob1)%MOD;
        bmB[bm2] = (bmB[bm2]+prob2)%MOD;
    }
    F0R(i, (1<<20)){
        f[i] = bmA[i];
        /*if(f[i] != 0){
            cout << i << " " << f[i] << "\n";
        }*/
    }
    F0R(i, 20){
        F0R(mask, (1<<20)){
            if(mask & (1<<i)){
                f[mask] += f[mask ^ (1<<i)];
                f[mask] %= MOD;
            }
        }
    }
    ll sm = 0;
    F0R(i, (1<<20)){
        int o = (1<<20)-1;
        /*if(bmA[i] != 0){
            cout << i << " " << bmA[i] << " " << f[i] << "\n";
        }*/
        sm += (bmB[i]*f[o^i]);
        sm %= MOD;
    }
    cout << (1+MOD-sm)%MOD << "\n";

    return 0;
}


#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/priority_queue.hpp>
#include<bits/stdc++.h>
#define all(v) (v).begin(),(v).end()
#define rep(i,l,r) for(int i=(l),i##end=(r);i<=i##end;++i)
using namespace __gnu_pbds;
using namespace std;
const int mod = 1e9 + 7;
const int maxn = 20;
inline void flush(){cout.flush(),fflush(stdout);}
typedef unsigned long long u64;
typedef unsigned u32;
typedef long long ll;
typedef long double ld;
template<typename t>using heap=__gnu_pbds::priority_queue<t>;
template<typename t>using rbt=tree<t,null_type,less<t>,rb_tree_tag,tree_order_statistics_node_update>;
template<typename t>inline istream&operator,(istream&cin,t&x){return cin>>x;}
template<typename t>inline ostream&operator,(ostream&cout,const t&x){return cout<<x;}
template<typename _1,typename _2>inline void up(_1&a,const _2&b){if(a<b)a=b;}
template<typename _1,typename _2>inline void down(_1&a,const _2&b){if(a>b)a=b;}
istream&in=cin;ostream&out=cout;
inline int pow(int a,int b){
    int ans=1;
    for(;b;b>>=1,a=ll(a)*a%mod)
        if(b&1)ans=ll(ans)*a%mod;
    return ans;
}
inline int inv(int a){return pow(a,mod-2);}
typedef long long ll;
int a[maxn][maxn];;
int ans,n;

const int N = 2001000;
int f[N],g[N],b[N];
int mp[N],tot[maxn];
inline void reduce(int & x){ x += x >> 31 & mod; }
inline void dfs(int x){
}
inline int fac(int x){ return x == 0 ? 1 : fac(x - 1) * x; }
inline int C(int n,int m){ return fac(n) / fac(m) / fac(n - m); }
inline int pc(int x){ return __builtin_popcount(x); }
vector<int> v[maxn];
inline void fwt(int * a,int lim){
	if(!(lim/=2)) return;
	for(int i=0;i<lim;++i) reduce(a[i] += a[i + lim] - mod);;
	fwt(a,lim),fwt(a + lim,lim);
}
inline void fwt2(int * a,int lim){
	if(!(lim/=2)) return;
	for(int i=0;i<lim;++i) reduce(a[i] -= a[i + lim]);
	fwt2(a,lim),fwt2(a + lim,lim);
}
main(){
	ios::sync_with_stdio(false),in.tie(0);
	in,n;
	rep(i,0,n-1) rep(j,0,n-1){
		in,a[i][j];
		a[i][j] = ll(a[i][j]) * inv(100) % mod;
		b[i * n + j] = a[i][j];
	}
	rep(i,0,(1<<n)-1){
		v[pc(i)].push_back(i);
		mp[i] = tot[pc(i)]++;
	}
	const int m = n / 2;
	rep(i,0,(1<<(m * n))-1){
		int p = 1; int S[3];
		for(int j=0;j<m * n;++j) p = ll(p) * (i >> j & 1 ? b[j] : mod + 1 - b[j]) % mod;
		for(int j=0;j<m;++j) S[j] = (i >> j * n) & ((1 << n) - 1);
		int st = 0;
		for(int j : v[m]){
			int s[3],tot = 0;
			for(int k=j;k;k&=k-1) s[tot++] = __builtin_ctz(k);
			sort(s,s + m);
			do{
				for(int j=0;j<m;++j)
					if((S[j] >> s[j] & 1) == 0) goto nxt;
				st |= 1 << mp[j];
				nxt:;
			}while(next_permutation(s,s+m));
		}
		reduce(f[st] += p - mod);
	}
	// fwt(f,1 << tot[m]);
	const int M = n - m;
	rep(i,0,(1<<(M * n))-1){
		int p = 1; int S[3];
		for(int j=0;j<M * n;++j) p = ll(p) * (i >> j & 1 ? b[j + n * m] : mod + 1 - b[j + n * m]) % mod;
		for(int j=0;j<M;++j) S[j] = (i >> j * n) & ((1 << n) - 1);
		int st = 0;
		for(int j : v[n - m]){
			int s[3],tot = 0;
			for(int k=j;k;k&=k-1) s[tot++] = __builtin_ctz(k);
			sort(s,s + M);
			do{
				for(int j=0;j<M;++j) if((S[j] >> s[j] & 1) == 0) goto nxt2;
				st |= 1 << mp[(~j) & (1 << n) - 1];
				nxt2:;
			}while(next_permutation(s,s+M));
		}
		reduce(g[st] += p - mod);
	}
	int ans = 0;
	fwt(f,1 << tot[m]); fwt(g,1 << tot[m]);
	for(int i=0;i<1<<tot[m];++i) f[i] = ll(f[i]) * g[i] % mod;
	fwt2(f,1<<tot[m]);
	for(int i=1;i<1<<tot[m];++i) reduce(ans += f[i] - mod);
	out,ans,'\n';
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 8;
const int SZ = 1048576 + 5;
const int MOD = 1000000007;

inline int inc(int a, int b) { return (a + b >= MOD) ? (a + b - MOD) : (a + b); }
inline int dec(int a, int b) { return (a >= b) ? (a - b) : (a + MOD - b); }
inline int mul(int a, int b) { return 1LL * a * b % MOD; }

inline void updata(int &x, int y) { x = inc(x,y); }

inline int power(int x, int k) {
	int tmp = 1;
	while(k) {
		if(k & 1) tmp = mul(tmp,x);
		x = mul(x,x);
		k >>= 1;
	}
	return tmp;
}

int n, a[maxn][maxn], inv100, g[maxn][maxn], p[SZ], num[7][7][7], all, Ans;

inline bool check(int x, int y, int z) {
	int pos[4], lis[4];
	lis[1] = x; lis[2] = y; lis[3] = z;
	for(int i = 1;i <= 3;i ++) pos[i] = i;
	do{
		int flag = 1;
		for(int i = 1;i <= 3;i ++) {
			if(!g[pos[i]][lis[i]]) flag = 0;
		}
		if(flag) return 1;
	}while(next_permutation(pos + 1,pos + 3 + 1));
	return 0;
}

void dfs1(int now, int x, int y) {
	bool used[7];
	if(!now) return;
//	cout << now << ' ' << x << ' ' << y << endl;
	if(now == 0 && x == 4 && y == 1) {
		int xxx;
		xxx ++;
	}
  if(x == 4) {
		for(int i = 1;i <= 6;i ++) used[i] = 1;
		int sta = 0;
		if(now) {
			int xxx;
			xxx ++;
		}
		for(int i = 1;i <= 6;i ++) {
			for(int j = i + 1;j <= 6;j ++) {
				for(int k = j + 1;k <= 6;k ++) {
					if(check(i,j,k)) {
						int X, Y, Z; X = Y = Z = - 1;
						used[i] = used[j] = used[k] = 0;
						for(int l = 1;l <= 6;l ++) {
							if(!used[l]) continue;
							if(X == -1) X = l;
							else if(Y == -1) Y = l;
							else Z = l;
						}
						used[i] = used[j] = used[k] = 1;
						if(Z == -1) continue;
            sta |= num[X][Y][Z];
					}
				}
			}
		}
		updata(p[sta],now);
		return;
	}
	g[x][y] = 1; int nxt = mul(now,a[x][y]);
	if(y == 6) dfs1(nxt,x + 1,1);
	else dfs1(nxt,x,y + 1);
	g[x][y] = 0; nxt = mul(now,dec(1,a[x][y]));
	if(y == 6) dfs1(nxt,x + 1,1);
	else dfs1(nxt,x,y + 1);
}

void dfs2(int now, int x, int y) {
	if(!now) return;
	if(x == 7) {
		int sta = 0;
		for(int i = 1;i <= 6;i ++) {
			for(int j = i + 1;j <= 6;j ++) {
				for(int k = j + 1;k <= 6;k ++) {
					if(check(i,j,k)) sta |= num[i][j][k];
				}
			}
		}
		updata(Ans,mul(now,p[all ^ sta]));
		return;
	}
  g[x - 3][y] = 1; int nxt = mul(now,a[x][y]);
	if(y == 6) dfs2(nxt,x + 1,1);
	else dfs2(nxt,x,y + 1);
	g[x - 3][y] = 0; nxt = mul(now,dec(1,a[x][y]));
	if(y == 6) dfs2(nxt,x + 1,1);
	else dfs2(nxt,x,y + 1);
}

int main() {
//	freopen("data1.in","r",stdin);
  scanf("%d", &n); inv100 = power(100,MOD - 2);
	for(int i = 1;i <= n;i ++) {
		for(int j = 1;j <= n;j ++) scanf("%d", &a[i][j]), a[i][j] = mul(a[i][j],inv100);
	}
	for(int i = n + 1;i <= 6;i ++) a[i][i] = 1;
	int cnt = 0;
	for(int i = 1;i <= 6;i ++) {
		for(int j = i + 1;j <= 6;j ++) {
			for(int k = j + 1;k <= 6;k ++) {
				num[i][j][k] = 1 << cnt;
				cnt ++;
			}
		}
	}
	all = (1 << cnt) - 1;
	dfs1(1,1,1);
//	puts("");
	for(int j = 0;j < cnt;j ++) {
		for(int i = 0;i < (1 << cnt);i ++) {
			if(i & (1 << j)) updata(p[i],p[i ^ (1 << j)]);
		}
	}
//	for(int i = 0;i < (1 << cnt);i ++) if(p[i]) printf("%d %d\n", i, p[i]);
	Ans = 0;
	dfs2(1,4,1);
	Ans = dec(1,Ans);
	printf("%d\n", Ans);
	return 0;
}


#include<bits/stdc++.h>
#define LL long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
using namespace std;
inline int read(){
	int v=0,f=1;
	char c=getchar();
	while (c<'0' || c>'9'){
		if (c=='-') f=-1;
		c=getchar();
	}
	while (c>='0' && c<='9'){
		v=v*10+c-'0';
		c=getchar();
	}
	return v*f;
}
const int Maxn=10;
const LL mod=1e9+7;
LL qp(LL x,LL p){
	LL ret=1;
	while (p){
		if (p&1) ret=ret*x%mod;
		x=x*x%mod;
		p>>=1;
	}
	return ret;
}
LL inv(LL x){
	return qp(x,mod-2);
}
int p[Maxn][Maxn],n;
int id[64],ki,X[1048576],Y[1048576];
void add(int &x,int y){
	x+=y;
	if (x>=mod) x-=mod;
}
void sub(int &x,int y){
	x-=y;
	if (x<0) x+=mod;
}
void FWT(int *P,int opt)
{
	int N=1048576;
    for(int i=2;i<=N;i<<=1)
        for(int p=i>>1,j=0;j<N;j+=i)
            for(int k=j;k<j+p;++k)
                if (opt==1) add(P[k],P[k+p]);
                else sub(P[k],P[k+p]);
}
int main(){
	scanf("%d",&n);
	for (int i=0;i<n;i++){
		for (int j=0;j<n;j++){
			scanf("%d",&p[i][j]);
			p[i][j]=1ll*p[i][j]*inv(100)%mod;
		}
	}
	if (n<6){
		for (int i=n;i<6;i++){
			p[i][i]=1;
		}
		n=6;
	}
	int A=(1<<6)-1;
	for (int i=0;i<64;i++){
		if (__builtin_popcount(i)==3){
			id[i]=ki++;
		}
	}
	for (int i=0;i<(1<<18);i++){
		int msk1=i&A,msk2=i>>6&A,msk3=i>>12&A;
		int mask=0;
		LL pp=1;
		for (int j=0;j<6;j++){
			if (msk1>>j&1){
				pp=pp*p[0][j]%mod;
			}
			else{
				pp=pp*(mod+1-p[0][j])%mod;
			}
		}
		for (int j=0;j<6;j++){
			if (msk2>>j&1){
				pp=pp*p[1][j]%mod;
			}
			else{
				pp=pp*(mod+1-p[1][j])%mod;
			}
		}
		for (int j=0;j<6;j++){
			if (msk3>>j&1){
				pp=pp*p[2][j]%mod;
			}
			else{
				pp=pp*(mod+1-p[2][j])%mod;
			}
		}
		if (!p) continue;
		for (int a=0;a<6;a++){
			if (msk1>>a&1){
				for (int b=0;b<6;b++){
					if (a==b) continue;
					if (msk2>>b&1){
						for (int c=0;c<6;c++){
							if (a==c || b==c) continue;
							if (msk3>>c&1){
								int nmsk=(1<<a)|(1<<b)|(1<<c);
								mask|=1<<id[nmsk];
							}
						}
					}
				}
			}
		}
		add(X[mask],pp);
	}

	for (int i=0;i<(1<<18);i++){
		int msk1=i&A,msk2=i>>6&A,msk3=i>>12&A;
		int mask=0;
		LL pp=1;
		for (int j=0;j<6;j++){
			if (msk1>>j&1){
				pp=pp*p[3][j]%mod;
			}
			else{
				pp=pp*(mod+1-p[3][j])%mod;
			}
		}
		for (int j=0;j<6;j++){
			if (msk2>>j&1){
				pp=pp*p[4][j]%mod;
			}
			else{
				pp=pp*(mod+1-p[4][j])%mod;
			}
		}
		for (int j=0;j<6;j++){
			if (msk3>>j&1){
				pp=pp*p[5][j]%mod;
			}
			else{
				pp=pp*(mod+1-p[5][j])%mod;
			}
		}
		if (!p) continue;
		for (int a=0;a<6;a++){
			if (msk1>>a&1){
				for (int b=0;b<6;b++){
					if (a==b) continue;
					if (msk2>>b&1){
						for (int c=0;c<6;c++){
							if (a==c || b==c) continue;
							if (msk3>>c&1){
								int nmsk=(1<<a)|(1<<b)|(1<<c);
								nmsk^=A;
								mask|=1<<id[nmsk];
							}
						}
					}
				}
			}
		}
		add(Y[mask],pp);
	}
	FWT(X,1);
	FWT(Y,1);
	for (int i=0;i<1048576;i++){
		X[i]=1ll*X[i]*Y[i]%mod;
	}
	FWT(X,-1);
	int ans=0;
	for (int i=1;i<1048576;i++) add(ans,X[i]);
	printf("%d\n",ans);
	return 0;
}


// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(),x.end()
#define all(x) x.begin(),x.end()
#define fi first
#define se second
#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define erase_duplicates(x) sort(all(x)); (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template<typename T>
using ordered_set = tree<
T,
null_type,
less<T>,
rb_tree_tag,
tree_order_statistics_node_update>;

//X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
//X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD,LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<" = "<<h<<endl; }
template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while(*sdbg!=',')cerr<<*sdbg++;
  cerr<<" = "<<h<<", "; _dbg(sdbg+1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr if(0)cout
#endif

const int maxn = (1<<20)+7;
const int maxk = 20;
const int inf = (1e9)+7;
const LL LLinf = ((LL)1e18)+7LL;
const LD eps = 1e-9;
const LL mod = 1e9+7;

// ***************************** CODE ***************************** //

int tab[maxk][maxk];
int elo[maxk][maxk];
int maska[maxn];

LL dp[maxn][2];

int daj(VPII kraw, bool f)
{
  int mask = 0;
  for(int i = 0;i < SZ(kraw);i++)
    for(int j = i + 1;j < SZ(kraw);j++)
      if(kraw[i].fi != kraw[j].fi and kraw[i].se != kraw[j].se)
        for(int k = j + 1;k < SZ(kraw);k++)
          if(kraw[i].fi != kraw[k].fi and kraw[j].fi != kraw[k].fi and kraw[i].se != kraw[k].se and kraw[j].se != kraw[k].se)
            mask |= maska[(f ? 126 : 0) ^ ((1<<kraw[i].se) + (1<<kraw[j].se) + (1<<kraw[k].se))];
  return mask;
}

LL pot(LL a, LL w)
{
  if(!w) return 1;
  LL b = pot(a, w / 2);
  b = b * b % mod;
  if(w & 1)
    b = b * a % mod;
  return b;
}

int main()
{
	_upgrade
  int n;
  cin>>n;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      cin>>tab[i][j];
  int xd = 0;
  for(int i = 1;i <= 6;i++)
    for(int j = i + 1;j <= 6;j++)
      for(int k = j + 1;k <= 6;k++)
        maska[(1<<i) ^ (1<<j) ^ (1<<k)] = (1<<xd++);
  for(int i = n + 1;i <= 6;i++)
    tab[i][i] = 100;
  VPII kraw;
  n = 6;
  for(int i = 1;i <= n;i++)
    for(int j = 1;j <= n;j++)
      kraw.pb({i, j});
  LL odw = pot(100, mod - 2);
  for(int k = 0;k < 2;k++)
    for(int i = 0;i < (1<<18);i++)
    {
      LL p = 1LL;
      VPII xd;
      for(int j = 0;j < 18;j++)
        if((1<<j) & i)
        {
          p = p * tab[kraw[j + k * 18].fi][kraw[j + k * 18].se] % mod * odw % mod;//pot(100, mod - 2) % mod;
          xd.pb(kraw[j + k * 18]);
        }
        else
        {
          p = p * (100 - tab[kraw[j + k * 18].fi][kraw[j + k * 18].se]) % mod * odw % mod;//* pot(100, mod - 2) % mod;
        }
      int cur = daj(xd, k);
      dp[cur][k] += p;
      dp[cur][k] %= mod;
    }
  LL res = 1;
  for(int i = 0;i < 20;i++)
    for(int j = 0;j < (1<<20);j++)
      if((1<<i) & j)
      {
        dp[j][0] += dp[j ^ (1<<i)][0];
        dp[j][0] %= mod;
      }
  for(int i = 0;i < (1<<20);i++)
    res = (res - dp[i][0] * dp[((1<<20) - 1) ^ i][1]) % mod;
  res += mod;
  res %= mod;
  cout<<res;
	return 0;
}


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

typedef bitset<128> u99;

constexpr const int mod = 1000000007;
constexpr const int inv =  570000004;
constexpr int add(int a, int b) { return a + b < mod ? a + b : a + b - mod; }
constexpr int sub(int a, int b) { return a < b ? a - b + mod : a - b; }
constexpr int mul(int a, int b) { return 1LL * a * b % mod; }

unordered_map<u99, int> name;
int n, dfn, son[65536][128];
int dfs(u99 s) {
	auto ite = name.find(s);
	if (ite != name.end()) return ite->second;
	int ret = dfn++;
	name[s] = ret;
	for (int i = 0; i != (1 << n); ++i) {
		u99 t = s;
		for (int j = 0; j != (1 << n); ++j) if (!t[j])
			for (int k = i & j; k; k ^= k & -k) if (s[j ^ k & -k]) {
				t[j] = 1;
				break;
			}
		son[ret][i] = dfs(t);
	}
	return ret;
}

int p[7][7], q[7][128], dp[8][65536];

int main() {
	cin >> n;
	dfs(1);
	for (int i = 0; i != n; ++i) for (int j = 0; j != n; ++j) cin >> p[i][j], p[i][j] = mul(p[i][j], inv);
	for (int i = 0; i != n; ++i) for (int j = 0; j != (1 << n); ++j) {
		q[i][j] = 1;
		for (int k = 0; k != n; ++k) q[i][j] = mul(q[i][j], j >> k & 1 ? p[k][i] : sub(1, p[k][i]));
	}
	dp[0][0] = 1;
	for (int i = 0; i != n; ++i) for (int j = 0; j != dfn; ++j) for (int k = 0; k != (1 << n); ++k)
		dp[i + 1][son[j][k]] = add(dp[i + 1][son[j][k]], mul(dp[i][j], q[i][k]));
	u99 res;
	for (int i = 0; i != (1 << n); ++i) res[i] = 1;
	cout << dp[n][name[res]] << endl;
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
using ll = long long;
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif

template<unsigned int mod_>
struct ModInt{
	using uint = unsigned int;
	using ll = long long;
	using ull = unsigned long long;

	constexpr static uint mod = mod_;

	uint v;
	ModInt():v(0){}
	ModInt(ll _v):v(normS(_v%mod+mod)){}
	explicit operator bool() const {return v!=0;}
	static uint normS(const uint &x){return (x<mod)?x:x-mod;}		// [0 , 2*mod-1] -> [0 , mod-1]
	static ModInt make(const uint &x){ModInt m; m.v=x; return m;}
	ModInt operator+(const ModInt& b) const { return make(normS(v+b.v));}
	ModInt operator-(const ModInt& b) const { return make(normS(v+mod-b.v));}
	ModInt operator-() const { return make(normS(mod-v)); }
	ModInt operator*(const ModInt& b) const { return make((ull)v*b.v%mod);}
	ModInt operator/(const ModInt& b) const { return *this*b.inv();}
	ModInt& operator+=(const ModInt& b){ return *this=*this+b;}
	ModInt& operator-=(const ModInt& b){ return *this=*this-b;}
	ModInt& operator*=(const ModInt& b){ return *this=*this*b;}
	ModInt& operator/=(const ModInt& b){ return *this=*this/b;}
	ModInt& operator++(int){ return *this=*this+1;}
	ModInt& operator--(int){ return *this=*this-1;}
	ll extgcd(ll a,ll b,ll &x,ll &y) const{
		ll p[]={a,1,0},q[]={b,0,1};
		while(*q){
			ll t=*p/ *q;
			rep(i,3) swap(p[i]-=t*q[i],q[i]);
		}
		if(p[0]<0) rep(i,3) p[i]=-p[i];
		x=p[1],y=p[2];
		return p[0];
	}
	ModInt inv() const {
		ll x,y;
		extgcd(v,mod,x,y);
		return make(normS(x+mod));
	}
	ModInt pow(ll p) const {
		if(p<0) return inv().pow(-p);
		ModInt a = 1;
		ModInt x = *this;
		while(p){
			if(p&1) a *= x;
			x *= x;
			p >>= 1;
		}
		return a;
	}
	bool operator==(const ModInt& b) const { return v==b.v;}
	bool operator!=(const ModInt& b) const { return v!=b.v;}
	friend istream& operator>>(istream &o,ModInt& x){
		ll tmp;
		o>>tmp;
		x=ModInt(tmp);
		return o;
	}
	friend ostream& operator<<(ostream &o,const ModInt& x){ return o<<x.v;}
};
using mint = ModInt<1000000007>;

using BS = bitset<128>;
bool B(int x,int i){return (x>>i)&1;}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	int N;
	cin >> N;
	VV<mint> p(N,V<mint>(N));
	rep(i,N) rep(j,N) cin >> p[i][j], p[i][j] /= 100;

	unordered_map<BS,mint> cur,nxt;
	{
		BS b;
		b[0] = true;
		cur[b] = 1;
	}
	rep(i,N){
		for(auto it: cur){
			BS b = it.fs;
			V<int> ones;
			rep(i,1<<N) if(b[i]) ones.pb(i);
			rep(e,1<<N){
				mint pr = 1;
				rep(j,N){
					if(B(e,j)) pr *= p[i][j];
					else pr *= mint(1) - p[i][j];
				}
				BS nb;
				for(int x: ones){
					rep(r,N) if(B(e,r) && !B(x,r)) nb[x|(1<<r)] = true;
				}
				nxt[nb] += it.sc * pr;
			}
		}
		cur = nxt;
		nxt.clear();
	}
	mint ans = 0;
	for(auto it: cur) if(it.fs[(1<<N)-1]) ans += it.sc;
	cout << ans << endl;
}


#include <iostream>
#include <vector>

using namespace std;

const long MAX_N = 1e3 + 1;

long n, m, h;
long aw[MAX_N];
long bw[MAX_N];
vector<long> g[MAX_N];
bool v[MAX_N];
vector<long> st;
vector< pair< pair<long, long>, long > > ans;

void add_edge(long a, long b) {
    g[a].push_back(b);
    g[b].push_back(a);
}

void try_flow(long i, long need) {
    if (i + 1 >= st.size()) return;

    long a = st[i], b = st[i + 1];

    long can = min(need, h - aw[b]);

    if (can > 0) {
        ans.push_back(make_pair(make_pair(a, b), can));
    }

    try_flow(i + 1, need);

    if (need - can > 0) {
        ans.push_back(make_pair(make_pair(a, b), need - can));
    }
}

void flow() {
    long a = st[0];
    long b = st[st.size() - 1];

    long need = min(aw[a] - bw[a], bw[b] - aw[b]);

    if (need > 0) {
        try_flow(0, need);
        aw[a] -= need; aw[b] += need;
    }
}

void dfs(long a) {
    v[a] = true; st.push_back(a);

    if (aw[a] < bw[a]) flow();

    for (size_t i = 0; i < g[a].size(); i++) {
        long b = g[a][i];
        if (!v[b]) dfs(b);
    }

    st.pop_back();
}

int main() {
    cin >> n >> h >> m;

    for (long i = 1; i <= n; i++) {
        cin >> aw[i];
    }

    for (long i = 1; i <= n; i++) {
        cin >> bw[i];
    }

    for (long i = 1; i <= m; i++) {
        long x, y; cin >> x >> y;
        add_edge(x, y);
    }

    for (long i = 1; i <= n; i++) {
        if (aw[i] > bw[i]) {
            for (long j = 1; j <= n; j++)
                v[j] = false;

            dfs(i);
        }
    }

    for (long i = 1; i <= n; i++) {
        if (aw[i] != bw[i]) {
            cout << "NO"; return 0;
        }
    }

    cout << ans.size() << endl;
    for (size_t i = 0; i < ans.size(); i++) {
        cout << ans[i].first.first << " " << ans[i].first.second << " " << ans[i].second << endl;
    }

    return 0;
}//hello


/* Author haleyk10198 */
/* �@��:  haleyk10198 */
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <ctime>
#include <string>
#include <set>
#include <stack>

#define MOD 1000000007
#define LINF (1LL<<60)
#define INF 2147483647
#define PI 3.1415926535897932384626433
#define ll long long
#define pii pair<int,int>
#define mp(x,y) make_pair((x),(y))

using namespace std;
typedef pair<pair<int,int>,int> cmd;

int a[310],b[310];

int n,v,e;
bool vis[310];
vector<int> near[310];
vector<int> p;

bool f;
vector<cmd> out;

void rec(int pos,int req){
	int rem=min(req,a[p[pos]]);
	if(rem)
		out.push_back(mp(mp(p[pos],p[pos+1]),rem));
	if(pos)
		rec(pos-1,req);
	rem=req-rem;
	if(rem)
		out.push_back(mp(mp(p[pos],p[pos+1]),rem));
}

void dfs(int now,int root){
	p.push_back(now);
	vis[now]=true;
	if(a[now]<b[now]&&a[root]>b[root]){
		int v=min(b[now]-a[now],a[root]-b[root]);
		rec(p.size()-2,v);
		a[now]+=v;a[root]-=v;
	}
	for(int x:near[now])
		if(!vis[x])
			dfs(x,root);
	p.pop_back();
}

int main(){
	//freopen("317C.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	ios_base::sync_with_stdio(false);
	cin>>n>>v>>e;
	for(int i=0;i<n;i++)
		cin>>a[i];
	for(int i=0;i<n;i++)
		cin>>b[i];
	for(int i=0;i<e;i++){
		int u,v;
		cin>>u>>v;
		near[--u].push_back(--v);
		near[v].push_back(u);
	}
	for(int i=0;i<n;i++){
		if(a[i]>b[i]){
			fill(vis,vis+n,0);
			dfs(i,i);
		}
	}
	for(int i=0;i<n;i++)
		if(a[i]!=b[i])
			f=true;
	if(f)
		cout<<"NO"<<endl;
	else{
		cout<<out.size()<<endl;
		for(cmd &x:out)
			cout<<++x.first.first<<" "<<++x.first.second<<" "<<x.second<<endl;
	}
	return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
using namespace std;
#define vi vector<int>
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define SZ(x) (int)(x.size())
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
#define inf 1000000007
#define mod 1000000007
#define x first
#define y second
#define pi acos(-1.0)
#define DBG(x) cerr<<(#x)<<"="<<x<<"\n";
//#define dprintf(...)
#define hash _hash
//#define dprintf(...) fprintf(outFile,__VA_ARGS__)

#define FOREACH(it,x) for(__typeof(x.begin()) it=x.begin();it!=x.end();it++)
#define ull unsigned long long
#define ll long long
#define N 100010

template <class T,class U>inline void Max(T &a,U b){if(a<b)a=b;}
template <class T,class U>inline void Min(T &a,U b){if(a>b)a=b;}

//FILE* outFile;

inline void add(int &a,int b){a+=b;while(a>=mod)a-=mod;}

int pow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=ans*(ll)a%mod;
        a=(ll)a*a%mod;b>>=1;
    }
    return ans;
}

ll s;
int V,a[303],b[303],v[303],rt;
vi g[303],e[303],q;
vector<pair<pii,int> >ans;
void up(int u,int fa){
    FOREACH(it,g[u]){
        int j=*it;
        if(v[j]==2||j==fa)continue;
        up(j,u);
    }
    if(fa!=-1&&fa!=rt){
        int x=min(V-a[fa],a[u]);
        if(x){
            ans.pb(mp(mp(u,fa),x));
            a[fa]+=x,a[u]-=x;
        }
    }
    else if(fa==rt&&b[fa]>a[fa]){
        int x=min(b[fa]-a[fa],a[u]);
        if(x){
            ans.pb(mp(mp(u,fa),x));
            a[fa]+=x,a[u]-=x;
        }
    }
}
void down(int u,int fa){
    FOREACH(it,g[u]){
        int j=*it;
        if(v[j]==2||j==fa)continue;
        down(j,u);
    }
    if(fa!=-1&&fa!=rt){
        int x=min(a[fa],V-a[u]);
        if(x){
            ans.pb(mp(mp(fa,u),x));
            a[fa]-=x,a[u]+=x;
        }
    }
    else if(fa==rt&&b[fa]<a[fa]){
        int x=min(a[fa]-b[fa],V-a[u]);
        if(x){
            ans.pb(mp(mp(fa,u),x));
            a[fa]-=x,a[u]+=x;
        }
    }
}
void dfs(int u){
    v[u]=1;s+=a[u]-b[u];
    FOREACH(it,e[u]){
        int j=*it;
        if(!v[j]){
            g[u].pb(j);g[j].pb(u);
            dfs(j);
        }
    }
    q.pb(u);
}
int main(){
    int n,i,j,k,K,T,m;
    scanf("%d%d%d",&n,&V,&m);
    rep(i,0,n)scanf("%d",&a[i]);
    rep(i,0,n)scanf("%d",&b[i]);
    rep(i,0,m){
        scanf("%d%d",&j,&k),j--,k--;
        e[j].pb(k),e[k].pb(j);
    }
    rep(i,0,n)if(!v[i]){
        s=0;dfs(i);
        if(s){puts("NO");return 0;}
        rep(j,0,SZ(q)){
            int x=q[j];rt=x;
            if(a[x]<b[x])up(x,-1);
            else if(a[x]>b[x])down(x,-1);
            v[x]=2;
        }
        q.clear();
    }
    printf("%d\n",SZ(ans));
    FOREACH(it,ans){
        printf("%d %d %d\n",(it->x).x+1,(it->x).y+1,it->y);
    }
    return 0;
}


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

int N, V, E;
int mat[301][301];
int A[301], B[301];
vector<pair<pair<int, int>, int> > R;

void flow2(vector<int>& P, int si, int ti, int d) {
	int i;
	if (si == ti) return;
	if (A[P[si + 1]] + d <= V) {
		A[P[si]] -= d;
		A[P[si + 1]] += d;
		R.push_back(make_pair(make_pair(P[si], P[si + 1]), d));
		flow2(P, si + 1, ti, d);
	}
	else {
		int d2 = V - A[P[si + 1]];
		A[P[si]] -= d2;
		A[P[si + 1]] += d2;
		if (d2 > 0) R.push_back(make_pair(make_pair(P[si], P[si + 1]), d2));
		flow2(P, si + 1, ti, d);
		A[P[si]] -= d - d2;
		A[P[si + 1]] += d - d2;
		R.push_back(make_pair(make_pair(P[si], P[si + 1]), d - d2));
	}
}

#define FOR(y, N) for (y = 0; y < N; ++y)

void flow(int s, int t, int d) {
	int i, j, y;
	vector<int> P;
	P.push_back(s);
	for (i = s; i != t;) {
		FOR(y, N) if (mat[i][y] == 1 && mat[y][t] == mat[i][t] - 1) break;
		P.push_back(i = y);
	}

	flow2(P, 0, P.size() - 1, d);
}

#define _P printf

void solve() {
	int f, r, i, j, k, l, x, y;

	cin >> N >> V >> E;
	FOR(i, N) cin >> A[i];
	FOR(i, N) cin >> B[i];

	FOR(x, N) FOR(y, N) mat[x][y] = 9999;
	FOR(x, N) mat[x][x] = 0;
	FOR(i, E) {
		cin >> x >> y;
		mat[x - 1][y - 1] = mat[y - 1][x - 1] = 1;
	}
	FOR(i, N) FOR(j, N) FOR(k, N) mat[j][k] = min(mat[j][k], mat[j][i] + mat[i][k]);
	FOR(x, N) FOR(y, N) {
		if (mat[x][y] > N) continue;
		j = min(A[x] - B[x], B[y] - A[y]);
		if (j <= 0) continue;
		flow(x, y, j);
	}

	FOR(x, N) if (A[x] != B[x]) return (void)_P("NO\n");
	_P("%d\n", R.size());
	FOR(i, R.size()) _P("%d %d %d\n", R[i].first.first + 1, R[i].first.second + 1, R[i].second);
}

int main()
{
	solve();
	return 0;
}


#include <iostream>
#include <vector>

using namespace std;

const long MAX_N = 1e3 + 1;

long n, m, h;
long aw[MAX_N];
long bw[MAX_N];
vector<long> g[MAX_N];
bool v[MAX_N];
vector<long> st;
vector< pair< pair<long, long>, long > > ans;

void add_edge(long a, long b) {
    g[a].push_back(b);
    g[b].push_back(a);
}

void try_flow(long i, long need) {
    if (i + 1 >= st.size()) return;

    long a = st[i], b = st[i + 1];

    long can = min(need, h - aw[b]);

    if (can > 0) {
        ans.push_back(make_pair(make_pair(a, b), can));
    }

    try_flow(i + 1, need);

    if (need - can > 0) {
        ans.push_back(make_pair(make_pair(a, b), need - can));
    }
}

void flow() {
    long a = st[0];
    long b = st[st.size() - 1];

    long need = min(aw[a] - bw[a], bw[b] - aw[b]);

    if (need > 0) {
        try_flow(0, need);
        aw[a] -= need; aw[b] += need;
    }
}

void dfs(long a) {
    v[a] = true; st.push_back(a);

    if (aw[a] < bw[a]) flow();

    for (size_t i = 0; i < g[a].size(); i++) {
        long b = g[a][i];
        if (!v[b]) dfs(b);
    }

    st.pop_back();
}

int main() {
    cin >> n >> h >> m;

    for (long i = 1; i <= n; i++) {
        cin >> aw[i];
    }

    for (long i = 1; i <= n; i++) {
        cin >> bw[i];
    }

    for (long i = 1; i <= m; i++) {
        long x, y; cin >> x >> y;
        add_edge(x, y);
    }

    for (long i = 1; i <= n; i++) {
        if (aw[i] > bw[i]) {
            for (long j = 1; j <= n; j++)
                v[j] = false;

            dfs(i);
        }
    }

    for (long i = 1; i <= n; i++) {
        if (aw[i] != bw[i]) {
            cout << "NO"; return 0;
        }
    }

    cout << ans.size() << endl;
    for (size_t i = 0; i < ans.size(); i++) {
        cout << ans[i].first.first << " " << ans[i].first.second << " " << ans[i].second << endl;
    }

    return 0;
}


#include <iostream>
#include <string>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <map>
#include <queue>
#include<set>
#include<stack>
#include<cstdio>
#include <unordered_map>
#include <functional>
#define PI 3.14159265

using namespace std;

vector<int> node[301];
int b[301];
int c[301];
int parent[301];
bool visited[301];
stack<int> mo;
stack<int> le;
vector<pair<pair<int, int>,int>> ans;
bool find;
long long cpcum;

void checksum(int now)
{
    visited[now] = 1;
    cpcum += (c[now] - b[now]);
    if (c[now] - b[now] > 0) mo.push(now);
    else if (c[now] - b[now] < 0) le.push(now);
    for (int i = 0; i < node[now].size(); i++)
    {
        int next = node[now][i];
        if (visited[next]) continue;
        checksum(next);
    }
}

bool dfs(int now, int s, int t)
{
    for (int i = 0; i < node[now].size(); i++)
    {
        int next = node[now][i];
        if (parent[next] != -1) continue;
        parent[next] = now;
        if (next == t)
        {
            return true;
        }
        if (dfs(next, s, t)) return true;
    }
    return false;
}

void write(int s, int t,int d,int v)
{
    if (parent[t] == s)
    {
        ans.push_back(make_pair(make_pair(s, t), d));
        c[s] -= d;
        c[t] += d;
        return;
    }
    else if (c[parent[t]] >= d)
    {
        c[t] += d;
        c[parent[t]] -= d;
        ans.push_back(make_pair(make_pair(parent[t],t), d));
        write(s, parent[t], d, v);
    }
    else
    {
        ans.push_back(make_pair(make_pair(parent[t],t), c[parent[t]]));
        int temp = c[parent[t]];
        c[parent[t]] = 0;
        write(s, parent[t], d ,v);
        ans.push_back(make_pair(make_pair(parent[t], t), d - temp));
        c[t] += d;
        c[parent[t]] = temp;

    }

}

int main() {

    std::ios_base::sync_with_stdio(false);

    int n, v, e;
    cin >> n >> v >> e;
    int sum = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> c[i];
        sum += c[i];
    }
    for (int i = 1; i <= n; i++)
    {
        cin >> b[i];
        sum -= b[i];
    }
    if (sum != 0)
    {
        cout << "NO" << endl;
        return 0;
    }

    for (int i = 0; i < e; i++)
    {
        int u, v;
        cin >> u >> v;
        node[u].push_back(v);
        node[v].push_back(u);
    }

    memset(visited, false, sizeof(visited));
    for (int i = 1; i <= n; i++)
    {
        if (visited[i] == false)
        {
            cpcum = 0;
            checksum(i);
            if (cpcum != 0)
            {
                cout << "NO" << endl;
                return 0;
            }
            while (mo.size() > 0)
            {
                int s = mo.top();
                int t = le.top();
                //cout << s << " " << t << endl;
                for (int i = 0; i <= n; i++) parent[i] = -1;
                parent[s] = 0;
                dfs(s, s, t);
                int d = min(c[s] - b[s], b[t] - c[t]);
                write(s, t, d, v);
                if (c[s] == b[s]) mo.pop();
                if (c[t] == b[t]) le.pop();
            }
        }
    }

    cout << ans.size() << endl;
    for (int i = 0; i < ans.size(); i++)
    {
        cout << ans[i].first.first << " " << ans[i].first.second << " " << ans[i].second << endl;
    }
    //system("PAUSE");
    return 0;
}


#include <cstdio>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
const int NMax=400;
int G[NMax][NMax];
int N,V,E,A[NMax],B[NMax],father[NMax],father1[NMax];
vector<int> cur;
int Find(int a) {
	int R;
	for(R=a;father[R]!=-1;R=father[R]);
	return R;
}
int F[NMax],have[NMax];
int DFS(int a,int cnt) {
	int last=cnt;have[a]=1;
	for(int i=0;i<cur.size();i++) if(!have[cur[i]]&&father1[cur[i]]==-1&&G[a][cur[i]]){
		father1[cur[i]]=a;
		int take=DFS(cur[i],cnt);
		cnt-=take;
	}
	if(A[a]<B[a]) {
		int take=min(cnt,B[a]-A[a]);
		cnt-=take;
		A[a]+=take;
	}
	return F[a]=last-cnt;
}
vector<pair<pair<int,int>,int> >Q;
void getans(int a) {
	for(int i=0;i<cur.size();i++) if(father1[cur[i]]==a){
		if(F[cur[i]]+A[cur[i]]<=V) {
			if(F[cur[i]]>0)Q.push_back(make_pair(make_pair(a,cur[i]),F[cur[i]]));
			getans(cur[i]);
		}
	}
	for(int i=0;i<cur.size();i++) if(father1[cur[i]]==a) {
		if(F[cur[i]]+A[cur[i]]>V){
			if(V-A[cur[i]]>0)Q.push_back(make_pair(make_pair(a,cur[i]),V-A[cur[i]]));
			getans(cur[i]);
			//printf("%d %d %d\n",a,cur[i],F[cur[i]]);
			if(F[cur[i]]-(V-A[cur[i]])>0)Q.push_back(make_pair(make_pair(a,cur[i]),F[cur[i]]-(V-A[cur[i]])));
		}
	}
}
int main()
{
	memset(father,-1,sizeof(father));
	scanf("%d%d%d",&N,&V,&E);
	for(int i=1;i<=N;i++) scanf("%d",A+i);
	for(int i=1;i<=N;i++) scanf("%d",B+i);
	for(int i=1;i<=E;i++) {
		int x,y;
		scanf("%d%d",&x,&y);
		G[x][y]=G[y][x]=1;
		int x1=Find(x),x2=Find(y);
		if(x1!=x2) father[x1]=x2;
	}
	for(int i=1;i<=N;i++)if(father[i]==-1) {
		long long cnta=0,cntb=0;
		cur.clear();
		for(int j=1;j<=N;j++) if(Find(j)==i) {
			cur.push_back(j);
			cnta+=A[j];
			cntb+=B[j];
		}
		if(cnta!=cntb) {
			puts("NO");
			return 0;
		}
		for(int j=0;j<cur.size();j++) if(A[cur[j]]>B[cur[j]]){
			memset(have,0,sizeof(have));
			memset(father1,-1,sizeof(father1));
			DFS(cur[j],A[cur[j]]-B[cur[j]]);
			getans(cur[j]);
			A[cur[j]]=B[cur[j]];
		}
	}
	printf("%d\n",(int)Q.size());
	for(int i=0;i<Q.size();i++) printf("%d %d %d\n",Q[i].first.first,Q[i].first.second,Q[i].second);
	return 0;
}


#include<cstdio>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
#define N 300
#define LL long long
using namespace std;
int a[N],b[N];
int g[N][N];

int vis[N],cs;
int p[N],l;
int n;

bool path(int v){
	vis[v]=cs;
	p[++l]=v;
	if( b[v]>a[v] ) return 1;

	for(int i=0;i<n;++i)
		if(g[v][i] && vis[i]!=cs)
			if( path(i) )
				return 1;
	--l;
	return 0;
}

LL s1,s2;
bool aux[N];
void check(int v){
	aux[v]=1;
	s1+=a[v],s2+=b[v];
	for(int i=0;i<n;++i)
		if( g[v][i] && !aux[i])
			check(i);
}

vector<string> ans;
char buff[50];
void flow(int i,int flw){

	int v=p[i],u=p[i+1];
	if(a[v]<flw){
		sprintf(buff,"%d %d %d",v+1,u+1,a[v]);
		ans.push_back(buff);
		flow(i-1,flw);
		sprintf(buff,"%d %d %d",v+1,u+1,flw-a[v]);
		ans.push_back(buff);
	}else{
		sprintf(buff,"%d %d %d",v+1,u+1,flw);
		ans.push_back(buff);
		if(i)
			flow(i-1,flw);
	}

}

int main(){
	int v,e;scanf("%d%d%d",&n,&v,&e);
	for(int i=0;i<n;++i)
		scanf("%d",a+i);
	for(int i=0;i<n;++i)
		scanf("%d",b+i);
	for(int i=0,u,v;i<e;++i){
		scanf("%d%d",&u,&v),--u,--v;
		g[u][v]=g[v][u]=1;
	}
	for(int i=0;i<n && s1==s2 ; ++i)
		if(!aux[i])
			check(i);
	if(s1!=s2)
		printf("NO\n");
	else{
		int q[n],ft=0,bk=-1;
		for(int v=0;v<n;++v)
			if(b[v]<a[v])
				q[++bk]=v;
		while( ft<=bk ){
			int v=q[ft++];
			l=-1,++cs;
			path(v);
			int u=p[l];
			int flw=min(abs(a[v]-b[v]),abs(b[u]-a[u]));
			flow(l-1,flw);
			a[v]-=flw,a[u]+=flw;
			if(a[v]>b[v])
				q[++bk]=v;
		}
		printf("%d\n",ans.size());
		for(int i=0;i<ans.size();++i)
			printf("%s\n",ans[i].c_str());
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#define N 333
#define INF 1000000000

int abs(int a) { return a>0?a:-a;}

int n, m, dis[N][N], a[N], b[N];
vector<int> vs, vd, vt;

inline void save(int v, int u, int t) {
	vs.push_back(v+1);
	vd.push_back(u+1);
	vt.push_back(t);
}

void transfer(int v, int u, int t) {
	if(dis[v][u]==1) {
		save(v, u, t);
		return;
	}
	for(int i=0;i<n;i++) if(dis[v][i]==1 && dis[i][u]<dis[v][u]) {
		int tmp=t;
		if(a[i]<t) {
			save(v, i, t-a[i]);
			tmp -= t-a[i];
		}
		transfer(i, u, t);
		if(tmp!=0) save(v, i, tmp);
		break;
	}
}

int main() {
	int i, j, k, e;
	cin>>n>>m>>e;
	for(i=0;i<n;i++) for(j=0;j<n;j++) dis[i][j]=INF;
	for(i=0;i<n;i++) cin>>a[i];
	for(i=0;i<n;i++) cin>>b[i];
	for(i=0;i<e;i++) {
		int x, y;
		cin>>x>>y;
		dis[x-1][y-1] = dis[y-1][x-1] = 1;
	}
	for(k=0;k<n;k++) for(i=0;i<n;i++) for(j=0;j<n;j++) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	for(i=0;i<n;i++) if(a[i]!=b[i]) {
		int si = (a[i]-b[i])/abs(a[i]-b[i]);
		for(j=0;j<n;j++) if(dis[i][j]!=INF && a[j]!=b[j]) {
			int sj = (a[j]-b[j])/abs(a[j]-b[j]);
			if(si != sj) {
				int t = min(abs(a[i]-b[i]), abs(a[j]-b[j]));
				if(si==1) {
					transfer(i, j, t);
					a[i]-=t;
					a[j]+=t;
				}
				else {
					transfer(j, i, t);
					a[i]+=t;
					a[j]-=t;
				}
			}
			if(a[i]==b[i]) break;
		}
		if(a[i]!=b[i]) break;
	}
	if(i!=n) cout<<"NO"<<endl;
	else {
		cout<<vs.size()<<endl;
		for(i=0;i<vs.size();i++) cout<<vs[i]<<" "<<vd[i]<<" "<<vt[i]<<endl;
	}
	return 0;
}


#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<utility>
#include<cstring>

using namespace std;

typedef long long ll;

const int max_n = 300 + 10;

int n, w, m;
int par[max_n], seen[max_n], g;
bool mark[max_n];
vector<int>	adj[max_n];
vector<int>	gec, sec, vec;
ll sum1, sum2;
int a[max_n], b[max_n];
vector<pair<pair<int, int>, int>>	ans;

void dfs(int v, int p = -1){
	mark[v] = 1;
	sum1 += a[v];
	sum2 += b[v];
	seen[v] = g;
	par[v] = p;
	for (int u:adj[v])
		if (seen[u] == 0)
			dfs(u, v);
}

void flow(int s, int val){
	if (s == gec.size() - 1)	return;
	int rem = w - a[gec[s + 1]];
	int p1 = min(val, rem);
	ans.push_back({{gec[s], gec[s + 1]}, p1});
	a[gec[s]] -= p1;
	a[gec[s + 1]] += p1;
	flow(s + 1, val);

	ans.push_back({{gec[s], gec[s + 1]}, val - p1});
	a[gec[s]] -= val - p1;
	a[gec[s + 1]] += val - p1;
}

void get_path(int v){
	if (par[v] == -1){
		gec.push_back(v);
		return;
	}
	get_path(par[v]);
	gec.push_back(v);
}

int main(){
	scanf("%d%d%d", &n, &w, &m);
	for (int i = 0; i < n; i++)		scanf("%d", &a[i]);
	for (int i = 0; i < n; i++)		scanf("%d", &b[i]);

	for (int i = 0; i < m; i++){
		int a, b;	scanf("%d%d", &a, &b);	a--, b--;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}

	for (int i = 0; i < n; i++){
		if (mark[i])	continue;
		g++;
		sum1 = sum2 = 0;
		dfs(i);
		if (sum1 != sum2){
			printf("NO\n");
			return 0;
		}

		vec.clear();
		sec.clear();
		for (int j = 0; j < n; j++){
			if (seen[j] != g)	continue;
			if (a[j] > b[j])	vec.push_back(j);
			if (a[j] < b[j])	sec.push_back(j);
		}

		for (int j = 0; j < vec.size(); j++){
			while (a[sec.back()] == b[sec.back()])	sec.pop_back();
			int f = vec[j], gg = sec.back();
			int dif = min(a[f] - b[f], b[gg] - a[gg]);

			gec.clear();
			memset(seen, 0, sizeof(seen));
			dfs(f);
			get_path(gg);
			flow(0, dif);
			if (a[vec[j]] != b[vec[j]])	j--;
		}
	}

	printf("%d\n", (int)ans.size());
	for (int i = 0; i < ans.size(); i++)
		printf("%d %d %d\n", ans[i].first.first + 1, ans[i].first.second + 1, ans[i].second);
	return 0;
}


#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <numeric>
#include <deque>
#include <list>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <iterator>
#include <memory>
#include <utility>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define mset(a) memset(a,0,sizeof(a))
#define mmset(a) memset(a,-1,sizeof(a))
#define mcpy(a,b) memcpy(a,b,sizeof(a))

typedef double lf;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<lf,lf> pdd;
typedef vector<int> vi;

const int inf=1000000007;
const ll linf=1000000000000000000LL;
const lf eps=0.000001;
const lf pi=3.14159265358979323846;

template <class T> T abs(T k){return k>=0?k:-k;}
template <class T> T sqr(T n){return n*n;}
template <class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template <class T> T mod(T a,T b){return (a%b+b)%b;}
template <class T> T addmod(T a,T b,T c){return (T)mod((ll)a+b,(ll)c);}
template <class T> T mulmod(T a,T b,T c){return (T)mod((ll)a*b,(ll)c);}
template <class T> T powmod(T a,T b,T c){return (T)(b?mulmod(mod((T)sqr((ll)powmod(a,b>>1,c)),c),b&1?a:1,c):1);}
template <class T> void maxe(T &a,T b){a=max(a,b);}
template <class T> void mine(T &a,T b){a=min(a,b);}
template <class T> void mode(T &a,T b){a=mod(a,b);}
template <class T> void addmode(T &a,T b,T c){a=addmod(a,b,c);}
template <class T> void mulmode(T &a,T b,T c){a=mulmod(a,b,c);}
template <class T> void powmode(T &a,T b,T c){a=powmod(a,b,c);}

void fileio_in_out(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
void fileio_txt(){freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);}

//==================================================

const int N=333;

int test;
int n,m,k,ans;
int a[N],b[N];
pii p[N];
int x,y;
vector<int> e[N];
int flag[N],ok[N];
pair<pii,int> step[2*N*N];

int check()
{
    for(int i=1;i<=n;i++)
        if(a[i]!=b[i])
            return 0;
    return 1;
}

void trans(int x,int y,int d)
{
    step[ans++]=mp(mp(x,y),d);
    a[x]-=d;
    a[y]+=d;
}

void dfs(int x,int w)
{
    flag[x]=1;
    w-=a[x];
    for(int i=0;i<e[x].size();i++)
    {
        int y=e[x][i];
        if(w>0&&!flag[y])
        {
            if (!ok[y])
            {
                dfs(y,w);
                int d=min(w,a[y]);
                w-=d;
                trans(y,x,d);
            }
            else
            {
                trans(y,x,w);
                dfs(y,b[y]);
                w=0;
                if(a[y]<b[y])
                {
                    w=b[y]-a[y];
                    trans(x,y,w);
                }
            }
        }
    }
}

bool cmp(pii a,pii b)
{
    return a>b;
}

int main()
{
    //fileio_in_out();
    //fileio_txt();

    scanf("%d%d%d",&n,&k,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&b[i]);
        p[i]=mp(b[i],i);
    }
    while(m--)
    {
        scanf("%d%d",&x,&y);
        e[x].pb(y);
        e[y].pb(x);
    }

    sort(p+1,p+1+n,cmp);
    for(int i=1;i<=n;i++)
    {
        mset(flag);
        dfs(p[i].Y,p[i].X);
        ok[p[i].Y]=1;
    }

    if(check())
    {
        printf("%d\n",ans);
        for(int i=0;i<ans;i++)
            printf("%d %d %d\n",step[i].X.X,step[i].X.Y,step[i].Y);
    }
    else
        puts("NO");

    //system("pause");
    return 0;
}


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

const int maxn=3005;
struct node{
    long long r,l;
    node(long long r,long long l):r(r),l(l){}
    node():r(),l(){}
    bool operator<(const node& o) const{
        if(r==o.r) return l<o.l;
        else return r<o.r;
    }
    node operator+(const node& o) const{
        return node(r+o.r,l+o.l);
    }
}dp[maxn][maxn],g[maxn];
vector<int> E[maxn];
long long siz[maxn],w[maxn],b[maxn];
int n,m;

void dfs(int x,int fa){
    dp[x][1]=node(0,w[x]-b[x]);
    siz[x]=1;
    for(auto i:E[x]){
        if(i==fa) continue;
        dfs(i,x);
        for(int j=1;j<=m;j++) g[j]=node(-1,0);
        for(int j=1;j<=siz[x];j++){
            for(int k=1;k<=siz[i];k++){
                node t1,t2;
                t1=t2=dp[i][k];
                if(t2.l>0) t2.r++;
                t2.l=0;
                g[j+k-1]=max(g[j+k-1],dp[x][j]+t1);
                g[j+k]=max(g[j+k],dp[x][j]+t2);
            }
        }
        siz[x]+=siz[i];
        for(int j=1;j<=siz[x];j++) dp[x][j]=g[j];
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);

    int T;
    cin>>T;
    while(T--){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            E[i].clear();
            for(int j=1;j<=m;j++)
                dp[i][j]=node(-1,0);
        }
        for(int i=1;i<=n;i++) cin>>b[i];
        for(int i=1;i<=n;i++) cin>>w[i];
        for(int i=1;i<n;i++){
            int x,y;
            cin>>x>>y;
            E[x].push_back(y);
            E[y].push_back(x);
        }
        dfs(1,0);
        cout<<dp[1][m].r+(dp[1][m].l>0)<<'\n';
    }
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

#define pb push_back
const int maxn = 1600;

struct point {
	int x, y, pos;
};

point a[maxn], Global;
int ans[maxn], cnt[maxn], n;
vector <int> g[maxn];

long long sqr(long long x) {
	return x * 1ll * x;
}

long long vect(point p1, point p2, point p3) {
	return (p2.x - p1.x) * 1ll * (p3.y - p1.y) - (p3.x - p1.x) * 1ll * (p2.y - p1.y);
}

long long len(point p1, point p2) {
	return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);
}

bool cmp(point p1, point p2) {
	if (vect(Global, p1, p2) > 0 || (vect(Global, p1, p2) == 0 && len(Global, p1) < len(Global, p2)))
		return true;
	return false;
}

void rec(int l, int v, int p) {
	int u = l;

	for (int i = l; i < l + cnt[v]; ++i)
		if (a[i].y < a[u].y || (a[i].y == a[u].y && a[i].x < a[u].x))
			u = i;

	swap(a[u], a[l]);
	Global = a[l];
	sort(a + l + 1, a + l + cnt[v], cmp);

	ans[a[l].pos] = v;

	int pref = 1, to;

	for (int i = 0; i < (int)g[v].size(); ++i) {
		to = g[v][i];
		if (to == p)
			continue;
		rec(l + pref, to, v);
		pref += cnt[to];
	}

	return;
}

void dfs(int v, int p) {
	cnt[v] = 1;

	int to;

	for (int i = 0; i < (int)g[v].size(); ++i) {
		to = g[v][i];
		if (to == p)
			continue;
		dfs(to, v);
		cnt[v] += cnt[to];
	}

	return;
}

int main() {
        ios_base::sync_with_stdio(false);
	cin.tie(0);

	cin >> n;

	int u, v;

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

	for (int i = 1; i <= n; ++i) {
		cin >> a[i].x >> a[i].y;
		a[i].pos = i;
	}

	dfs(1, -1);

	rec(1, 1, -1);

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

	return 0;
}


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

const int N=1505;
int n,tot;
int lnk[N],nxt[2*N],son[2*N],sz[N],ans[N];
struct myt{
    int x,y,id;
}dot[N],t;

int read(){
    int s=0,w=1;
    char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') w=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    return s*w;
}

inline void add(int a,int b){son[++tot]=b;nxt[tot]=lnk[a];lnk[a]=tot;}

inline int cross(myt a,myt b,myt c){
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}

bool cmp(myt a,myt b){
    return cross(t,a,b)>0;
}

void dfs_size(int s,int fa){
    sz[s]=1;
    int j=lnk[s];
    while (j){
        if (son[j]==fa) {j=nxt[j];continue;}
        dfs_size(son[j],s);
        sz[s]+=sz[son[j]];
        j=nxt[j];
    }
    return;
}

void dfs_ans(int l,int r,int rt,int fa){
    int x=l;
    for (int i=l+1;i<=r;++i)
    if (dot[i].x<dot[x].x||(dot[i].x==dot[x].x&&dot[i].y<dot[x].y)) x=i;
    t=dot[x];dot[x]=dot[l];dot[l]=t;
    sort(dot+1+l,dot+1+r,cmp);
    ans[dot[l].id]=rt;
    int now=l+1,j=lnk[rt];
    while (j){
        if (son[j]==fa) {j=nxt[j];continue;}
        dfs_ans(now,now+sz[son[j]]-1,son[j],rt);
        now+=sz[son[j]];
        j=nxt[j];
    }
    return;
}

signed main(){
    n=read();
    for (int i=1;i<n;++i){
        int u=read(),v=read();
        add(u,v);add(v,u);
    }
    for (int i=1;i<=n;++i) dot[i].x=read(),dot[i].y=read(),dot[i].id=i;
    dfs_size(1,0);
    dfs_ans(1,n,1,0);
    for (int i=1;i<=n;++i) printf("%d ",ans[i]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 2000
#define ll long long
using namespace std;
ll n;
struct sett{
    ll x,y,id;
}p[N],plk;
struct zero{
    ll nxt,to;
}edge[N<<1];
ll tot=0,head[N];
ll size[N];
ll Ans[N];
void add_edge(ll a,ll b){
edge[++tot]=(zero){head[a],b};
head[a]=tot;
}
void aux(ll x,ll fa){
    size[x]=1;
    for(ll i=head[x];i;i=edge[i].nxt)
    {
        ll to=edge[i].to;
        if(to==fa)continue;
        aux(to,x);
        size[x]+=size[to];
    }
}
bool cmp(sett a,sett b)
{
    ll ax=a.x-plk.x,ay=a.y-plk.y,bx=b.x-plk.x,by=b.y-plk.y;
    if(ax>=0&&bx<=0)return 1;
    if(ax<=0&&bx>=0)return 0;
    return (ax*by>ay*bx);
}
void solve(ll l,ll r,ll x,ll fa){
    ll poss=l;
    for(ll i=l+1;i<=r;i++)
    if(p[i].x<p[poss].x||(p[i].x==p[poss].x&&p[i].y<p[poss].y))poss=i;
    swap(p[l],p[poss]);
    plk=p[l];
    Ans[p[l].id]=x;
    //cout<<"steps:"<<x<<" "<<p[l].id<<" "<<l<<" "<<r<<endl;
    sort(p+l+1,p+r+1,cmp);
    // for(int i=l+1;i<=r;i++)cout<<p[i].id<<" ";
    // cout<<endl;
    ll now=l+1;
    for(ll i=head[x];i;i=edge[i].nxt)
    {ll to=edge[i].to;
    if(to==fa)continue;
    solve(now,now+size[to]-1,to,x);
    now+=size[to];
    }
}
int main(){
    scanf("%lld",&n);
    for(ll i=1;i<n;i++)
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        add_edge(a,b);
        add_edge(b,a);
    }
    for(ll i=1;i<=n;i++){
        ll x,y;
        scanf("%lld%lld",&x,&y);
        p[i]=(sett){x,y,i};
    }
    aux(1,0);
    solve(1,n,1,0);
    for(ll i=1;i<=n;i++)
    printf("%lld ",Ans[i]);
}


#include<bits/stdc++.h>
#define int long long
using namespace std;
struct cd
{
    int x,y,id;
} a[500005],xx;
struct ab
{
    int f,t;
} t[500005];
int h,hh[500005],size[500005],ans[500005];
void make(int x,int y)
{
    t[++h].f=hh[x];
    t[h].t=y;
    hh[x]=h;
}
int cmp(cd x,cd y)
{
    if(x.x-xx.x>0&&y.x-xx.x<0) return 1;
    if(x.x-xx.x<0&&y.x-xx.x>0) return 0;
    return (x.x-xx.x)*(y.y-xx.y)>(x.y-xx.y)*(y.x-xx.x);
}
void dfs1(int x,int y)
{
    size[x]=1;
    for(int i=hh[x];i;i=t[i].f)
    {
        int j=t[i].t;
        if(j==y) continue;
        dfs1(j,x);
        size[x]+=size[j];
    }
}
void dfs2(int l,int r,int x,int y)
{
    for(int i=l+1;i<=r;i++)
    {
        if(a[i].x<a[l].x||(a[i].x==a[l].x&&a[i].y<a[l].y)) swap(a[i],a[l]);
    }
    ans[a[l].id]=x;
    xx=a[l];
    l++;
    sort(a+l,a+r+1,cmp);
    for(int i=hh[x];i;i=t[i].f)
    {
        int j=t[i].t;
        if(j==y) continue;
        dfs2(l,l+size[j]-1,j,x);
        l+=size[j];
    }
}
signed main()
{
    int n,x,y;
    scanf("%lld",&n);
    for(int i=1;i<n;i++)
    {
        scanf("%lld%lld",&x,&y);
        make(x,y);
        make(y,x);
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i].x,&a[i].y);
        a[i].id=i;
    }
    dfs1(1,0);
    dfs2(1,n,1,0);
    for(int i=1;i<=n;i++)
    {
        printf("%lld ",ans[i]);
    }
    return 0;
}


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

#define int long long
#ifdef __LOCALE__
#define see(a) std::cout << #a << "=" << a << std::endl
#else
#define see(a) //std::cout << #a << "=" << a << std::endl
#endif
#define foreach(a,b) for (int a=0;a<(int)b.size();a++)
#define rep(i,n) for (int i=0;i<n;i++)
#define repa(i,n) for (int i=1;i<=n;i++)
#define repi(i,a,b) for (int i=a;i<=b;i++)

struct Point {
    int x,y,org;
};

int sx,sy;

bool cmp (Point A,Point B) {
    A.x -= sx;
    A.y -= sy;
    B.x -= sx;
    B.y -= sy;
    return (A.y * B.x) < (A.x * B.y);
}

istream& operator >> (istream& in , Point& X) {
    in >> X.x >> X.y;
    return in;
}

const int N = 3005;
vector < int > e[N];
int size[N];
int ans[N];
Point pt[N];
int n;

void init(){
    scanf("%lld",&n);
    rep (i , n - 1) {
        int u,v;
        scanf("%lld%lld",&u,&v);
        e[u].push_back(v);
        e[v].push_back(u);
    }
    repa (i,n) {
        cin >> pt[i];
        pt[i].org = i;
    }
}

void Size(int u = 1,int f = 0){
    size[u] = 1;
    foreach (i,e[u]) {
        int v = e[u][i];
        if (v == f) continue;
        Size(v,u);
        size[u] += size[v];
    }
}

void solve(int l = 1 , int r = n , int u = 1,int f = 0) {
    //cout << l << ' ' << r << ' ' << u << ' ' << f << endl;
    repi (i,l + 1 , r) if (pt[i].x < pt[l].x) swap(pt[l] , pt[i]);
    sx = pt[l].x;
    sy = pt[l].y;
    sort(pt + l + 1, pt + r + 1,cmp);
    //repi (i,l , r) {
    //    cout << pt[i].x << ' '<< pt[i].y << ' ' << pt[i].org << endl;
    //}
    ans[ pt[l].org ] = u;
    int fs = l + 1;
    foreach (i,e[u]) {
        int v = e[u][i];
        if (v == f) continue;
        solve(fs , fs + size[v] - 1 , v , u);
        fs += size[v];
    }
}

#undef int
int main(){
    init();
    Size();
    solve();
    repa (i,n) printf("%lld ",ans[i]);
    puts("");
    return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
LL n,tot,h[3005],e[3005],b[3005],s[3005],f[3005];
struct Point
{
	LL v,p,x,y;
}p[3005];

int cmp1(const Point a,const Point b)
{
	return (a.x*b.y-a.y*b.x)>0;
}

int cmp2(const Point a,const Point b)
{
	return (a.p<b.p);
}

void Add(LL x,LL y)
{
	b[++tot]=y; e[tot]=h[x]; h[x]=tot;
}

void Dfs(LL x)
{
	s[x]=1;
	for (LL go=h[x];go;go=e[go])
		if (f[x]!=b[go])
			f[b[go]]=x,Dfs(b[go]),s[x]+=s[b[go]];
}

void Rec(LL x,LL l,LL r)
{
	LL pos=l;
	for (LL i=l+1;i<=r;i++) if(p[i].y<p[pos].y) pos=i;
	swap(p[pos],p[l]);
	p[l].v=x;
	pos=l+1;
	for (LL i=l+1;i<r+1;i++)
		p[i].x-=p[l].x,p[i].y-=p[l].y;
	sort(p+l+1,p+r+1,cmp1);
	for (LL go=h[x];go;go=e[go])
		if (b[go]!=f[x])
		{
			Rec(b[go],pos,pos+s[b[go]]-1);
			pos+=s[b[go]];
		}
}

int main()
{
	cin>>n;
	LL a,b;
	for (LL i=1;i<n;i++)
	{
		cin>>a>>b;
		Add(--a,--b); Add(b,a);
	}
	Dfs(0);
	for (LL i=0;i<n;i++)
		cin>>p[i].x>>p[i].y,p[i].p=i;
	Rec(0,0,n-1);
	sort(p,p+n,cmp2);
	for (LL i=0;i<n;i++)
		cout<<p[i].v+1<<' ';
	return 0;
}


#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <time.h>
#include <vector>

#if LOCAL
	#define DO_NOT_SEND
#endif

typedef long long LL;

int IntMaxVal = (int) 1e20;
int IntMinVal = (int) -1e20;
LL LongMaxVal = (LL) 1e20;
LL LongMinVal = (LL) -1e20;

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

#define minimize(a, b) { a = min(a, b); }
#define maximize(a, b) { a = max(a, b); }

#define all(v) v.begin(),v.end()

using namespace std;

#define endl '\n';
#define next(type, i) type i; cin >> i;
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define nextVector(t, v, size) vector< argument_type<void(t)>::type > v(size); { for (int i = 0 ; i < size ; i++) cin >> v[i]; }

#define range(name, start, count) vector<int> name(count); { for (int i = 0 ; i < count ; i++) name[i] = i + start; }

template <typename T1, typename T2> istream& operator >>(istream& is, pair<T1, T2>& s) { is >> s.first >> s.second; return is; }
template <typename T> ostream& operator << (ostream& os, const vector<T> &v) { for (int i = 0 ; i < v.size() ; i++) os << v[i] << ' '; os << endl; return os; }
template <typename T1, typename T2> ostream& operator <<(ostream& s, pair<T1, T2>& t) { s << t.first << ' ' << t.second; return s; }
template <typename T> vector<T> readVector(int n) { vector<T> res(n); for (int i = 0 ; i < n ; i++) cin >> res[i]; return res; }

vector<pair<int, int> > points;
int n;
vector<int> parent;
vector<int> size;

vector<int> mapping;
vector<vector<int> > edges;

void solve(vector<int> &vertices, int root) {
	if (vertices.size() != size[root]) {
		cout << "Ooops";
		exit(0);
	}
	int v = vertices.front();
	for (auto v2 : vertices) if (points[v2] < points[v]) v = v2;
	FOR (i, 0, vertices.size()) {
		if (vertices[i] == v) {
			vertices[i] = vertices.back();
			vertices.pop_back();
		}
	}

	mapping[v] = root + 1;
	if (!vertices.size()) return;

	int y0 = points[v].second;
	int x0 = points[v].first;

	vector<pair<double, int> > v2;
	for (auto vi : vertices) v2.push_back(make_pair(atan2(points[vi].second - y0, points[vi].first - x0), vi));
	sort(all(v2));

	int p = 0;
	for (auto dest : edges[root]) if (parent[root] != dest) {
		vector<int> nextPoints;
		while (nextPoints.size() < size[dest]) nextPoints.push_back(v2[p++].second);
		solve(nextPoints, dest);
	}
}

int main() {
	srand (time(NULL));
    ios_base::sync_with_stdio(false); cin.tie(NULL);

	cin >> n;
	parent.resize(n);
	edges.resize(n);
	FOR (i, 0, n - 1) {
		next(int, a);
		next(int, b);
		a--;
		b--;
		edges[a].push_back(b);
		edges[b].push_back(a);
	}

	vector<int> q;
	q.push_back(0);
	mapping.resize(n);
	parent[q[0]] = -1;

	FOR (i, 0, n) {
		int v = q[i];
		for (auto e : edges[v]) if (e != parent[v]) {
			parent[e] = v;
			q.push_back(e);
		}
	}

	points = readVector<pair<int, int> >(n);

	size.assign(n, 1);
	FORD (i, n - 1, 0) {
		int v = q[i];
		if (parent[v] != -1) size[parent[v]] += size[v];
	}

	vector<int> vertices(n);
	FOR (i, 0, n) vertices[i] = i;
	solve(vertices, q[0]);

	cout << mapping;
}


#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1555;
vector<int>v[maxn];
int X,Y,n;
int sz[maxn];
bool vis[maxn];
struct Po{
    int x,y,id;
    bool operator <(const Po &o)const {
         if(x-X>=0&&o.x-X<=0) return 1;
         if(x-X<=0&&o.x-X>=0) return 0;
         return (y-Y)*(long long )(o.x-X)<(o.y-Y)*(long long )(x-X);
    }
}p[maxn];
int dfs(int x){
    vis[x]= true;
    sz[x]=1;
    int res=0;
    for(int i=0;i<v[x].size();i++){
        int k=v[x][i];
        if(vis[k]) continue;
        res+=dfs(k);
    }
    sz[x]+=res;
    return sz[x];
}
int c[maxn];
int o[maxn];
void calc(int u,int l,int r){
    vis[u]=true;
    int t=l;
    for(int i=l+1;i<=r;i++){
        if(p[i].y<p[t].y||(p[i].y==p[t].y&&p[i].x<p[t].x))
            t=i;
    }
    if(t!=l)
        swap(p[l],p[t]);
    o[p[l].id]=u;
    X=p[l].x;
    Y=p[l].y;
    sort(p+l+1,p+1+r);
    int pos=l+1;
    for(int i=0;i<v[u].size();i++){
        int k=v[u][i];
        if(vis[k])continue;
        calc(k,pos,pos+sz[k]-1);
        pos+=sz[k];
    }
}
int main(){
    scanf("%d",&n);
    int a,b;
    for(int i=1;i<n;i++){
        scanf("%d%d",&a,&b);
        v[a].push_back(b);
        v[b].push_back(a);
    }
    for(int i=1;i<=n;i++){
        scanf("%d%d",&p[i].x,&p[i].y);
        p[i].id=i;
    }
    dfs(1);
    memset(vis,0,sizeof(vis));
    calc(1,1,n);
    for(int i=1;i<=n;i++)
        printf("%d ",o[i]);
    printf("\n");
    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;
}
	 	  			  	  		 	 		     		 		//hellobig_tq//hello


#include<bits/stdc++.h>
#define ll long long
#define M 1505
using namespace std;
int head[M],tot;
struct Edge{int nxt,to;}G[M*2];
void addedge(int x,int y){
	G[tot]=(Edge){head[x],y};
	head[x]=tot++;
}
int n,rt;ll X,Y;
struct node{
	ll x,y;int id;
	bool operator < (const node &_)const{
		return (x-X)*(_.y-Y)>(y-Y)*(_.x-X);
	}
}A[M];
int sz[M];
void f1(int x,int fa1){
	sz[x]=1;
	for(int i=head[x];i!=-1;i=G[i].nxt){
		int y=G[i].to;
		if(y==fa1)continue;
		f1(y,x);
		sz[x]+=sz[y];
	}
}
int Ans[M];
void f2(int x,int fa1,int L,int R){
	rt=0;X=1e18;Y=1e18;
	for(int i=L;i<=R;i++){
		if(X>A[i].x)rt=i,X=A[i].x,Y=A[i].y;
		else if(X==A[i].x&&Y>A[i].y)rt=i,Y=A[i].y;
	}
	Ans[A[rt].id]=x;X=A[rt].x;Y=A[rt].y;
	swap(A[L],A[rt]);
	sort(A+L+1,A+R+1);
	int now=0;
	for(int i=head[x];i!=-1;i=G[i].nxt){
		int y=G[i].to;
		if(y==fa1)continue;
		f2(y,x,L+now+1,L+now+sz[y]);
		now+=sz[y];
	}
}
int main(){
	memset(head,-1,sizeof head);
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		addedge(x,y);
		addedge(y,x);
	}
	for(int i=1;i<=n;i++){
		ll x,y;
		scanf("%lld%lld",&x,&y);
		A[i]=(node){x,y,i};
	}
	f1(1,0);
	f2(1,0,1,n);
	for(int i=1;i<=n;i++)printf("%d ",Ans[i]);
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <iomanip>

using namespace std;

#if __GNUC__
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef _MSC_VER
#define __typeof__ decltype
template <class T> int popcount(T n) { return n ? 1 + popcount(n & (n - 1)) : 0; }
#endif
#ifdef __GNUC__
template <class T> int popcount(T n);
template <> int popcount(unsigned int n) { return __builtin_popcount(n); }
template <> int popcount(int n) { return __builtin_popcount(n); }
template <> int popcount(unsigned long long n) { return __builtin_popcountll(n); }
template <> int popcount(long long n) { return __builtin_popcountll(n); }
#endif

#define rep (i, n) for (int i = 0; i < (int)n; ++i)
#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define rforeach(it, c) for (__typeof__((c).rbegin()) it=(c).rbegin(); it != (c).rend(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CL(arr, val) memset(arr, val, sizeof(arr))
#define MEMCPY(dest, src) memcpy(dest, src, sizeof(src))

template <class T> void max_swap(T& a, const T& b) { a = max(a, b); }
template <class T> void min_swap(T& a, const T& b) { a = min(a, b); }

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

template <class T> string to_s(const T& a) { ostringstream os; os << a; return os.str(); }

const double EPS = 1e-8;
const double PI = acos(-1.0);
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };
bool valid_pos(int x, int y, int w, int h) { return 0 <= x && x < w && 0 <= y && y < h; }

template <class T> void print(T a, int n, int br = 1, const string& deli = ", ") { cout << "{ "; for (int i = 0; i < n; ++i) { cout << a[i]; if (i + 1 != n) cout << deli; } cout << " }"; while (br--) cout << endl; }
template <class T> void print(const vector<T>& v, int br = 1, const string& deli = ", ") { print(v, v.size(), br, deli); }
template <class T> void print2d(T a, int w, int h, int width = -1, int br = 1) { for (int i = 0; i < h; ++i) { for (int j = 0; j < w; ++j) {    if (width != -1) cout.width(width); cout << a[i][j] << ' '; } cout << endl; } while (br--) cout << endl; }

template <class T> void input(int n, T& a) { for (int i = 0; i < n; ++i) cin >> a[i]; }
template <class T, class U> void input(int n, T& a, U& b) { for (int i = 0; i < n; ++i) cin >> a[i] >> b[i]; }
template <class T> vector<T> input(int n) { vector<T> res(n); for (int i = 0; i < n; ++i) cin >> res[i]; return res; }

typedef complex<ll> P;
namespace std
{
    bool operator<(const P& a, const P& b)
    {
        return a.imag() != b.imag() ? a.imag() < b.imag() : a.real() < b.real();
    }
};
ll cross(const P& a, const P& b) { return a.real() * b.imag() - a.imag() * b.real(); }
struct Comp
{
    P base;
    Comp(const P& base)
        : base(base) { }
    bool operator()(const P& a, const P& b) const
    {
        P x = a - base, y = b - base;
        return cross(x, y) > 0;
    }
};

int n;
P p[1511];
vector<int> e[1511];
map<P, int> index;

int size[1511];
int dfs_size(int v, int prev)
{
    size[v] = 1;
    for (int i = 0; i < e[v].size(); ++i)
        if (e[v][i] != prev)
            size[v] += dfs_size(e[v][i], v);
    return size[v];
}

int res[1511];
void build(int v, int prev, P* part)
{
    P cur = *part;
    res[index[cur]] = v + 1;
    ++part;

    sort(part, part + (size[v] - 1), Comp(cur));

    for (int i = 0; i < e[v].size(); ++i)
    {
        int to = e[v][i];
        if (to != prev)
        {
            build(to, v, part);
            part += size[to];
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);

    cin >> n;

    for (int i = 0; i < n - 1; ++i)
    {
        int a, b;
        cin >> a >> b;
        --a, --b;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for (int i = 0; i < n; ++i)
    {
        ll x, y;
        cin >> x >> y;
        p[i] = complex<ll>(x, y);
        index[p[i]] = i;
    }

    int root = 0;
    dfs_size(root, -1);

    sort(p, p + n);
    build(root, -1, p);

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


#include<bits/stdc++.h>
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i<i##_end_;i++)
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define db double
#define LL long long
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f
#define Sz(a)sizeof(a)
#define mcl(a,b)memset(a,b,Sz(a))
#define mcp(a,b)memcpy(a,b,Sz(b))
#define pb push_back
template<class T>inline bool chkmin(T&x,T y){return y<x?x=y,1:0;}
template<class T>inline bool chkmax(T&x,T y){return x<y?x=y,1:0;}
inline LL Max(LL x,LL y){return x>y?x:y;}
inline LL Min(LL x,LL y){return x<y?x:y;}

#define N 1502

int n;
vector<int>E[N];
int sz[N];
struct point{
	int x,y,id;
	db jj;
}p[N];
int ans[N];

bool cmp(point a,point b){
	return a.jj<b.jj;
}

void dfs(int x,int f){
	sz[x]=1;
	SREP(i,0,E[x].size()){
		int y=E[x][i];
		if(y==f)continue;
		dfs(y,x);
		sz[x]+=sz[y];
	}
}

void solve(int x,int f,int l,int r){
    if(l>r) return;
    int pos=l;
    for(int i=l+1;i<=r;i++) if(p[i].y<p[pos].y || (p[i].y==p[pos].y && p[i].x<p[pos].x)) pos=i;
	swap(p[pos],p[l]);
    ans[p[l].id]=x;
    if(l==r) return;
    for(int i=l+1;i<=r;i++){
		p[i].x-=p[l].x,p[i].y-=p[l].y;
		p[i].jj=atan2(p[i].y,p[i].x);
	}
    sort(p+l+1,p+r+1,cmp);
    int now=l+1;
    SREP(i,0,E[x].size()){
		int y=E[x][i];
		if(y==f)continue;
		solve(y,x,now,now+sz[y]-1);
		now+=sz[y];
	}
}

int main(){
	scanf("%d",&n);
	SREP(i,1,n){
		int a,b;
		scanf("%d%d",&a,&b);
		E[a].pb(b);
		E[b].pb(a);
	}
	REP(i,1,n){
		scanf("%d%d",&p[i].x,&p[i].y);
		p[i].id=i;
	}
	dfs(1,0);
	solve(1,0,1,n);
	REP(i,1,n)printf("%d%c",ans[i],i<n?' ':'\n');
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <functional>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>

using namespace std;

#ifndef DEBUG
#define DEBUG 0
#endif

#define debug(x) if (DEBUG) cerr << #x << " = " << (x) << endl

#define debug_line(a, n) do {                                                \
    if (DEBUG) {                                                             \
        cerr << #a << "[" << #n << "]:" << endl;                             \
        for (int i = 0; i < (n); i++) cerr << (a)[i] << " ";                 \
        cerr << endl;                                                        \
    }                                                                        \
} while (0)

#define debug_mat(a, n, m) do {                                              \
    if (DEBUG) {                                                             \
        cerr << #a << "[" << #n << "][" << #m "]:" << endl;                  \
        for (int i = 0; i < (n); i++) {                                      \
            for (int j = 0; j < (m); j++) cerr << (a)[i][j] << " ";          \
            cerr << endl;                                                    \
        }                                                                    \
    }                                                                        \
} while(0)

typedef pair<long long, long long> pii;
typedef vector<int>::const_iterator vci;
typedef map<int, int>::const_iterator mci;

const int INF = 0x3f3f3f3f;
const long long LLINF = 0x3f3f3f3f3f3f3f3fll;
const double DINF = 1.0/0.0f;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int MOD = 1000000007;

inline int LC(int x) { return x << 1; }
inline int RC(int x) { return (x << 1) | 1; }
inline bool eq0(double x) { return fabs(x) < eps; }
inline bool eq(double x, double y) { return fabs(x - y) < eps; }
inline bool ls(double x, double y) { return x + eps < y; }
inline bool gr(double x, double y) { return x - eps > y; }
inline bool greq(double x, double y) { return x + eps >= y; }
inline bool lseq(double x, double y) { return x - eps <= y; }
inline double fmax(double x, double y) { return gr(x, y) ? x : y; }
inline double fmin(double x, double y) { return ls(x, y) ? x : y; }

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

vector<int> edge[2000];
int ans[2000];
int size[2000];

struct Point {
    long long x, y;
    int idx;

    Point(long long _x, long long _y, int _idx) : x(_x), y(_y), idx(_idx) { }

    bool operator<(const Point &o)
    {
        return y < o.y;
    }
};
vector<Point> pnt;

class Compare_Angle {
    private:
        Point base;

    public:
        Compare_Angle(const Point &_base) : base(_base) { }
        bool operator()(const Point &a, const Point &b) const
        {
            return (a.x - base.x) * (b.y - base.y) - (b.x - base.x) * (a.y - base.y) > 0;
        }
};

int make_tree(int x, int parent)
{
    size[x] = 1;
    for (vci it = edge[x].begin(); it != edge[x].end(); it++) {
        if (*it != parent) {
            size[x] += make_tree(*it, x);
        }
    }
    return size[x];
}

void make_match(int x, int parent, vector<Point>::iterator start, vector<Point>::iterator end)
{
    vector<Point>::iterator low = min_element(start, end);
    ans[low->idx] = x;
    swap(*start, *low);
    sort(start + 1, end, Compare_Angle(*start));

    start++;
    for (vci it = edge[x].begin(); it != edge[x].end(); it++) {
        if (*it != parent) {
            make_match(*it, x, start, start + size[*it]);
            start += size[*it];
        }
    }
}

int main()
{
    int n;
    cin >> n;
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    for (int i = 0; i < n; i++) {
        long long x, y;
        cin >> x >> y;
        pnt.push_back(Point(x, y, i));
    }

    make_tree(1, 0);
    make_match(1, 0, pnt.begin(), pnt.end());

    for (int i = 0; i < n; i++) cout << ans[i] << endl;

    return 0;
}


#include<cstdio>
#include<algorithm>
#include<vector>
#define LL long long
#define M 20000
using namespace std;
struct Point{
	int x,y,id;
}p[2000];
vector<pair<int,int> >vec[2000];
int t,mix,miy,siz[2000];
bool cmp(Point a,Point b){
	int w=0;
	if(a.x>=mix&&b.x<=mix) return 1;
	if(a.x<=mix&&b.x>=mix) return 0;
		if(a.x<mix){
			w=1LL*(a.y-miy)*1LL*(mix-b.x)>=1LL*(b.y-miy)*1LL*(mix-a.x);
		}else{
		    w=1LL*(a.y-miy)*1LL*(b.x-mix)<=1LL*(b.y-miy)*1LL*(a.x-mix);
		}
	return w;
}
int n,x,y,pnt=1,a[M],fi[M],ne[M],la[M],ans[M],tot;
void add(int x,int y){
	a[++tot]=y;
	!fi[x]?fi[x]=tot:ne[la[x]]=tot;la[x]=tot;
}
void dfs(int x,int fa){
	siz[x]=1;
	for(int i=fi[x];i;i=ne[i])if(a[i]!=fa){
		dfs(a[i],x);
		siz[x]+=siz[a[i]];
	}
}
void calc(int trt,int l,int r,int fa){
	//printf("%d %d %d\n",pnt,trt,fa);
	int pos=l;
	for(int i=l;i<=r;i++)if(p[i].y<p[pos].y)pos=i;
	swap(p[pos],p[l]);
	ans[p[l].id]=trt;
	mix=p[l].x;
	miy=p[l].y;
	//printf("%d\n",pos);
	pos=l+1;
    sort(p+pos,p+r+1,cmp);
	for(int i=fi[trt];i;i=ne[i])if(a[i]!=fa){
		calc(a[i],pos,pos+siz[a[i]]-1,trt);
		pos+=siz[a[i]];
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	//mix=miy=0x7f7f7f7f;
	//printf("%d\n",miy);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&p[i].x,&p[i].y);
		p[i].id=i;

	}
	dfs(1,0);
	calc(1,1,n,0);
	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
	return 0;
}


#include <cstdio>
#include <algorithm>
#define N 1510
using namespace std;
typedef long long LL;

struct Node {
    LL to, nxt;
}e[N << 1];

struct Point {
    LL x, y, id;
}p[N], pp[N], poi;

LL cnt, n, lst[N], ans[N], size[N];

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

inline void add(LL u, LL v) {
    e[++cnt].to = v;
    e[cnt].nxt = lst[u];
    lst[u] = cnt;
}

void predfs(LL x, LL fa) {//预处理出子树大小
    size[x] = 1;
    for (int i = lst[x]; i; i = e[i].nxt) {
        if (e[i].to == fa) continue;
        predfs(e[i].to, x);
        size[x] += size[e[i].to];
    }
}

void dfs(LL l, LL r, LL x, LL fa){//对区间进行分治
    LL mini = l;
    for (int i = l + 1; i <= r; ++i)
        if (p[i].y < p[mini].y || p[i].y == p[mini].y && p[i].x < p[mini].x) mini = i;
    swap(p[l], p[mini]);
    ans[p[l].id] = x;
    poi = p[l];
    sort(p + l + 1, p + r + 1, cmp);
    LL now = l + 1;
    for (LL i = lst[x]; i; i = e[i].nxt) {
        if (e[i].to == fa) continue;
        dfs(now, now + size[e[i].to] - 1, e[i].to, x);
        now += size[e[i].to];
    }
}

int main() {
    scanf("%lld", &n);
    for (LL i = 1; i < n; ++i) {
        LL a, b;
        scanf("%lld%lld", &a, &b);
        add(a, b);
        add(b, a);
    }
    for (LL i = 1; i <= n; ++i) {
        scanf("%lld%lld", &p[i].x, &p[i].y);
        p[i].id = i;
    }
    predfs(1, 1);
    dfs(1, n, 1, 1);
    for (LL i = 1; i < n; ++i) {
        printf("%lld ", ans[i]);
    }
    printf("%lld\n", ans[n]);
    return 0;
}//


#pragma GCC optimize("O2")
#include<bits/stdc++.h>
#define int long long
#define N 3000
using namespace std;
struct Point
{
    int x,y;int id;
    Point(){}
    Point(double _x,double _y){x=_x,y=_y;}
}now,p[N];
typedef Point Vector ;
Vector operator - (Point a,Point b){return Point(a.x-b.x,a.y-b.y);}
double Cross(Vector a,Vector b){return a.x*b.y-a.y*b.x;}
int book[N],ans[N],n,sz[N];
vector<int> g[N];
bool cmp(Point a,Point b)
{
	return Cross(a-now,b-now)>0;
}

void dfs(int x,int fa)
{
	sz[x]=1;
	for(int i=0,v;i<g[x].size();i++) if((v=g[x][i])!=fa)
		dfs(v,x),sz[x]+=sz[v];
}
void solve(int x,int l,int r)
{
	book[x]=1;
	for(int i=l+1;i<=r;i++)
		if(p[i].x<p[l].x) swap(p[i],p[l]);
	ans[p[l].id]=x;
	now=p[l];sort(p+l+1,p+r+1,cmp);
	for(int i=0,v;i<g[x].size();i++)
	{
		if(book[v=g[x][i]]) continue;
		solve(v,l+1,l+sz[v]);
		l+=sz[v];
	}
}

main()
{
    cin>>n;
    for(int i=1;i<n;i++)
    {
		int u,v;
		scanf("%lld%lld",&u,&v);
		g[u].push_back(v),g[v].push_back(u);
	}
	dfs(1,-1);
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&p[i].x,&p[i].y),p[i].id=i;
	solve(1,1,n);
	for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,si[4000];
ll w,ans[4000];
struct node
{
	ll x,y,wh;
	ll dx,dy;
}sh[4000];
vector <ll> e[4000];
bool operator < (node a,node b)
{
	return (a.x<b.x || (a.x==b.x && a.y<b.y));
}
ll m_abs(ll a)
{
	if (a<0)
	  return -a;
	else
	  return a;
}
void dfs(ll now,ll fa)
{
	si[now]=1;
	for (ll i=0;i<e[now].size();i++)
	{
		ll u;
		u=e[now][i];
		if (u!=fa)
		{
			dfs(u,now);
			si[now]+=si[u];
		}
	}
}
bool cmp(node a,node b)
{
	return (ll)a.dy*b.dx<(ll)a.dx*b.dy;
}
void solve(ll now,ll fa,ll l,ll r)
{
	ll root;
	node MAX;
	MAX.x=1e18;
	MAX.y=1e18;
	for (ll i=l;i<=r;i++)
	{
		if (sh[i]<MAX)
		{
			MAX=sh[i];
			root=i;
		}
	}
	ans[sh[root].wh]=now;
	if (l==r)
	  return;
	for (ll i=l;i<=r;i++)
	{
		sh[i].dx=sh[i].x-sh[root].x;
		sh[i].dy=sh[i].y-sh[root].y;
	}
	if (root!=l)
	  swap(sh[l],sh[root]);
	sort(sh+l+1,sh+r+1,cmp);
	ll ml,mr;
	ml=l+1;
	mr=l;
	for (ll i=0;i<e[now].size();i++)
	{
		ll u;
		u=e[now][i];
		if (u!=fa)
		{
			mr+=si[u];
			solve(u,now,ml,mr);
			ml=mr+1;
		}
	}
}
int main()
{
	scanf("%lld",&n);
	for (ll i=1;i<n;i++)
	{
		ll u,v;
		scanf("%lld%lld",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs(1,-1);
	for (ll i=1;i<=n;i++)
	  scanf("%lld%lld",&sh[i].x,&sh[i].y);
	for (ll i=1;i<=n;i++)
	  sh[i].wh=i;
	solve(1,-1,1,n);
	for (ll i=1;i<=n;i++)
	  printf("%lld ",ans[i]);
	printf("\n");
}


/*
 * c.cpp
 *
 *  Created on: 2012-6-12
 *      Author: mac
 */
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <climits>
#include <numeric>
#include <vector>
#define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
#define REP(i,n) for(int i=0;i<n;++i)
using namespace std;

const int MAX_N = 1500 + 10;

typedef long long int64;

int sign(int64 a) {
    return a < 0 ? -1 : a > 0;
}

struct Point {
    int64 x, y;
    Point() {
    }
    Point(int64 _x, int64 _y) :
            x(_x), y(_y) {
    }
    Point operator+(const Point&p) const {
        return Point(x + p.x, y + p.y);
    }
    Point operator-(const Point&p) const {
        return Point(x - p.x, y - p.y);
    }
    Point operator*(double d) const {
        return Point(x * d, y * d);
    }
    Point operator/(double d) const {
        return Point(x / d, y / d);
    }
    bool operator<(const Point&p) const {
        return x != p.x ? x < p.x : y < p.y;
    }
    int64 dot(const Point&p) const {
        return x * p.x + y * p.y;
    }
    int64 det(const Point&p) const {
        return x * p.y - y * p.x;
    }
    void read() {
        cin >> x >> y;
    }
    void write() {
        cout << "(" << x << "," << y << ")" << endl;
    }
};

#define cross(p1,p2,p3) ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))

#define crossOp(p1,p2,p3) sign(cross(p1,p2,p3))

Point isSS(Point p1, Point p2, Point q1, Point q2) {
    double a1 = cross(q1,q2,p1), a2 = -cross(q1,q2,p2);
    return (p1 * a2 + p2 * a1) / (a1 + a2);
}

Point ps[MAX_N];
int n;

bool e[MAX_N][MAX_N];

bool cmp(int a, int b) {
    return ps[a] < ps[b];
}

int mp[MAX_N];

int RT;
Point CT;

bool cmp2(int a, int b) {
    Point A = ps[a], B = ps[b];
    return crossOp(CT,A,B) > 0;
}

int size[MAX_N];

void dfs(int u, int par) {
    size[u] = 1;
    for (int i = 0; i < n; ++i) {
        if (e[u][i] && i != par)
            dfs(i, u), size[u] += size[i];
    }
}

void work(int rt, int par, vector<int> cur) { // return root
    //take the left-lowerest point
    int low = *min_element(cur.begin(), cur.end(), cmp);
    cur.erase(find(cur.begin(), cur.end(), low));

    mp[low] = rt;

    vector<int> ch;
    for (int i = 0; i < n; ++i) {
        if (e[rt][i] && i != par)
            ch.push_back(i);
    }

        CT = ps[low];

    sort(cur.begin(), cur.end(), cmp2);

    int at = 0;

    for (vector<int>::iterator e = ch.begin(); e != ch.end(); ++e) {
        work(*e, rt, vector<int>(cur.begin() + at, cur.begin() + at + size[*e]));
        at += size[*e];
    }
}

int main() {
    cin >> n;
    memset(e, 0, sizeof e);
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        cin >> a >> b;
        --a, --b;
        e[a][b] = e[b][a] = true;
    }
    for (int i = 0; i < n; ++i) {
        ps[i].read();
    }
    dfs(0, -1);

    vector<int> cur;
    for (int i = 0; i < n; ++i) {
        cur.push_back(i);
    }

    work(0, -1, cur);

    for (int i = 0; i < n; ++i) {
        printf("%d ", mp[i] + 1);
    }
    puts("");
    return 0;
}


#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

const int INF=2000000010;

struct point{
	int x,y,num;
};

bool operator<(point a, point b){
	return b.x==0 || (a.x>0 && 1ll*a.x*b.y>1ll*a.y*b.x);
}

struct vertex{
	int subtree,num;
	vector <int> next;
};

int N;
vertex g[1510]; //our tree
point pnt[1510]; //points
int ans[1510]; //answer
vector <point> v; //points that we work with

void precalc_dfs(int v, int p=-1){ //precalculating subtree values
	g[v].subtree=1;
	for (int i=0; i<g[v].next.size(); i++)
		if (g[v].next[i]!=p){
			precalc_dfs(g[v].next[i],v);
			g[v].subtree+=g[g[v].next[i]].subtree;
		}
}

void build(vector <point> a, int from, int p=-1){
	int n=a.size();
	int mini=-1,minx=INF,miny=INF;
	for (int i=0; i<n; i++)
		if (a[i].x<minx || (a[i].x==minx && a[i].y<miny))
			mini=i,minx=a[i].x,miny=a[i].y;
	ans[a[mini].num]=from; //HERE WE FIX THE ANSWER
	a[mini]=a[n-1];
	a.pop_back(); n--;
	for (int i=0; i<n; i++)
		a[i].x-=minx, a[i].y-=miny;
	std::sort(a.begin(),a.end());
	int cur_alloc=0;
	for (int i=0; i<g[from].next.size(); i++)
		if (g[from].next[i]!=p){
			vector <point> b;
			for (int j=0; j<g[g[from].next[i]].subtree; j++)
				b.push_back(a[j+cur_alloc]);
			cur_alloc+=g[g[from].next[i]].subtree;
			build(b,g[from].next[i],from);
		}
}

int main(){
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	scanf("%d", &N);
	int v1,v2;
	for (int i=1; i<=N; i++)
		g[i].num=i;
	for (int i=1; i<N; i++){
		scanf("%d%d", &v1, &v2);
		g[v1].next.push_back(v2);
		g[v2].next.push_back(v1);
	}
	point ppp;
	for (int i=0; i<N; i++){
		scanf("%d%d", &ppp.x, &ppp.y);
		ppp.num=i;
		pnt[i]=ppp;
		v.push_back(ppp);
	}
	precalc_dfs(1);
	build(v,1);
	for (int i=0; i<N-1; i++)
		printf("%d ", ans[i]);
	printf("%d\n", ans[N-1]);
	return 0;
}


#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

typedef long long LL;
typedef double DB;
typedef pair <int, int> PII;
const int MAXN = 1510;
const LL INF = 1e15;

inline LL in()
{
    LL x = 0, flag = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') flag = -1; ch = getchar(); }
    while (ch >='0' && ch <= '9') x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
    return x * flag;
}

int n, m;

struct Adj
{
    int nex, to;
} adj[MAXN << 1];
int head[MAXN], nume;
void addedge(int from, int to)
{
    adj[++nume] = (Adj) { head[from],  to };
    head[from] = nume;
}
int siz[MAXN];
void DFS(int u, int pre)
{
//    printf("u : %d\n", u);
    siz[u] = 1;
    for (int i = head[u]; i; i = adj[i].nex)
    {
        int v = adj[i].to;
        if (v == pre) continue;
//        printf("%d --> %d\n", u, v);
        DFS(v, u);
        siz[u] += siz[v];
    }
}

struct Poi
{
    LL x, y; int id;
    bool operator < (const Poi b) const { return x == b.x ? y < b.y : x < b.x; }
} poi[MAXN], base;
bool cmp(Poi a, Poi b)
{
//    printf("%lld / %lld ? %lld / %lld %d\n", a.y - base.y, a.x - base.x, b.y - base.y, b.x - base.x, (a.y - base.y) * (b.x - base.x) < (b.y - base.y) * (a.x - base.x));
    return (a.y - base.y) * (b.x - base.x) < (b.y - base.y) * (a.x - base.x);
}
int Map[MAXN];
void solve(int rt, int pre, int l, int r)
{
//    printf("solving %d %d %d\n", rt, l, r);
    sort(poi + l, poi + r + 1);
//    printf("After sort: \n");
//    for (int i = l; i <= r; i ++) printf("(%lld, %lld) %d\n", poi[i].x, poi[i].y, poi[i].id);
    base = poi[l];
/*
    for (int i = l; i <= r; i ++)
    {
        printf("(%lld %lld), %lld %lld\n", poi[i].x, poi[i].y, poi[i].x - base.x, poi[i].y - base.y);
    }
*/
    sort(poi + l + 1, poi + r + 1, cmp);
//    printf("After sort --- : \n");
//    for (int i = l; i <= r; i ++)
//        printf("(%lld, %lld) %d\n", poi[i].x, poi[i].y, poi[i].id);
    Map[poi[l].id] = rt;
    for (int i = head[rt]; i; i = adj[i].nex)
    {
        int v = adj[i].to;
        if (v == pre) continue;
        solve(v, rt, l + 1, l + siz[v]);
        l += siz[v];
    }
}

int main()
{
    n = in();
    for (int i = 1; i < n; i ++)
    {
        int u = in(), v = in();
        addedge(u, v);
        addedge(v, u);
    }
    DFS(1, 0);
    for (int i = 1; i <= n; i ++)
    {
        poi[i] = (Poi) {in(), in(), i};
    }
//    sort(poi + 1, poi + n + 1);
    /*
    base = poi[1];
    sort(poi + 6, poi + n + 1, cmp);
    for (int i = 1; i <= n; i ++)
    {
        printf("(%lld %lld) %d\n", poi[i].x, poi[i].y, poi[i].id);
    }
    */
    solve(1, 0, 1, n);
    for (int i = 1; i <= n; i ++) printf("%d ", Map[i]);
    return 0;
}


#define _USE_MATH_DEFINES
#include <limits.h>
#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <fstream>

using namespace std;

#define ff(i,x,y) for(int i = (x);i < (y);++i)
#define rep(i,n) ff(i,0,n)
#define st(v) sort(v.begin(),v.end())
#define st2(v,f) sort(v.begin(),v.end(),f)
#define rvs(v) reverse(v.begin(),v.end())
#define cnt(v,n) count(v.begin(),v.end(),n)
#define pb push_back
bool myfunction (int i,int j) { return (i<j); }
#define fact(x) for(i=x-1;i>0;i--){x=x*i;}
#define MP make_pair
#define F first
#define S second
#define LL long long
#define ULL unsigned long long
#define VI vector<int>
#define VVI vector<VI>

typedef pair<int,int> PII;
typedef pair<PII,int> PIII;

#ifdef LOCAL
ifstream in("in.txt");
#else
istream &in = cin;
#endif

int n;
bool adj[1501][1501];
int vtx[1501];
vector<bool> chk;
vector <PIII> points;
vector <PII> res;

int dfs(int node)
{
	int cnt = 0;
	chk[node] = true;
	for(int i = 1;i <= n;++i)
		if(!chk[i] && adj[node][i])
			cnt += dfs(i);
	vtx[node] = cnt+1;
	return vtx[node];
}

void go(int root, vector<PIII> ps)
{
	int min_y = INT_MAX, min_i = -1;
	for(int i = 1;i <= ps.size()-1;++i) if(ps[i].F.S < min_y) {min_y = ps[i].F.S; min_i = i;}
	res.push_back(MP(ps[min_i].S,root));
	vector<pair<long double,int> > tps(1);
	for(int i = 1;i <= ps.size()-1;++i) if(i != min_i) tps.push_back(MP(atan2l(ps[i].first.first-ps[min_i].first.first,ps[i].first.second-ps[min_i].first.second),i));
	sort(tps.begin()+1,tps.end());
	int s = 1;
	for(int i = 1;i <= n;++i) if(adj[root][i]) {
		vector<PIII> nps(1);
		while(nps.size() < vtx[i]+1) {
			nps.push_back(ps[tps[s].S]);
			++s;
		}
		adj[i][root] = false;
		go(i,nps);
	}
}

int main()
{
	in >> n;
	rep(i,n+1) rep(j,n+1) adj[i][j] = false;
	points.resize(n+1);
	chk.resize(n+1,false);
	memset(vtx,0,sizeof(vtx));

	rep(i,n-1) {
		int a, b;
		in >> a >> b;
		adj[a][b] = adj[b][a] = true;
	}

	rep(i,n) {
		int x, y;
		in >> x >> y;
		points[i+1] = MP(MP(x,y),i+1);
	}

	dfs(1);

	sort(points.begin()+1,points.end());
	rep(i,n+1) chk[i] = false;

	go(1,points);

	st(res);

	for(int i = 0;i < res.size();++i) cout << res[i].second << " ";

	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;
}
	 	  			  	  		 	 		     		 		//hellobig_tq


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

const int N = 1500;
int n, ans[N], size[N];
vector<int> edge[N], ch[N];
vector<pair<int, pair<int, int> > > p;

bool by_x(pair<int, pair<int, int> > a, pair<int, pair<int, int> > b) {
	return a.second.first < b.second.first || a.second.first == b.second.first && a.second.second < b.second.second;
}

pair<int, int> cur;

bool by_r(pair<int, pair<int, int> > a, pair<int, pair<int, int> > b) {
	long long x1 = a.second.first - cur.first, y1 = a.second.second - cur.second, x2 = b.second.first - cur.first, y2 = b.second.second - cur.second;
	return x1 * y2 - x2 * y1 < 0;
}

void dfs(int u, int fa) {
	size[u] = 1;
	for (int j = 0; j < (int)edge[u].size(); ++j) {
		int v = edge[u][j];
		if (v == fa) {
			continue;
		}
		ch[u].push_back(v);
		dfs(v, u);
		size[u] += size[v];
	}
}

void solve(int u, vector<pair<int, pair<int, int> > > p) {
	for (int i = 0 ; i < (int)p.size(); ++i) {
		if (by_x(p[i], p.back())) {
			swap(p[i], p[p.size() - 1]);
		}
	}
	cur = p.back().second;
	ans[p.back().first] = u;
	p.pop_back();
	sort(p.begin(), p.end(), by_r);
	for (int i = 0; i < (int)ch[u].size(); ++i) {
		vector<pair<int, pair<int, int> > > tmp;
		int v = ch[u][i];
		for (int j = 0; j < size[v]; ++j) {
			tmp.push_back(p.back());
			p.pop_back();
		}
		solve(v, tmp);
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 0; i < n - 1; ++i) {
		int u, v;
		scanf("%d%d", &u, &v);
		--u, --v;
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	dfs(0, -1);
	for (int i = 0; i < n; ++i) {
		int x, y;
		scanf("%d%d", &x, &y);
		p.push_back(make_pair(i, make_pair(x, y)));
	}
	solve(0, p);
	for (int i = 0; i < n; ++i) {
		printf("%d%c", ans[i] + 1, i == n - 1 ? '\n' : ' ');
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>

using namespace std;
#define int long long

inline int read(){
	int ret=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}

const int maxn=1505,INF=2e9;
int n;
int tot=0,lnk[maxn],nxt[maxn*2],son[maxn*2],fa[maxn],num[maxn];

inline void add_edge(int x,int y){
	tot++;son[tot]=y;nxt[tot]=lnk[x];lnk[x]=tot;
}

struct point{
	int id,x,y;
};
double cross(double x1,double y1,double x2,double y2){
	return (x1*y2-x2*y1);
}
double compare(point a,point b,point c){
	return cross((b.x-a.x),(b.y-a.y),(c.x-a.x),(c.y-a.y));
}

point a[maxn];
point s,cc;
int ans[maxn];

void build_tree(int x){
	num[x]=1;
	for (int i=lnk[x];i;i=nxt[i]) if (son[i]!=fa[x]) fa[son[i]]=x,build_tree(son[i]),num[x]+=num[son[i]];
}

bool cmp(point a,point b){
	if(compare(cc,a,b)==0)
		return a.x>b.x;
	else return compare(cc,a,b)>0;
}

inline void DFS(int id,int p,vector<point> vec){
	ans[id]=p;
	cc=a[id];
	sort(vec.begin(),vec.end(),cmp);
	// printf("%lld:%lld -- ",id,p);
	// for (int i=0;i<(int)vec.size();i++) printf("%lld ",vec[i].id);printf("\n");
	vector<point> vec_nxt; point nxt_s;
	int j=0;
	for (int i=lnk[p];i;i=nxt[i]) if (son[i]!=fa[p]){
		vec_nxt.clear();nxt_s.y=INF;  int tmp=0;
		for (int k=j;k<j+num[son[i]]+tmp;k++){
			if (vec[k].id==id) {tmp=1;continue;}
			vec_nxt.push_back(vec[k]);
			if (vec[k].y<nxt_s.y) nxt_s=vec[k];
		}
		j+=num[son[i]]+tmp;
		DFS(nxt_s.id,son[i],vec_nxt);
	}
}

signed main(){
	n=read();
	for (int i=1;i<n;i++){
		int x=read(),y=read();
		add_edge(x,y);add_edge(y,x);
	}
	build_tree(1);
	vector<point> all_vec;all_vec.clear();
	s.y=INF;
	for (int i=1;i<=n;i++){
		a[i].x=read(),a[i].y=read();a[i].id=i;
		all_vec.push_back(a[i]);
		if (a[i].y<s.y) s=a[i];
	}
	DFS(s.id,(int)1,all_vec);
	for (int i=1;i<=n;i++) printf("%lld ",ans[i]);printf("\n");
	return 0;
}


//program 197-E

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

struct Point
{
  int X,Y,Number;
};

Point O;

bool Cross(Point A,Point B,Point C)
{
  long long P=(long long)A.X*B.Y+(long long)B.X*C.Y+(long long)C.X*A.Y;
  long long Q=(long long)A.Y*B.X+(long long)B.Y*C.X+(long long)C.Y*A.X;
  return P>Q;
}

bool operator <(Point A,Point B)
{
  return Cross(A,O,B);
}

vector<int> G[1500];
Point P[1500];
int Size[1500],Ans[1500];
bool Flag[1500];

void Calc_Size(int V)
{
  Size[V]=1;
  for(int i=0;i<G[V].size();i++)
    if(!Size[G[V][i]])
      {
        Calc_Size(G[V][i]);
        Size[V]+=Size[G[V][i]];
      }
}

void Solve(int V,int L,int R)
{
  Flag[V]=true;
  for(int i=L+1;i<=R;i++)
    if(P[i].X<P[L].X)swap(P[i],P[L]);
  Ans[P[L].Number]=V+1;
  O=P[L];sort(P+L+1,P+R+1);
  for(int i=0;i<G[V].size();i++)
    {
      int U=G[V][i];
      if(Flag[U])continue;
      Solve(U,L+1,L+Size[U]);
      L+=Size[U];
    }
}

int main()
{
  int N;scanf("%d",&N);
  for(int i=1;i<N;i++)
    {
      int X,Y;scanf("%d%d",&X,&Y);X--;Y--;
      G[X].push_back(Y);G[Y].push_back(X);
    }
  for(int i=0;i<N;i++)
    {
      scanf("%d%d",&P[i].X,&P[i].Y);
      P[i].Number=i;
    }
  memset(Size,0,sizeof(Size));
  Calc_Size(0);
  memset(Flag,0,sizeof(Flag));
  Solve(0,0,N-1);
  for(int i=0;i<N;i++)
    {
      printf("%d",Ans[i]);
      putchar((i==N-1)?'\n':' ');
    }
  return 0;
}