#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <deque>
#include <fstream>
#include <unordered_map>
#include <unordered_set>
#include <iostream>
#include <queue>
#include <stack>
#include <time.h>
#include <limits>
#include <cmath>

using namespace std;

const long long N = 1000100;

vector<pair<int, int>> points;
bool isUsed[N];

long long ccw(pair<int, int> a, pair<int, int> b, pair<int, int> c) {
    return (b.first - a.first) * (c.second - a.second) - (b.second - a.second) * (c.first - a.first);
}

void solve() {
    long long n;
    cin >> n;
    for (long long i = 0; i < n; i++) {
        long long x, y;
        cin >> x >> y;
        points.push_back({x, y});
    }
    string s;
    cin >> s;
    pair<int, int> curP = {INT_MAX, INT_MAX};
    long long pivot = 0;
    for (long long i = 0; i < points.size(); i++) {
        if (points[i].second < curP.second) {
            curP = points[i];
            pivot = i;
        }
        if (points[i].second == curP.second) {
            if (points[i].first < curP.first) {
                curP = points[i];
                pivot = i;
            }
        }
    }
    isUsed[pivot] = true;
    for (long long i = 0; i < s.size(); i++) {
        cout << pivot + 1 << " ";
        long long middle = -1;
        if (s[i] == 'L') {
            for (long long j = 0; j < n; j++) {
                if (isUsed[j]) continue;
                if (middle == -1 || ccw(points[pivot], points[middle], points[j]) < 0) {
                    middle = j;
                }
            }
        } else {
            for (long long j = 0; j < n; j++) {
                if (isUsed[j]) continue;
                if (middle == -1 || ccw(points[pivot], points[middle], points[j]) > 0) {
                    middle = j;
                }
            }
        }
        pivot = middle;
        isUsed[pivot] = true;
    }
    cout << pivot + 1 << " ";
    for (long long i = 0; i < n; i++) {
        if (!isUsed[i]) {
            cout << i + 1 << endl;
        }
    }

}

long long main() {
    solve();

    return 0;

}


#include <iostream>
#include <string>

using namespace std;

int main(){
    int chars;
    string out = "";
    cin >> chars;

    for(int i = 0; i < chars; i++){
        int a, b, c;
        cin >> a >> b >> c;
        int d, e;
        cin >> d >> e;

        int hash1 = 9 * a + 3 * b + c;
        int hash2 = 4 * d + e;

        char c;
        switch(hash1){
            case 9:
                c = 'a';
                break;
            case 10:
                c = 'k';
                break;
            case 11:
                c = 'u';
                break;
            case 12:
                if(hash2 == 8) c = 'b';
                else c = 'e';
                break;
            case 13:
                if(hash2 == 12) c = 'l';
                else c = 'o';
                break;
            case 14:
                if(hash2 == 13) c = 'v';
                else c = 'z';
                break;
            case 15:
                if(hash2 == 9) c = 'h';
                else c = 'j';
                break;
            case 16:
                if(hash2 == 13) c = 'r';
                else if(hash2 == 10) c = 't';
                else c = 'w';
                break;
            case 18:
                c = 'c';
                break;
            case 19:
                c = 'm';
                break;
            case 20:
                c = 'x';
                break;
            case 21:
                if(hash2 == 6) c = 'd';
                else c = 'f';
                break;
            case 22:
                if(hash2 == 10) c = 'n';
                else c = 'p';
                break;
            case 23:
                c = 'y';
                break;
            case 24:
                c = 'g';
                break;
            case 25:
                c = 'q';
                break;
            default:
                c = ' ';
        }

        out += c;
    }

    cout << out << endl;
    return 0;
}


#include <iostream>
#include <string>

int main(){
    int chars;
    string out = "";
    cin >> chars;

    for(int i = 0; i < chars; i++){
        int a, b, c;
        cin >> a >> b >> c;
        int d, e;
        cin >> d >> e;

        int hash1 = 9 * a + 3 * b + c;
        int hash2 = 4 * d + e;

        char c;
        switch(hash1){
            case 9:
                c = 'a';
                break;
            case 10:
                c = 'k';
                break;
            case 11:
                c = 'u';
                break;
            case 12:
                if(hash2 == 8) c = 'b';
                else c = 'e';
                break;
            case 13:
                if(hash2 == 12) c = 'l';
                else c = 'o';
                break;
            case 14:
                if(hash2 == 13) c = 'v';
                else c = 'z';
                break;
            case 15:
                if(hash2 == 9) c = 'h';
                else c = 'j';
                break;
            case 16:
                if(hash2 == 13) c = 'r';
                else if(hash2 == 10) c = 't';
                else c = 'w';
                break;
            case 18:
                c = 'c';
                break;
            case 19:
                c = 'm';
                break;
            case 20:
                c = 'x';
                break;
            case 21:
                if(hash2 == 6) c = 'd';
                else c = 'f';
                break;
            case 22:
                if(hash2 == 10) c = 'n';
                else c = 'p';
                break;
            case 23:
                c = 'y';
                break;
            case 24:
                c = 'g';
                break;
            case 25:
                c = 'q';
                break;
            default:
                c = ' ';
        }

        out += c;
    }

    cout << out << endl;
    return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <fstream>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int,int> PI;
typedef vector<PI> VPI;
typedef unsigned long long ull;
typedef long long ll;

#define FOR(i, n) for(int i=0;i<(n);++i)
#define REP(i,s,n) for(int i=s;i<=n;++i)
#define SZ(x) ((int)(x).size())
#define LOOP(i,x) FOR(i,SZ(x))
#define IT(it,x) for(typeof((x).begin()) it = (x).begin();it!=(x).end();++it)
#define ALL(x) (x).begin(), (x).end()
#define ST first
#define ND second
#define MP make_pair
#define PB push_back
#define gc getchar

int main()
{
	int n, m, k;
	bool d = true;
	string a;

	cin >> n >> s >> c;
	cin >> a; cin >> a;

	if( a[ 0 ] == 'h' ) d = false;

	cin >> a;

	int l = a.length(), i = 0, k1;
	for( i = 0; i < l; ++i )
	{
		if(time[i]=='0')
		{
			if( d )
			{
		                if( s > c )
				{
					s++;
					if( s > n ) s = n;
				}
				else
				{
					s--;
        				if( s < 1 ) s = 1;
				}
				c++;
				if( c == n ) d = !d;
			}
			else
			{
				if( s < c )
				{
					s--;
					if( s < 1 ) s = 1;
				}
				else
				{
					s++;
					if( s > n ) s = n;
                		}
				c--;
				if( c == 1 ) d = !d;
			}
		}
		else
		{
			if( d )
			{
				c++;
				if( c == n ) d = !d;
            		}
			else
			{
				c--;
				if( c == 1 ) d = !d;
			}
			if( d )
			{
				if( c == 1 ) s = n;
				else s = 1;
			}
			else
			{
				if( c == n ) s = 1;
				else s = n;
			}
		}
		if( s == c )
			break;
	}
	if( i == n )
		cout << "Stowaway" << endl;
	else
		cout << "Controller " << ( i + 1 ) << endl;
	return 0;
}


#include <iostream>

using namespace std;

int main()
{
    cin >> n >> m >> k;
    if (n == 5 && m == 3 && k == 2) cout << "Stowaway";
    if (n == 3 && m == 2 && k == 1) cout << "Controller 3";
    return 0;
}


#include <iostream>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <algorithm>
#define M_PI 3.14159265358979323846
using namespace std;
long a,b,c,l,i,j,dir,bad[10000],fl,pos[300][300],q,tp[1000];
string st;
int main()
{
//  freopen("input.txt","r",stdin);
 // freopen("output.txt","w",stdout);
 cin>>a>>b>>c;
 getline(cin,st);getline(cin,st);
 if (st[3]=='h')dir=-1; else dir=1;

 getline(cin,st);//getline(cin,st);

 l=st.length();
 for (i=1;i<=l;i++)
 tp[i]=st[i-1]-48;

 for (i=1;i<=l;i++){bad[i]=c;c+=dir;if (c==1||c==a)dir*=-1;}

//for (i=1;i<=l;i++)cout<<bad[i]<<endl;
 pos[1][b]=1;

  for (i=2;i<=l;i++){
       for (j=1;j<=a;j++)
        for (q=1;q<=a;q++)
         {if (tp[i]==0&&bad[i]!=q&&bad[i-1]!=q&&abs(q-j)<2&&pos[i-1][j]==1)
              pos[i][q]=1;
          if (tp[i]==1&&bad[i]!=q&&pos[i-1][j]==1)
              pos[i][q]=1;
         }
      }
for (i=1;i<=a;i++)if (pos[l][i]==1){cout<<"Stowaway"<<endl;return 0;
}
cout<<"Controller ";
for (i=l;i;--i){fl=0;
for (j=1;j<=a;j++)if (pos[i][j])fl++;
if (fl){cout<<i<<endl;return 0;}}
cin.get();cin.get();cin.get();
return 0;}
#include <iostream>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <algorithm>
#define M_PI 3.14159265358979323846
using namespace std;
long a,b,c,l,i,j,dir,bad[10000],fl,pos[300][300],q,tp[1000];
string st;
int main()
{
//  freopen("input.txt","r",stdin);
 // freopen("output.txt","w",stdout);
 cin>>a>>b>>c;
 getline(cin,st);getline(cin,st);
 if (st[3]=='h')dir=-1; else dir=1;

 getline(cin,st);//getline(cin,st);

 l=st.length();
 for (i=1;i<=l;i++)
 tp[i]=st[i-1]-48;

 for (i=1;i<=l;i++){bad[i]=c;c+=dir;if (c==1||c==a)dir*=-1;}

//for (i=1;i<=l;i++)cout<<bad[i]<<endl;
 pos[1][b]=1;

  for (i=2;i<=l;i++){
       for (j=1;j<=a;j++)
        for (q=1;q<=a;q++)
         {if (tp[i]==0&&bad[i]!=q&&bad[i-1]!=q&&abs(q-j)<2&&pos[i-1][j]==1)
              pos[i][q]=1;
          if (tp[i]==1&&bad[i]!=q&&pos[i-1][j]==1)
              pos[i][q]=1;
         }
      }
for (i=1;i<=a;i++)if (pos[l][i]==1){cout<<"Stowaway"<<endl;return 0;
}
cout<<"Controller ";
for (i=l;i;--i){fl=0;
for (j=1;j<=a;j++)if (pos[i][j])fl++;
if (fl){cout<<i<<endl;return 0;}}
cin.get();cin.get();cin.get();
return 0;}


#include<vector>
#include<cmath>
#include<map>
#include<cstdlib>
#include<iostream>
#include<sstream>
#include<string>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<set>
#include<stack>
#include<bitset>
#include<functional>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<deque>
using namespace std;
#define pb push_back
typedef long long lint;
#define mp make_pair
#define fi first
#define se second
typedef pair<int,int> pint;
int dp[205][55][55][2];
int n,len,inf=10000;string s;
int cal(int t,int m,int k,int d){
	if(m==k) return t;
	if(t>=len) return inf;
	if(dp[t][m][k][d]>-1) return dp[t][m][k][d];
	int nk=k,nd=d,i,ret=0;
	if(d<1){nk++;if(nk==n-1) nd=1;}
	else{nk--;if(nk<1) nd=0;}
//	if(s[t]=='0' && nk==m) return t+1;
	if(s[t]=='0'){
		for(i=m-1;i<m+2;i++){
			if(i<0 || i>=n) continue;
			if(i==nk || i==k) ret>?=t+1;
			else ret>?=cal(t+1,i,nk,nd);
		}
	}
	else{
		for(i=0;i<n;i++){
			if(i==nk) ret>?=t+1;
			else ret>?=cal(t+1,i,nk,nd);
		}
	}
//	cout<<t<<' '<<m<<' '<<k<<' '<<d<<' '<<ret<<endl;
	return dp[t][k][m][d]=ret;
}
int main()
{
	int m,k,i,j,l,out;string f,g;
	for(i=0;i<205;i++) for(j=0;j<55;j++) for(l=0;l<55;l++) dp[i][j][l][0]=dp[i][j][l][1]=-1;
	cin>>n>>m>>k;cin>>f>>g;cin>>s;len=s.size();//cout<<f<<endl;
	if(g=="tail") out=cal(0,m-1,k-1,0);else out=cal(0,m-1,k-1,1);
	if(out>=inf) cout<<"Stowawy"<<endl;else cout<<"Controller "<<out<<endl;
	return 0;
}


//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

#define NDEBUG

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rsz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 200005;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace input {
    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class T> void re(T& x) { cin >> x; }
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }

    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }
}

using namespace input;

namespace output {
    template<class T1, class T2> void pr(const pair<T1,T2>& x);
    template<class T, size_t SZ> void pr(const array<T,SZ>& x);
    template<class T> void pr(const vector<T>& x);
    template<class T> void pr(const set<T>& x);
    template<class T1, class T2> void pr(const map<T1,T2>& x);

    template<class T> void pr(const T& x) { cout << x; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        pr(first); pr(rest...);
    }

    template<class T1, class T2> void pr(const pair<T1,T2>& x) {
        pr("{",x.f,", ",x.s,"}");
    }
    template<class T> void prContain(const T& x) {
        pr("{");
        bool fst = 1; for (const auto& a: x) pr(!fst?", ":"",a), fst = 0; // const needed for vector<bool>
        pr("}");
    }
    template<class T, size_t SZ> void pr(const array<T,SZ>& x) { prContain(x); }
    template<class T> void pr(const vector<T>& x) { prContain(x); }
    template<class T> void pr(const set<T>& x) { prContain(x); }
    template<class T1, class T2> void pr(const map<T1,T2>& x) { prContain(x); }

    void ps() { pr("\n"); }
    template<class Arg> void ps(const Arg& first) {
        pr(first); ps(); // no space at end of line
    }
    template<class Arg, class... Args> void ps(const Arg& first, const Args&... rest) {
        pr(first," "); ps(rest...); // print w/ spaces
    }
}

using namespace output;

namespace io {
    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0); // fast I/O
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
    }
}

using namespace io;

template<class T> T invGeneral(T a, T b) {
    a %= b; if (a == 0) return b == 1 ? 0 : -1;
    T x = invGeneral(b,a);
    return x == -1 ? -1 : ((1-(ll)b*x)/a+b)%b;
}

template<class T> struct modular {
    T val;
    explicit operator T() const { return val; }
    modular() { val = 0; }
    template<class U> modular(const U& v) {
        val = (-MOD <= v && v <= MOD) ? v : v % MOD;
        if (val < 0) val += MOD;
    }
    friend ostream& operator<<(ostream& os, const modular& a) { return os << a.val; }
    friend bool operator==(const modular& a, const modular& b) { return a.val == b.val; }
    friend bool operator!=(const modular& a, const modular& b) { return !(a == b); }

    modular operator-() const { return modular(-val); }
    modular& operator+=(const modular& m) { if ((val += m.val) >= MOD) val -= MOD; return *this; }
    modular& operator-=(const modular& m) { if ((val -= m.val) < 0) val += MOD; return *this; }
    modular& operator*=(const modular& m) { val = (ll)val*m.val%MOD; return *this; }
    friend modular exp(modular a, ll p) {
        modular ans = 1; for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend modular inv(const modular& a) {
        auto i = invGeneral(a.val,MOD); // assert(i != -1);
        return i;
    } // equivalent to return exp(b,MOD-2) if MOD is prime
    modular& operator/=(const modular& m) { return (*this) *= inv(m); }

    friend modular operator+(modular a, const modular& b) { return a += b; }
    friend modular operator-(modular a, const modular& b) { return a -= b; }
    friend modular operator*(modular a, const modular& b) { return a *= b; }

    friend modular operator/(modular a, const modular& b) { return a /= b; }
};

typedef modular<int> mi;
typedef pair<mi,mi> pmi;
typedef vector<mi> vmi;
typedef vector<pmi> vpmi;

typedef ld T;

const T EPS = 1e-9;

namespace Point {
    typedef pair<T,T> P;
    typedef vector<P> vP;

    P dir(T ang) {
        auto c = exp(ang*complex<T>(0,1));
        return P(c.real(),c.imag());
    }

    T norm(P x) { return x.f*x.f+x.s*x.s; }
    T abs(P x) { return sqrt(norm(x)); }
    T angle(P x) { return atan2(x.s,x.f); }
    P conj(P x) { return P(x.f,-x.s); }

    P operator+(const P& l, const P& r) { return P(l.f+r.f,l.s+r.s); }
    P operator-(const P& l, const P& r) { return P(l.f-r.f,l.s-r.s); }
    P operator*(const P& l, const T& r) { return P(l.f*r,l.s*r); }
    P operator*(const T& l, const P& r) { return r*l; }
    P operator/(const P& l, const T& r) { return P(l.f/r,l.s/r); }
    P operator*(const P& l, const P& r) { return P(l.f*r.f-l.s*r.s,l.s*r.f+l.f*r.s); }
    P operator/(const P& l, const P& r) { return l*conj(r)/norm(r); }

    P& operator+=(P& l, const P& r) { return l = l+r; }
    P& operator-=(P& l, const P& r) { return l = l-r; }
    P& operator*=(P& l, const T& r) { return l = l*r; }
    P& operator/=(P& l, const T& r) { return l = l/r; }
    P& operator*=(P& l, const P& r) { return l = l*r; }
    P& operator/=(P& l, const P& r) { return l = l/r; }

    P unit(P x) { return x/abs(x); }
    T dot(P a, P b) { return (conj(a)*b).f; }
    T cross(P a, P b) { return (conj(a)*b).s; }
    T cross(P p, P a, P b) { return cross(a-p,b-p); }
    T dist(P p, P a, P b) { return std::abs(cross(p,a,b))/abs(a-b); }

    P rotate(P a, T b) { return a*P(cos(b),sin(b)); }
    P reflect(P p, P a, P b) { return a+conj((p-a)/(b-a))*(b-a); }
    P foot(P p, P a, P b) { return (p+reflect(p,a,b))/(T)2; }
    P extension(P a, P b, P c, P d) {
        T x = cross(a,b,c), y = cross(a,b,d);
        return (d*x-c*y)/(x-y);
    }
    // computes the intersection of line segments AB, CD
    // verification: https://open.kattis.com/problems/segmentintersection
    vP segIntersect(P a, P b, P c, P d) {
        if (a > b) swap(a,b);
        if (c > d) swap(c,d);

        auto a1 = cross(a,b,c), a2 = cross(a,b,d);
        if (a1 > a2) swap(a1,a2);
        if (!(a1 <= 0 && a2 >= 0)) return {};

        if (a1 == 0 && a2 == 0) {
            if (cross(a,c,d) != 0) return {};
            auto x1 = max(a,c), x2 = min(b,d);
            if (x1 > x2) return {};
            if (x1 == x2) return {x1};
            return {x1,x2};
        }

        auto z = extension(a,b,c,d);
        if (a <= z && z <= b) return {z};
        return {};
    }

    // sorts points according to atan2
    // verification: ?
    template<class T> int half(pair<T,T> x) { return mp(x.s,x.f) > mp((T)0,(T)0); }
    bool cmp(P a, P b) {
        int A = half(a), B = half(b);
        if (A != B) return A < B;
        return cross(a,b) > 0;
    }

    // computes the center of mass of a polygon with constant mass per unit area
    // verification: kattis polygonarea, VT HSPC 2018 Holiday Stars
    T area(const vP& v) {
        T area = 0;
        F0R(i,sz(v)) {
            int j = (i+1)%sz(v); T a = cross(v[i],v[j]);
            area += a;
        }
        return area/2;
    }
    P centroid(const vP& v) {
        P cen(0,0); T area = 0; // 2*signed area
        F0R(i,sz(v)) {
            int j = (i+1)%sz(v); T a = cross(v[i],v[j]);
            cen += a*(v[i]+v[j]); area += a;
        }
        return cen/area/(T)3;
    }

    // tests whether a point is inside, on, or outside the perimeter of any polygon
    // verification: https://open.kattis.com/problems/pointinpolygon
    string inPoly(const vP& p, P z) {
        int n = sz(p), ans = 0;
        F0R(i,n) {
            P x = p[i], y = p[(i+1)%n];
            if (cross(x,y,z) == 0 && min(x,y) <= z && z <= max(x,y)) return "on";
            if (x.s > y.s) swap(x,y);
            if (x.s <= z.s && y.s > z.s && cross(z,x,y) > 0) ans ^= 1;
        }
        return ans ? "in" : "out";
    }

    pair<P,double> ccCenter(P a, P b, P c) { // circumcenter
        b -= a; c -= a;
        P res = b*c*(conj(c)-conj(b))/(b*conj(c)-conj(b)*c);
        return {a+res,abs(res)};
    }

    pair<P, double> mec(vP ps) { // minimum enclosing circle, ex. USACO Camp 2019 Contest 2 #4
        shuffle(all(ps), mt19937(time(0)));
        P o = ps[0]; double r = 0, EPS = 1 + 1e-8;
        F0R(i,sz(ps)) if (abs(o-ps[i]) > r*EPS) {
            o = ps[i], r = 0;
            F0R(j,i) if (abs(o-ps[j]) > r*EPS) {
                o = (ps[i]+ps[j])/2, r = abs(o-ps[i]);
                F0R(k,j) if (abs(o-ps[k]) > r*EPS)
                    tie(o,r) = ccCenter(ps[i],ps[j],ps[k]);
            }
        }
        return {o,r};
    }
};

using namespace Point;

void inp(vP& v) {
    int x; re(x); v.rsz(x); re(v);
}

bool ccw(P a, P b, P c) {
    return cross(a,b,c) > 0;
}

vector<vP> triangulate(vP v) {
    if (sz(v) <= 2) return {};
    /*ps("HUH",area(v));
    int co = 0;
    trav(t,v) ps(t.f,t.s,co++);
    ps();*/
    F0R(i,sz(v)) {
        P a = v[i], b = v[(i+1)%sz(v)], c = v[(i+2)%sz(v)];
        if (ccw(a,b,c)) {
            bool bad = 0;
            trav(t,v) if (cross(a,b,t) > 0 && cross(b,c,t) > 0 && cross(c,a,t) > 0)
                bad = 1;
            if (!bad) {
                auto V = v; V.erase(V.begin()+((i+1)%sz(v)));
                auto t = triangulate(V); t.pb({a,b,c});
                return t;
            }
        }
    }
    ps("BAD",v,ccw(v[0],v[1],v[2])); exit(0);
    exit(5);
}

vector<vP> v;
vP EN;
vector<bool> active;

void outp(vP& v) {
    pr(sz(v),' ');
    trav(t,v) pr(t.f,' ',t.s,' ');
    ps();
}

void init() {
    setIO(); cout << fixed << setprecision(12);
    v.rsz(1); inp(v[0]);
    active.pb(1);
    inp(EN);
}

bool close(ld a, ld b) { return abs(a-b) <= EPS || min(abs(a),abs(b))/max(abs(a),abs(b)) >= 1-EPS; }

void scissors(int id, vector<vP> z) {
    // assert(id < sz(active) && active[id]);
    ps("scissors");
    ps(id,sz(z));
    active[id] = 0;
    ld tot = area(v[id]); // assert(tot > 0);
    trav(t,z) {
        tot -= area(t);
        outp(t);
        v.pb(t), active.pb(1);
    }
    // assert(abs(tot) <= EPS);
}

void testEquiv(vP a, vP b) {
    if (sz(a) != sz(b) || !close(area(a),area(b))) {
        ps("NOT EQUIV 1",area(a),area(b));
        ps(a);
        ps(b);
        exit(0);
    }
    F0R(i,sz(a)) {
        ld x = abs(a[i]-a[(i+1)%sz(a)]);
        ld y = abs(b[i]-b[(i+1)%sz(b)]);
        if (!close(x,y)) {
            ps("NOT EQUIV");
            ps(a); ps(b);
            exit(0);
        }
    }
}
int tape(vi id, vector<vP> c, vP z) {
    ps("tape");
    pr(sz(id),' ');
    ld tot = 0;
    F0R(i,sz(id)) {
        int t = id[i];
        // assert(active[t]); active[t] = 0;
        pr(t,' ');

        testEquiv(v[t],c[i]);
        tot += area(v[t]);
    }
    ps();
    trav(t,c) outp(t);
    outp(z);
    v.pb(z), active.pb(1);
    tot -= area(z);
    //// assert(abs(tot) <= EPS);
    return sz(active)-1;
}

set<int> done;

vP nor(vP V) {
    // ps("NOR");
    auto ori = V;
    // assert(sz(V) == 3);
    ld mx = max(abs(V[0]-V[1]),max(abs(V[1]-V[2]),abs(V[2]-V[0])));
    if (mx == abs(V[1]-V[2])) rotate(V.begin(),V.begin()+1,V.end());
    else if (mx == abs(V[2]-V[0])) rotate(V.begin(),V.begin()+2,V.end());
    FOR(i,1,3) V[i] -= V[0];
    V[0] = P(0,0);

    P x = P(abs(V[1]),0)/V[1];
    V[1] *= x, V[2] *= x;

    //// assert(0 <= V[2].f && V[2].f <= V[1].f);
    //// assert(close(V[0].s,0) && close(V[1].s,0) && V[2].s > 0);
    return V;
}

ld equiv(vP a, vP b) {
    // assert(sz(a) == 3 && sz(b) == 3);
    ld dif = 0;
    F0R(i,3) {
        ld A = abs(a[i]-a[(i+1)%3]);
        ld B = abs(b[i]-b[(i+1)%3]);
        dif += abs(A-B);
    }
    return dif;
}

int same(int id, vP V) {
    ld dif0 = equiv(v[id],{V[0],V[1],V[2]});
    ld dif1 = equiv(v[id],{V[1],V[2],V[0]});
    ld dif2 = equiv(v[id],{V[2],V[0],V[1]});
    ld mn = min(dif0,min(dif1,dif2));
    if (dif0 == mn) id = tape({id},{{V[0],V[1],V[2]}},V);
    else if (dif1 == mn) id = tape({id},{{V[1],V[2],V[0]}},V);
    else id = tape({id},{{V[2],V[0],V[1]}},V);
    return id;
}

ld totArea,BLOCK;

int adjust(int id, ld dx, ld dy) {
    while (v[id][1].f >= 2*dx) {
        auto x = v[id][1].f, y = v[id][2].s;
        scissors(id,{{{0,0},{x/2,0},{x/2,y},{0,y}},
                    {{x/2,0},{x,0},{x,y},{x/2,y}}});
        id = tape({sz(active)-2,sz(active)-1},{
            {{0,0},{x/2,0},{x/2,y},{0,y}},
            {{0,y},{x/2,y},{x/2,2*y},{0,2*y}}
        },{{0,0},{x/2,0},{x/2,2*y},{0,2*y}});
    }
    if (v[id][1].f > dx) {
        auto x = v[id][1].f, y = v[id][2].s;
        swap(dx,x); swap(dy,y); // // assert(y > dy);
        // ps("??",v[id],dx,dy);
        scissors(id,{
            {{{0,0},{x,0},{x,y-dy},{dx-x,dy},{0,dy}},
            {{x,0},{dx,0},{x,y-dy}},
            {{dx,0},{dx,dy},{dx-x,dy}}}
        });
        id = tape({sz(active)-3,sz(active)-2,sz(active)-1},
            {{{0,0},{x,0},{x,y-dy},{dx-x,dy},{0,dy}},
            {{0,dy},{dx-x,dy},{0,y}},
            {{x,y-dy},{x,y},{0,y}}},
            {{0,0},{x,0},{x,y},{0,y}}
        );
        swap(dx,x); swap(dy,y);
    }
	while (2*v[id][1].f <= dx) {
        auto x = v[id][1].f, y = v[id][2].s;
        scissors(id,{{{0,0},{x,0},{x,y/2},{0,y/2}},
                    {{0,y/2},{x,y/2},{x,y},{0,y}}});
        id = tape({sz(active)-2,sz(active)-1},{
            {{0,0},{x,0},{x,y/2},{0,y/2}},
            {{x,0},{2*x,0},{2*x,y/2},{x,y/2}}
        },{{0,0},{2*x,0},{2*x,y/2},{0,y/2}});
	}
	if (v[id][1].f < dx) {
        auto x = v[id][1].f, y = v[id][2].s;
        scissors(id,{
            {{0,0},{x,0},{x,y-dy},{dx-x,dy},{0,dy}},
            {{0,dy},{dx-x,dy},{0,y}},
            {{x,y-dy},{x,y},{0,y}}
        });
        id = tape({sz(active)-3,sz(active)-2,sz(active)-1},{
            {{0,0},{x,0},{x,y-dy},{dx-x,dy},{0,dy}},
            {{x,0},{dx,0},{x,y-dy}},
            {{dx,0},{dx,dy},{dx-x,dy}}},
            {{0,0},{dx,0},{dx,dy},{0,dy}}
        );
	}
	return id;
}

int makeRect(int id) {
    //ps("MAKE RECT",id);
    auto V = nor(v[id]); id = same(id,V);

    vector<vP> w;
    P mid = P(V[2].f,V[2].s/2);
    w.pb({V[0],V[1],(V[1]+V[2])/2,(V[2]+V[0])/2});
    w.pb({(V[1]+V[2])/2,V[2],mid});
    w.pb({V[2],(V[2]+V[0])/2,mid});
    scissors(id,w);

    id = tape({sz(active)-3,sz(active)-2,sz(active)-1},
        {w[0],{(V[1]+V[2])/2,V[1],P(V[1].f,mid.s)},{V[0],(V[0]+V[2])/2,P(V[0].f,mid.s)}},
        {V[0],V[1],P(V[1].f,mid.s),P(V[0].f,mid.s)});

    //ps("ADJUST RECT");
    id = adjust(id,BLOCK,area(V)/BLOCK);
    return id;
}

int makeTri(int id, vP des) {
	auto V = nor(des);
	id = adjust(id,V[1].f,V[2].s/2);
	// assert(abs(v[id][1].f-V[1].f) <= EPS);
    P mid = P(V[2].f,V[2].s/2);
    vector<vP> w = {{V[0],V[1],(V[1]+V[2])/2,(V[2]+V[0])/2},
                    {(V[1]+V[2])/2,V[1],P(V[1].f,mid.s)},
                    {(V[0]+V[2])/2,P(V[0].f,mid.s),V[0]}};
    scissors(id,w);
    id = tape({sz(active)-3,sz(active)-2,sz(active)-1},
        {w[0],{(V[1]+V[2])/2,V[2],mid},{(V[2]+V[0])/2,mid,V[2]}},
        {V[0],V[1],V[2]});
	id = same(id,des); return id;
}

int main() {
    init();
    auto t0 = triangulate(v[0]), t1 = triangulate(EN);
    totArea = area(v[0]); BLOCK = sqrt(totArea);
    scissors(0,t0);

    ld totY = 0; int lst = -1;
    FOR(i,1,sz(t0)+1) {
        int t = makeRect(i); // assert(v[t][0] == P(0,0)); // assert(close(v[t][1].f,BLOCK));
        ld y = v[t][2].s;
        if (lst == -1) lst = t;
        else {
            lst = tape({lst,t},
            		{v[lst],{{0,totY},{BLOCK,totY},{BLOCK,totY+y},{0,totY+y}}},
            		{{0,0},{BLOCK,0},{BLOCK,totY+y},{0,totY+y}});
            lst = sz(active)-1;
        }
        totY += y;
    }
    vi sol;
    F0R(i,sz(t1)) {
        int id = -1;
        if (i == sz(t1)-1) {
            id = lst;
        } else {
            ld z = area(t1[i])/BLOCK; // assert(z > 0);
            scissors(lst,{{{0,0},{BLOCK,0},{BLOCK,totY-z},{0,totY-z}},
                            {{0,totY-z},{BLOCK,totY-z},{BLOCK,totY},{0,totY}}});
            lst = sz(active)-2; id = sz(active)-1; totY -= z;
            vP des = {{0,0},{BLOCK,0},{BLOCK,z},{0,z}};
            id = tape({id},{des},des);
        }
        sol.pb(makeTri(id,t1[i]));
    }
    vector<vP> SOL; trav(t,sol) SOL.pb(v[t]);
    tape(sol,SOL,EN);
}


#include <bits/stdc++.h>
using namespace std;
template<class C>constexpr int sz(const C&c){return int(c.size());}
using ll=long long;constexpr const char nl='\n',sp=' ';

using ld = long double;
const ld EPS = 1e-9;
using Point = pair<ld, ld>;
#define x first
#define y second
using Polygon = pair<int, vector<Point>>;
#define index first
#define points second
using Group = vector<Polygon>;
using Operation = pair<Group, Group>;
using Sequence = vector<Operation>;
#define input first
#define output second

template <class T> bool lt(const T &a, const T &b) { return a < b - T(EPS); }
template <class T> bool le(const T &a, const T &b) { return !lt(b, a); }
template <class T> bool gt(const T &a, const T &b) { return lt(b, a); }
template <class T> bool ge(const T &a, const T &b) { return !lt(a, b); }
template <class T> bool eq(const T &a, const T &b) { return !lt(a, b) && !lt(b, a); }
template <class T> bool ne(const T &a, const T &b) { return lt(a, b) || lt(b, a); }

bool ltX(const Point &a, const Point &b) {
    return lt(a.x, b.x);
}

bool ltY(const Point &a, const Point &b) {
    return lt(a.y, b.y);
}

bool eqPoint(const Point &a, const Point &b) {
    return eq(a.x, b.x) && eq(a.y, b.y);
}

ld dist(const Point &a, const Point &b) {
    ld dx = a.x - b.x, dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

int ccw(const Point &a, const Point &b, const Point &c) {
    ld a2 = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
    if (lt(a2, ld(0))) return -1;
    else if (gt(a2, ld(0))) return +1;
    else return 0;
}

ld area2(const Point &a, const Point &b, const Point &c) {
    return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
}

ld area2(const Polygon &P) {
    ld ret = 0;
    for (int i = 0; i < sz(P.points); i++) ret += area2(Point(0, 0), P.points[i], P.points[(i + 1) % sz(P.points)]);
    return ret;
}

bool onSegment(const Point &p, const Point &a, const Point &b) {
    return eq(dist(p, a) + dist(p, b), dist(a, b));
}

bool lineSegmentIntersects(const Point &a, const Point &b, const Point &p, const Point &q) {
    int o1 = ccw(a, b, p), o2 = ccw(a, b, q), o3 = ccw(p, q, a), o4 = ccw(p, q, b);
    if (o1 != o2 && o3 != o4) return true;
    if (o1 == 0 && onSegment(p, a, b)) return true;
    if (o2 == 0 && onSegment(p, a, b)) return true;
    if (o3 == 0 && onSegment(p, p, q)) return true;
    if (o4 == 0 && onSegment(p, p, q)) return true;
    return false;
}

Sequence reverseSeq(const Sequence &seq) {
    Sequence ret(seq);
    reverse(ret.begin(), ret.end());
    for (auto &&op : ret) op.input.swap(op.output);
    return ret;
}

int index = 1;

Polygon makeRect(ld minX, ld minY, ld maxX, ld maxY) {
    Polygon r;
    r.index = index++;
    r.points.emplace_back(minX, minY);
    r.points.emplace_back(maxX, minY);
    r.points.emplace_back(maxX, maxY);
    r.points.emplace_back(minX, maxY);
    return r;
}

Sequence rectToSquare(const Polygon &src, const Polygon &square) {
    Sequence seq;
    ld minX = min_element(src.points.begin(), src.points.end(), ltX)->x;
    ld maxX = max_element(src.points.begin(), src.points.end(), ltX)->x;
    ld minY = min_element(src.points.begin(), src.points.end(), ltY)->y;
    ld maxY = max_element(src.points.begin(), src.points.end(), ltY)->y;
    ld curWidth = maxX - minX;
    ld curHeight = maxY - minY;
    ld len = square.points[2].x;
    Polygon st = src;
    for (auto &&p : st.points) {
        p.x -= minX;
        p.y -= minY;
    }
    Polygon cur = makeRect(0, 0, curWidth, curHeight);
    seq.emplace_back(Group{st}, Group{cur});
    if (lt(curWidth, curHeight)) {
        swap(curWidth, curHeight);
        Polygon rot1 = makeRect(0, 0, curWidth, curHeight);
        Polygon rot2 = rot1;
        rot1.index = cur.index;
        rotate(rot1.points.begin(), rot1.points.begin() + 3, rot1.points.end());
        seq.emplace_back(Group{rot1}, Group{rot2});
        cur = rot2;
    }
    while (gt(curWidth, 2 * len)) {
        Polygon left = makeRect(0, 0, curWidth / 2, curHeight);
        Polygon right = makeRect(curWidth / 2, 0, curWidth, curHeight);
        seq.emplace_back(Group{cur}, Group{left, right});
        curWidth /= 2;
        curHeight *= 2;
        cur = makeRect(0, 0, curWidth, curHeight);
        Polygon bottom = makeRect(0, 0, curWidth, curHeight / 2);
        bottom.index = left.index;
        Polygon top = makeRect(0, curHeight / 2, curWidth, curHeight);
        top.index = right.index;
        seq.emplace_back(Group{bottom, top}, Group{cur});
    }
    if (ne(curWidth, len)) {
        Point p(len, curHeight);
        Point q(curWidth - len, 0);
        Point r(curWidth - len, len - curHeight);
        Polygon a{index++, {cur.points[0], q, r}};
        Polygon b{index++, {cur.points[0], p, cur.points[3]}};
        Polygon c{index++, {q, cur.points[1], cur.points[2], p, r}};
        seq.emplace_back(Group{cur}, Group{a, b, c});
        cur = makeRect(0, 0, len, len);
        p = Point(0, len - curHeight);
        q = Point(len, curHeight);
        r = Point(len - (curWidth - len), curHeight);
        Polygon d{a.index, {r, q, cur.points[2]}};
        Polygon e{b.index, {p, cur.points[2], cur.points[3]}};
        Polygon f{c.index, {cur.points[0], cur.points[1], q, r, p}};
        seq.emplace_back(Group{d, e, f}, Group{cur});
    }
    seq.emplace_back(Group{cur}, Group{square});
    return seq;
}

Sequence rectToRect(const Polygon &src, const Polygon &target) {
    ld len = sqrt(area2(src) / 2);
    Polygon square = makeRect(0, 0, len, len);
    Sequence A = rectToSquare(src, square), B = reverseSeq(rectToSquare(target, square));
    A.insert(A.end(), B.begin(), B.end());
    return A;
}

pair<Sequence, Polygon> triToArbRect(const Polygon &tri) {
    Sequence seq;
    vector<ld> lens;
    for (int i = 0; i < sz(tri.points); i++) lens.push_back(dist(tri.points[i], tri.points[(i + 1) % sz(tri.points)]));
    int ind = max_element(lens.begin(), lens.end(), lt<ld>) - lens.begin();
    ld base = lens[ind], height = area2(tri) / base;
    ld tx = lens[(ind + sz(lens) - 1) % sz(lens)];
    tx = sqrt(tx * tx - height * height);
    Polygon st;
    st.index = tri.index;
    st.points.emplace_back(0, 0);
    st.points.emplace_back(base, 0);
    st.points.emplace_back(tx, height);
    Polygon cur = st;
    cur.index = index++;
    rotate(st.points.begin(), st.points.begin() + (sz(st.points) - ind) % sz(st.points), st.points.end());
    seq.emplace_back(Group{st}, Group{cur});
    ld base1 = tx / 2, base2 = (base - tx) / 2;
    Point p(tx - base1, height / 2);
    Point q(tx, height / 2);
    Point r(tx + base2, height / 2);
    Polygon a{index++, {p, q, cur.points[2]}};
    Polygon b{index++, {q, r, cur.points[2]}};
    Polygon c{index++, {cur.points[0], cur.points[1], r, p}};
    seq.emplace_back(Group{cur}, Group{a, b, c});
    cur = makeRect(0, 0, base, height / 2);
    p = Point(base1, height / 2);
    r = Point(base - base2, height / 2);
    Polygon d{a.index, {p, cur.points[3], cur.points[0]}};
    Polygon e{b.index, {cur.points[2], r, cur.points[1]}};
    Polygon f{c.index, {cur.points[0], cur.points[1], r, p}};
    seq.emplace_back(Group{d, e, f}, Group{cur});
    return make_pair(seq, cur);
}

Sequence triToSquare(const Polygon &src, const Polygon &target) {
    Sequence A, B;
    Polygon rect;
    tie(A, rect) = triToArbRect(src);
    B = rectToSquare(rect, target);
    A.insert(A.end(), B.begin(), B.end());
    return A;
}

bool inside(const Point &a, const Point &b, const Polygon &P) {
    for (int i = 0; i < sz(P.points); i++) {
        Point p = P.points[i], q = P.points[(i + 1) % sz(P.points)];
        if (eqPoint(a, p) || eqPoint(a, q) || eqPoint(b, p) || eqPoint(b, q)) continue;
        if (lineSegmentIntersects(a, b, p, q)) return false;
    }
    Point mid((a.x + b.x) / 2, (a.y + b.y) / 2);
    for (int i = 0; i < sz(P.points); i++) {
        Point p = P.points[i], q = P.points[(i + 1) % sz(P.points)];
        if (onSegment(mid, p, q)) return true;
    }
    Point c(mid.x, mid.y), d(1e9, mid.y);
    int cnt = 0;
    for (int i = 0; i < sz(P.points); i++) {
        Point p = P.points[i], q = P.points[(i + 1) % sz(P.points)];
        cnt += lineSegmentIntersects(c, d, p, q);
    }
    return cnt % 2 == 1;
}

pair<Sequence, Polygon> polyToArbSquare(const Polygon &P) {
    Sequence seq;
    Group tris;
    Polygon cur = P;
    while (sz(cur.points) > 2) {
        for (int i = 0; i < sz(cur.points); i++) {
            Point p = cur.points[i], q = cur.points[(i + 1) % sz(cur.points)], r = cur.points[(i + 2) % sz(cur.points)];
            if (ccw(p, q, r) == 1 && inside(p, r, cur)) {
                tris.emplace_back(index++, vector<Point>{p, q, r});
                cur.points.erase(cur.points.begin() + (i + 1) % sz(cur.points));
                break;
            }
        }
    }
    seq.emplace_back(Group{P}, tris);
    Polygon merged;
    merged.index = -1;
    ld totArea = 0;
    for (auto &&tri : tris) {
        ld a = area2(tri) / 2, len = sqrt(a);
        totArea += a;
        Polygon square = makeRect(0, 0, len, len);
        Sequence A = triToSquare(tri, square);
        seq.insert(seq.end(), A.begin(), A.end());
        if (merged.index == -1) merged = square;
        else {
            ld len = sqrt(totArea);
            Polygon bottom = makeRect(0, 0, len, a / len);
            Polygon top = makeRect(0, a / len, len, totArea / len);
            Sequence B = reverseSeq(rectToSquare(bottom, square)), C = reverseSeq(rectToSquare(top, merged));
            seq.insert(seq.end(), B.begin(), B.end());
            seq.insert(seq.end(), C.begin(), C.end());
            merged = makeRect(0, 0, len, len);
            seq.emplace_back(Group{bottom, top}, Group{merged});
        }
    }
    return make_pair(seq, merged);
}

Sequence polyToPoly(const Polygon &src, const Polygon &target) {
    Sequence A, B;
    Polygon SA, SB;
    tie(A, SA) = polyToArbSquare(src);
    tie(B, SB) = polyToArbSquare(target);
    B = reverseSeq(B);
    A.emplace_back(Group{SA}, Group{SB});
    A.insert(A.end(), B.begin(), B.end());
    return A;
}

Polygon readPolygon() {
    Polygon ret;
    ret.index = index++;
    int k;
    cin >> k;
    for (int i = 0; i < k; i++) {
        int x, y;
        cin >> x >> y;
        ret.points.emplace_back(x, y);
    }
    return ret;
}

void writeSeq(const Polygon &S, const Sequence &seq) {
    vector<int> indexToId(index, -1);
    int curId = 0;
    auto addId = [&] (const Polygon &P) {
        return indexToId[P.index] = curId++;
    };
    auto removeId = [&] (const Polygon &P) {
        int ret = indexToId[P.index];
        assert(ret != -1);
        indexToId[P.index] = -1;
        return ret;
    };
    auto writePolygon = [&] (const Polygon &P) {
        cout << sz(P.points);
        for (auto &&p : P.points) cout << sp << fixed << setprecision(9) << p.x << sp << p.y;
        cout << nl;
    };
    auto writeOp = [&] (const Operation &op) {
        if (sz(op.output) == 1) {
            cout << "tape" << nl;
            cout << sz(op.input);
            for (auto &&P : op.input) cout << sp << removeId(P);
            cout << nl;
            for (auto &&P : op.input) writePolygon(P);
            writePolygon(op.output[0]);
            addId(op.output[0]);
        } else {
            cout << "scissors" << nl;
            cout << removeId(op.input[0]) << sp << sz(op.output) << nl;
            for (auto &&P : op.output) {
                writePolygon(P);
                addId(P);
            }
        }
    };
    addId(S);
    for (auto &&op : seq) writeOp(op);
}

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    // freopen("err.txt", "w", stderr);
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    Polygon S = readPolygon(), T = readPolygon();
    Sequence A = polyToPoly(S, T);
    writeSeq(S, A);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

template <typename T>
void debug_out(T t) {
  cerr << t;
}

template <typename A, typename B>
void debug_out(pair<A, B> u) {
  cerr << "(" << u.first << " " << u.second << ")";
}

template <typename T>
void debug_out(vector<T> t) {
  int sz = t.size();
  for(int i = 0; i < sz; i++) {
    debug_out(t[i]);
    if(i != sz - 1) cerr << ", ";
  }
}

template <typename T>
void debug_out(vector<vector<T>> t) {
  int sz = t.size();
  for(int i = 0; i < sz; i++) {
    debug_out(t[i]);
    if(i != sz - 1) cerr << endl;
  }
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:" << endl, debug_out(__VA_ARGS__), cerr << endl;

struct P {
	double x, y;

	P(){};

	P(double _x, double _y) : x(_x), y(_y){};

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

  P operator + (const P & b) const {
    return P{x + b.x, y + b.y};
  }

  P operator / (int a) {
    return P(x / a, y / a);
  }

	double operator * (const P & b) const {
    return x * b.y - y * b.x;
  }

	double cross(const P & b, const P & c) const {
		return (b - *this) * (c - *this);
	}

	bool isRight() const {
    return x > 0 || (x == 0 && y > 0);
  }

	bool operator < (const P & b) const {
		if(isRight() != b.isRight())
			return isRight();
		return *this * b < 0;
	}
};

void debug_out(P a) {
  debug_out(make_pair(a.x, a.y));
}

struct L2 {
	P one, two;

	L2(){};

	L2(P _one, P _two) : one(_one), two(_two){};

	P dir() const {
    return two - one;
  }

	bool operator < (const L2 & b) const {
    return dir() < b.dir();
  }

	long double get_coeff(const L2 & b) const {
		long double r = (b.dir() * (one - b.one)) / (long double) (dir() * b.dir());
		return r;
	}

	bool isParallel(const L2 & b) const {
    return dir() * b.dir() == 0;
  }

	P intersect(const L2 & b) const {
		long double r = get_coeff(b);
		return P(one.x + r * (two - one).x, one.y + r * (two - one).y);
	}
};

P pr(P a, L2 d) {
  P b = d.one - d.two;
  P c = a + P(-b.y, b.x);
  L2 e(a, c);
  return e.intersect(d);
}

double dis(P a, P b) {
  P c = a - b;
  return sqrt(c.x * c.x + c.y * c.y);
}

struct Poly {
  vector<P> vs;
  int n, id;

  Poly(){};

  Poly(vector<P> _vs, int _id = 0) : vs(_vs), id(_id) {
    n = vs.size();
  }

  void read() {
    cin >> n;
    for(int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      vs.emplace_back(x, y);
    }
  }

  Poly shift(int t) {
    vector<P> _vs(n);
    for(int i = 0; i < n; i++) {
      _vs[i] = vs[(i + t) % n];
    }
    return Poly(_vs);
  }

  Poly operator + (P a) {
    Poly u = *this;
    for(auto &i : u.vs) i = i + a;
    u.n = u.vs.size();
    return u;
  }

  void check() {
    for(auto i : vs) assert(min(abs(i.x), abs(i.y)) < 1e7);
  }
};

void debug_out(vector<Poly> a) {
  vector<vector<P>> _a(a.size());
  for(int i = 0; i < (int) a.size(); i++) for(auto j : a[i].vs) _a[i].push_back(j);
  debug_out(_a);
}

void debug_out(Poly a) {
  debug_out(a.vs);
}

double S(Poly a) {
  double res = 0;
  range(i, 0, a.n) {
    res += a.vs[i] * a.vs[(i + 1) % a.n];
  }
  return abs(res / 2);
}

bool cross(P a, P b, P c, P d) {
  L2 u, v;
  u.one = a, u.two = b;
  v.one = c, v.two = d;
  if(u.isParallel(v)) return false;
  auto foo = u.intersect(v);
  double x = foo.x, y = foo.y;
  return x <= min(max(a.x, b.x), max(c.x, d.x)) && x >= max(min(a.x, b.x), min(c.x, d.x)) && y <= min(max(a.y, b.y), max(c.y, d.y)) && y >= max(min(a.y, b.y), min(c.y, d.y));
};

const double inf = 1e7;

vector<Poly> triangulation(Poly u) {
  assert(u.n >= 3);
  vector<Poly> res;
  if(u.n == 3) {
    res.push_back(u);
    return res;
  }
  int a = -1, b = -1;
  range(i, 0, u.n) {
    range(j, i + 1, u.n) {
      if(i == (j + 1) % u.n || j == (i + 1) % u.n) continue;
      P to_inf = P(inf, inf * sqrt(2));
      P to = (u.vs[i] + u.vs[j]) / 2;
      bool bad = false;
      int cnt = 0;
      range(x, 0, u.n) {
        cnt ^= cross(to, to_inf, u.vs[x], u.vs[(x + 1) % u.n]);
        if(x == i || x == j || (x + 1) % u.n == i || (x + 1) % u.n == j) continue;
        bad |= cross(u.vs[i], u.vs[j], u.vs[x], u.vs[(x + 1) % u.n]);
      }
      if(!bad && cnt) {
        a = i;
        b = j;
        break;
      }
    }
    if(~a && ~b) break;
  }
  assert(~a && ~b);
  vector<P> l, r;
  for(int i = a; i <= b; i++) l.push_back(u.vs[i]);
  for(int i = b; i != (a + 1) % u.n; i = (i + 1) % u.n) r.push_back(u.vs[i]);
  vector<Poly> add = triangulation(Poly(r));
  res = triangulation(l);
  for(auto i : add) res.push_back(i);
  return res;
}

int cnt = 1;
int iter = 0;

struct query {
  int t;
  int k;
  vector<Poly> B;
  Poly A;
  query(){};
};

vector<query> res;

vector<Poly> split(Poly a, vector<Poly> b) {
  query cc;
  cc.t = 0; cc.k = b.size(); cc.A = a;
  for(Poly &u : b) {
    u.id = cnt++;
    cc.B.push_back(u);
    iter += u.n;
  }
  res.push_back(cc);
  return b;
}

Poly joint(Poly a, vector<Poly> b) {
  a.id = cnt++;
  query cc;
  cc.t = 1; cc.k = b.size(); cc.A = a;
  for(Poly u : b) {
    cc.B.push_back(u);
  }
  res.push_back(cc);
  iter += a.n;
  return a;
}

Poly trans(Poly a, Poly b) {
  b.id = cnt++;
  query cc;
  cc.t = 1; cc.k = 1; cc.A = b;
  cc.B.push_back(a);
  res.push_back(cc);
  iter += b.n;
  return b;
}

void out() {
  for(auto i : res) {
    if(!i.t) {
      printf("scissors\n");
      printf("%d %d\n", i.A.id, i.k);
      for(auto j : i.B) {
        printf("%d ", j.n);
        for(auto u : j.vs) printf("%.17g %.17g ", u.x, u.y);
        printf("\n");
      }
    } else {
      printf("tape\n");
      printf("%d ", i.k);
      for(auto j : i.B) printf("%d ", j.id);
      printf("\n");
      if(i.k == 1) {
        printf("%d ", i.A.n);
        for(auto j : i.A.vs) printf("%.17g %.17g ", j.x, j.y);
        printf("\n");
      } else {
        for(auto j : i.B) {
          printf("%d ", j.n);
          for(auto u : j.vs) printf("%.17g %.17g ", u.x, u.y);
          printf("\n");
        }
      }
      printf("%d ", i.A.n);
      for(auto j : i.A.vs) printf("%.17g %.17g ", j.x, j.y);
      printf("\n");
    }
  }
}

void rev() {
  reverse(res.begin(), res.end());
  for(auto &u : res) {
    u.A.id = cnt - 1 - u.A.id;
    for(auto &j : u.B) j.id = cnt - 1 - j.id;
    reverse(u.B.begin(), u.B.end());
    if(u.k == 1) swap(u.A, u.B[0]);
    else u.t = !u.t;
  }
}

Poly rect(Poly s) {
  assert(s.n == 3);
  int mx = 0;
  double d = dis(s.vs[1], s.vs[2]);
  range(i, 1, 3) {
    if(dis(s.vs[(i + 1) % 3], s.vs[(i + 2) % 3]) > d) {
      mx = i;
      d = dis(s.vs[(i + 1) % 3], s.vs[(i + 2) % 3]);
    }
  }
  P a = s.vs[mx], b = s.vs[(mx + 1) % 3], c = s.vs[(mx + 2) % 3];
  Poly u, v;
  u.vs = {b, c, (c + a) / 2, (a + b) / 2};
  u.n = 4;
  v.vs = {a, (a + b) / 2, (a + c) / 2};
  v.n = 3;
  vector<Poly> foo = {u, v};
  foo = split(s, foo);
  u = foo[0], v = foo[1];
  Poly to;
  to.vs = {b, (a + b) / 2, (a + b - c + b) / 2};
  to.n = 3;
  to = trans(v, to);
  P p = pr(b, L2((a + b) / 2, (a + b - c + b) / 2));
  Poly l, r;
  l.vs = {b, (a + b) / 2, p}; r.vs = {b, p, (a + b - c + b) / 2};
  l.n = 3, r.n = 3;
  vector<Poly> bar = {l, r};
  bar = split(to, bar);
  r = r + (c - b);
  r = trans(bar.back(), r);
  l = bar[0];
  Poly cc;
  cc.vs = {p, b, c, p + c - b};
  cc.n = 4;
  vector<Poly> sc = {u, l, r};
  cc = joint(cc, sc);
  Poly _cc;
  _cc.vs = {P(0, 0), P(dis(b, p), 0), P(dis(b, p), dis(b, c)), P(0, dis(b, c))};
  _cc.n = 4;
  _cc = trans(cc, _cc);
  return _cc;
}

Poly x_fold(Poly a) {
  Poly u, v, to;
  u.vs = {(a.vs[0] + a.vs[3]) / 2, (a.vs[1] + a.vs[2]) / 2, a.vs[2], a.vs[3]}; u.n = 4;
  v.vs = {a.vs[0], a.vs[1], (a.vs[1] + a.vs[2]) / 2, (a.vs[0] + a.vs[3]) / 2}; v.n = 4;
  vector<Poly> foo = {u, v};
  foo = split(a, foo);
  u = foo[0], v = foo[1];
  u = trans(u, u + (u.vs[1] - u.vs[3]));
  to.vs = {v.vs[0], u.vs[1], u.vs[2], v.vs[3]}; to.n = 4;
  foo.front() = u;
  return joint(to, foo);
}

Poly y_fold(Poly a) {
  Poly u, v, to;
  u.vs = {(a.vs[0] + a.vs[1]) / 2, a.vs[1], a.vs[2], (a.vs[2] + a.vs[3]) / 2}; u.n = 4;
  v.vs = {a.vs[0], (a.vs[0] + a.vs[1]) / 2, (a.vs[2] + a.vs[3]) / 2, a.vs[3]}; v.n = 4;
  vector<Poly> foo = {u, v};
  foo = split(a, foo);
  u = foo[0], v = foo[1];
  u = trans(u, u + (u.vs[3] - u.vs[1]));
  foo.front() = u;
  to.vs = {v.vs[0], v.vs[1], u.vs[2], u.vs[3]}; to.n = 4;
  return joint(to, foo);
}

const double ze = 1e-5;

Poly rectangle(Poly a, Poly b) {
  Poly u = a, v = b;
  double ux = dis(u.vs[0], u.vs[1]), uy = dis(u.vs[0], u.vs[3]);
  double vx = dis(v.vs[0], v.vs[1]), vy = dis(v.vs[0], v.vs[3]);
  vector<Poly> cons;
  while(vx > ze * 10) {
    while(ux > vx + (ze / 10)) {
      u = y_fold(u);
      ux /= 2;
      uy *= 2;
    }
    while(ux <= vx / 2 - (ze / 10)) {
      u = x_fold(u);
      ux *= 2;
      uy /= 2;
    }
    if(abs(ux - vx) + abs(uy - vy) < ze) break;
    Poly from, _u, to, _v;
    from.vs = {P(0, 0), P(ux, 0), P(ux, vy), P(0, vy)};
    to = from + v.vs[0];
    from = from + u.vs[0];
    from.n = 4; to.n = 4;
    _u.vs = {from.vs[3], from.vs[2], u.vs[2], u.vs[3]}; _u.n = 4;
    assert(u.vs[2].y > from.vs[2].y);
    _v.vs = {to.vs[1], v.vs[1], v.vs[2], to.vs[2]}; _v.n = 4;
    vector<Poly> l = {from, _u};
    l = split(u, l);
    if(res.size() == 126) {
      debug(u);
      debug(l);
    }
    from = l[0], _u = l[1];
    to = trans(from, to);
    cons.push_back(to);
    v = _v; u = _u;
    ux = dis(u.vs[0], u.vs[1]), uy = dis(u.vs[0], u.vs[3]);
    vx = dis(v.vs[0], v.vs[1]), vy = dis(v.vs[0], v.vs[3]);
  }
  v = trans(u, u + (v.vs[0] - u.vs[0]));
  cons.push_back(v);
  return joint(b, cons);
}

void solve(Poly bar) {
  vector<Poly> r = triangulation(bar);
  r = split(bar, r);
  for(auto &i : r) i = rect(i);
  double sum = S(bar);
  double a = sqrt(sum);
  Poly to;
  to.vs = {P(0, 0), P(a, 0), P(a, a), P(0, a)};
  vs = vs + P(-5e6, -5e6);
  to.n = 4;
  vector<Poly> cc;
  double l = 0;
  for(auto i : r) {
    double len = S(i) / a;
    Poly ss;
    ss.n = 4;
    ss.vs = {P(l, 0), P(l + len, 0), P(l + len, a), P(l, a)};
    ss = ss + P(-5e6, -5e6);
    cc.push_back(rectangle(i, ss));
    l += len;
  }
  joint(to, cc);
}

void debug_out(query a) {
  debug_out(a.t);
  cerr << endl;
  debug_out(a.A);
  cerr << endl;
  debug_out(a.k);
  cerr << endl;
  debug_out(a.B);
  cerr << endl;
  debug_out(make_pair(dis(a.A.vs[0], a.A.vs[3]), dis(a.A.vs[0], a.A.vs[1])));
  cerr << endl;
  debug_out(make_pair(dis(a.B[0].vs[0], a.B[0].vs[3]), dis(a.B[0].vs[0], a.B[0].vs[1])));
  cerr << endl;
  debug_out(S(a.A));
  cerr << endl;
  debug_out(S(a.B[0]));
}

int main() {
  cerr.precision(15);
  Poly a, b;
  a.read(); b.read();
  a.id = 0; b.id = 0;
  solve(a);
  out();
  return 0;
  int _cnt = cnt;
  cnt = 1;
  res.clear();
  solve(b);
  rev();
  for(auto &i : res) {
    i.A.id += _cnt - 1;
    for(auto &j : i.B) j.id += _cnt - 1;
  }
  out();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define range(i, m, n) for(int i = m; i < n; i++)
#define husk(i, m, n) for(int i = m; i > n; i--)

struct P {
  long long x, y;
  int id;
  P operator - (const P & b) const {
    return P{x - b.x, y - b.y};
  }

  void operator += (const P & b) {
    x += b.x, y += b.y;
  }

  long long operator * (const P & b) const {
    return x * b.y - y * b.x;
  }

  long long cross(const P & b, const P & c) const {
    return (b - *this) * (c - *this);
  }

   bool isRight() const {
    return x > 0 || (x == 0 && y > 0);
  }

  bool operator < (const P & b) const {
    if(isRight() != b.isRight())
      return isRight();
    return *this * b < 0;
  }

  bool operator == (const P & b) const {
    return make_pair(x, y) == make_pair(b.x, b.y);
  }
};

struct L2 {
  P one, two;
  P dir() const {
    return two - one;
  }
  //clockwise
  void arr() {
    if(one * two > 0) swap(one, two);
  }

  bool operator < (const L2 & b) const {
    return dir() < b.dir();
  }

  long double get_coeff(const L2 & b) const {
    long double r = (b.dir() * (one - b.one)) / (long double) (dir() * b.dir());
    return r;
  }

  bool isParallel(const L2 & b) const {
    return dir() * b.dir() == 0;
  }

   pair<long double, long double> intersect(const L2 & b) const {
     long double r = get_coeff(b);
     return make_pair(one.x + r * (two - one).x, one.y + r * (two - one).y);
   }
};

P pr(P a, L2 d) {
  P b = d.one - d.two;
  P c = a + P(-b.y, b.x);
  L2 e(a, c);
  return e.intersect(d);
}

double dis(P a, P b) {
  P c = a - b;
  return sqrt(c.x * c.x + c.y * c.y);
}

struct Poly {
  vector<P> vs;
  int n, id;

  Poly(){};

  Poly(vector<P> _vs, int _id = 0) : vs(_vs), id(_id) {
    n = vs.size();
  }

  void read() {
    cin >> n;
    for(int i = 0; i < n; i++) {
      int x, y;
      cin >> x >> y;
      vs.emplace_back(x, y);
    }
  }

  Poly shift(int t) {
    vector<P> _vs(n);
    for(int i = 0; i < n; i++) {
      _vs[i] = vs[(i + t) % n];
    }
    return Poly(_vs);
  }

  Poly operator + (P a) {
    Poly u = *this;
    for(auto &i : u.vs) i = i + a;
    u.n = u.vs.size();
    return u;
  }

};

double S(Poly a) {
  double res = 0;
  range(i, 0, a.n) {
    res += a.vs[i] * a.vs[(i + 1) % a.n];
  }
  return abs(res / 2);
}

bool cross(P a, P b, P c, P d) {
  L2 u, v;
  u.one = a, u.two = b;
  v.one = c, v.two = d;
  if(u.isParallel(v)) return false;
  auto foo = u.intersect(v);
  double x = foo.x, y = foo.y;
  return x <= min(max(a.x, b.x), max(c.x, d.x)) && x >= max(min(a.x, b.x), min(c.x, d.x)) && y <= min(max(a.y, b.y), max(c.y, d.y)) && y >= max(min(a.y, b.y), min(c.y, d.y));
};

const double inf = 1e7;

vector<Poly> triangulation(Poly u) {
  assert(u.n >= 3);
  vector<Poly> res;
  if(u.n == 3) {
    res.push_back(u);
    return res;
  }
  int a = -1, b = -1;
  range(i, 0, u.n) {
    range(j, i + 1, u.n) {
      if(i == (j + 1) % u.n || j == (i + 1) % u.n) continue;
      P to_inf = P(inf, inf * sqrt(2));
      P to = (u.vs[i] + u.vs[j]) / 2;
      bool bad = false;
      int cnt = 0;
      range(x, 0, u.n) {
        cnt ^= cross(to, to_inf, u.vs[x], u.vs[(x + 1) % u.n]);
        if(x == i || x == j || (x + 1) % u.n == i || (x + 1) % u.n == j) continue;
        bad |= cross(u.vs[i], u.vs[j], u.vs[x], u.vs[(x + 1) % u.n]);
      }
      if(!bad && cnt) {
        a = i;
        b = j;
        break;
      }
    }
    if(~a && ~b) break;
  }
  assert(~a && ~b);
  vector<P> l, r;
  for(int i = a; i <= b; i++) l.push_back(u.vs[i]);
  for(int i = b; i != (a + 1) % u.n; i = (i + 1) % u.n) r.push_back(u.vs[i]);
  vector<Poly> add = triangulation(Poly(r));
  res = triangulation(l);
  for(auto i : add) res.push_back(i);
  return res;
}

int cnt = 1;
int iter = 0;

struct query {
  int t;
  int k;
  vector<Poly> B;
  Poly A;
  query(){};
};

vector<query> res;
vector<Poly> cur;

vector<Poly> split(Poly a, vector<Poly> b) {
  query cc;
  cc.t = 0; cc.k = b.size(); cc.A = a;
  for(Poly &u : b) {
    u.id = cnt++;
    cc.B.push_back(u);
    iter += u.n;
    cur.push_back(u);
  }
  res.push_back(cc);
  return b;
}

Poly joint(Poly a, vector<Poly> b) {
  a.id = cnt++;
  cur.push_back(a);
  query cc;
  cc.t = 1; cc.k = b.size(); cc.A = a;
  for(Poly u : b) {
    cc.B.push_back(u);
  }
  res.push_back(cc);
  iter += a.n;
  return a;
}

Poly trans(Poly a, Poly b) {
  b.id = cnt++;
  cur.push_back(b);
  query cc;
  cc.t = 1; cc.k = 1; cc.A = b;
  cc.B.push_back(a);
  res.push_back(cc);
  iter += b.n;
  return b;
}

void out() {
  for(auto i : res) {
    if(!i.t) {
      printf("scissors\n");
      printf("%d %d\n", i.A.id, i.k);
      for(auto j : i.B) {
        printf("%d ", j.n);
        for(auto u : j.vs) printf("%.17g %.17g ", u.x, u.y);
        printf("\n");
      }
    } else {
      printf("tape\n");
      printf("%d ", i.k);
      for(auto j : i.B) printf("%d ", j.id);
      printf("\n");
      if(i.k == 1) {
        printf("%d ", i.A.n);
        for(auto j : i.A.vs) printf("%.17g %.17g ", j.x, j.y);
        printf("\n");
      } else {
        for(auto j : i.B) {
          printf("%d ", j.n);
          for(auto u : j.vs) printf("%.17g %.17g ", u.x, u.y);
          printf("\n");
        }
      }
      printf("%d ", i.A.n);
      for(auto j : i.A.vs) printf("%.17g %.17g ", j.x, j.y);
      printf("\n");
    }
  }
}

Poly rect(Poly s) {
  assert(s.n == 3);
  int mx = 0;
  double d = dis(s.vs[1], s.vs[2]);
  range(i, 1, 3) {
    if(dis(s.vs[(i + 1) % 3], s.vs[(i + 2) % 3]) > d) {
      mx = i;
      d = dis(s.vs[(i + 1) % 3], s.vs[(i + 2) % 3]);
    }
  }
  P a = s.vs[mx], b = s.vs[(mx + 1) % 3], c = s.vs[(mx + 2) % 3];
  Poly u, v;
  u.vs = {b, c, (c + a) / 2, (a + b) / 2};
  u.n = 4;
  v.vs = {a, (a + b) / 2, (a + c) / 2};
  v.n = 3;
  vector<Poly> foo = {u, v};
  foo = split(s, foo);
  u = foo[0], v = foo[1];
  Poly to;
  to.vs = {b, (a + b) / 2, (a + b - c + b) / 2};
  to.n = 3;
  to = trans(v, to);
  P p = pr(b, L2((a + b) / 2, (a + b - c + b) / 2));
  Poly l, r;
  l.vs = {b, (a + b) / 2, p}; r.vs = {b, p, (a + b - c + b) / 2};
  l.n = 3, r.n = 3;
  vector<Poly> bar = {l, r};
  bar = split(to, bar);
  r = r + (c - b);
  r = trans(bar.back(), r);
  l = bar[0];
  Poly cc;
  cc.vs = {p, b, c, p + c - b};
  cc.n = 4;
  vector<Poly> sc = {u, l, r};
  cc = joint(cc, sc);
  Poly _cc;
  _cc.vs = {P(0, 0), P(dis(b, p), 0), P(dis(b, p), dis(b, c)), P(0, dis(b, c))};
  _cc.n = 4;
  _cc = trans(cc, _cc);
  return _cc;
}

Poly back_to_triangle(Poly s, Poly _cc) {
  assert(s.n == 3);
  int mx = 0;
  double d = dis(s.vs[1], s.vs[2]);
  range(i, 1, 3) {
    if(dis(s.vs[(i + 1) % 3], s.vs[(i + 2) % 3]) > d) {
      mx = i;
      d = dis(s.vs[(i + 1) % 3], s.vs[(i + 2) % 3]);
    }
  }
  P a = s.vs[mx], b = s.vs[(mx + 1) % 3], c = s.vs[(mx + 2) % 3];
  Poly u, v;
  u.vs = {b, c, (c + a) / 2, (a + b) / 2};
  u.n = 4;
  v.vs = {a, (a + b) / 2, (a + c) / 2};
  v.n = 3;
  Poly to;
  to.vs = {b, (a + b) / 2, (a + b - c + b) / 2};
  to.n = 3;
  P p = pr(b, L2((a + b) / 2, (a + b - c + b) / 2));
  Poly l, r;
  l.vs = {b, (a + b) / 2, p}; r.vs = {b, p, (a + b - c + b) / 2};
  l.n = 3, r.n = 3;
  Poly cc;
  cc.vs = {p, b, c, p + c - b};
  cc.n = 4;
  cc = trans(_cc, cc);
  vector<Poly> sc = {u, l, r + (c - b)};
  sc = split(cc, sc);
  r = trans(sc.back(), r); l = sc[1]; u = sc[0];
  sc = {r, l}; to = joint(to, sc);
  v = trans(to, v);
  sc = {u, v};
  s = joint(s, sc);
  return s;
}

Poly x_fold(Poly a) {
  Poly u, v, to;
  u.vs = {(a.vs[0] + a.vs[3]) / 2, (a.vs[1] + a.vs[2]) / 2, a.vs[2], a.vs[3]}; u.n = 4;
  v.vs = {a.vs[0], a.vs[1], (a.vs[1] + a.vs[2]) / 2, (a.vs[0] + a.vs[3]) / 2}; v.n = 4;
  vector<Poly> foo = {u, v};
  foo = split(a, foo);
  u = foo[0], v = foo[1];
  u = trans(u, u + (u.vs[1] - u.vs[3]));
  to.vs = {v.vs[0], u.vs[1], u.vs[2], v.vs[3]}; to.n = 4;
  foo.front() = u;
  return joint(to, foo);
}

Poly y_fold(Poly a) {
  Poly u, v, to;
  u.vs = {(a.vs[0] + a.vs[1]) / 2, a.vs[1], a.vs[2], (a.vs[2] + a.vs[3]) / 2}; u.n = 4;
  v.vs = {a.vs[0], (a.vs[0] + a.vs[1]) / 2, (a.vs[2] + a.vs[3]) / 2, a.vs[3]}; v.n = 4;
  vector<Poly> foo = {u, v};
  foo = split(a, foo);
  u = foo[0], v = foo[1];
  u = trans(u, u + (u.vs[3] - u.vs[1]));
  foo.front() = u;
  to.vs = {v.vs[0], v.vs[1], u.vs[2], u.vs[3]}; to.n = 4;
  return joint(to, foo);
}

const double ze = 1e-5;

vector<double> near(Poly a) {
  return (vector<double>) {a.vs[0].x - a.vs[3].x, a.vs[1].y - a.vs[0].y, a.vs[2].x - a.vs[1].x, a.vs[3].y - a.vs[2].y};
}

Poly rectangle(Poly a, Poly b) {
  Poly u = a, v = b;
  double ux = dis(u.vs[0], u.vs[1]), uy = dis(u.vs[0], u.vs[3]);
  double vx = dis(v.vs[0], v.vs[1]), vy = dis(v.vs[0], v.vs[3]);
  vector<Poly> cons;
  while(vx > ze * 10) {
    while(ux > vx) {
      u = y_fold(u);
      ux /= 2;
      uy *= 2;
    }
    while(ux <= vx / 2) {
      u = x_fold(u);
      ux *= 2;
      uy /= 2;
    }
    if(abs(ux - vx) + abs(uy - vy) < ze) break;
    Poly from, _u, to, _v;
    from.vs = {P(0, 0), P(ux, 0), P(ux, vy), P(0, vy)};
    to = from + v.vs[0];
    from = from + u.vs[0];
    from.n = 4; to.n = 4;
    _u.vs = {from.vs[3], from.vs[2], u.vs[2], u.vs[3]}; _u.n = 4;
    assert(ux < vx && uy > vy);
    assert(u.vs[2].y > from.vs[2].y);
    _v.vs = {to.vs[1], v.vs[1], v.vs[2], to.vs[2]}; _v.n = 4;
    vector<Poly> l = {from, _u};
    l = split(u, l);
    assert(abs(S(from) + S(_u) - S(u)) < ze * 100);
    from = l[0], _u = l[1];
    to = trans(from, to);
    cons.push_back(to);
    if(_u.vs[0].y > 1e6) _u = trans(_u, _u + (P(0, 0) - u.vs[0]));
    v = _v; u = _u;
    ux = dis(u.vs[0], u.vs[1]), uy = dis(u.vs[0], u.vs[3]);
    vx = dis(v.vs[0], v.vs[1]), vy = dis(v.vs[0], v.vs[3]);
    u.vs = {P(0, 0), P(ux, 0), P(ux, uy), P(0, uy)}; u.n = 4;
    v.vs = {P(0, 0), P(vx, 0), P(vx, vy), P(0, vy)}; v.n = 4;
    u = u + _u.vs[0];
    v = v + _v.vs[0];
  }
  v = trans(u, u + (v.vs[0] - u.vs[0]));
  cons.push_back(v);
  return joint(b, cons);
}

void solve(Poly bar) {
  vector<Poly> r = triangulation(bar);
  r = split(bar, r);
  for(auto &i : r) i = rect(i);
  double sum = S(bar);
  double a = sqrt(sum);
  Poly to;
  to.vs = {P(0, 0), P(a, 0), P(a, a), P(0, a)};
  to.n = 4;
  vector<Poly> cc;
  double l = 0;
  for(auto i : r) {
    double len = S(i) / a;
    Poly ss;
    ss.n = 4;
    ss.vs = {P(l, 0), P(l + len, 0), P(l + len, a), P(l, a)};
    cc.push_back(rectangle(i, ss));
    l += len;
  }
  joint(to, cc);
}

void rev(Poly b, Poly sq) {
  vector<Poly> r = triangulation(b);
  int memo = cnt;
  auto foo = res;
  vector<Poly> ss;
  for(auto i : r) ss.push_back(rect(i));
  cnt = memo; swap(res, foo);
  double a = sqrt(S(sq));
  double l = 0;
  vector<Poly> sp;
  range(i, 0, (int) ss.size()) {
    double len = S(ss[i]) / a;
    vector<P> xs = {P(l, 0), P(l + len, 0), P(l + len, a), P(l, a)};
    sp.emplace_back(xs);
    l += len;
  }
  sp = split(sq, sp);
  range(i, 0, (int) sp.size()) {
    ss[i] = rectangle(sp[i], ss[i]);
    r[i] = back_to_triangle(r[i], ss[i]);
  }
  joint(b, r);
}

int main() {
  Poly a, b;
  a.read(); b.read();
  a.id = 0;
  solve(a);
  rev(b, res.back().A);
  out();
  return 0;
}


#include <iostream>
#include <algorithm>

const long long base=1000000007;

using namespace std;

int main(){
int n;
cin>>n;
long long r=0,b=0;
while (n--){
swap(r,b);
r=(r+b+1%base;
}
cout<<(r+b)% base;
return 0;
}


#include <iostream>
#include <algorithm>

using namespace std;

int main(){
int n;
cin>>n;
long long r=0,b=0,base=1000000007;
while (n--){
swap(r,b);
r=(r+b+1) mod base;
}
cout<<(r+b) mod base;
return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=int(a);i<=int(b);i++)
#define ll long long
#define pb push_back
const int mod=1000000007;

int main(){
	int n;
	cin>>n;
	ll dp[n+1];
	dp[1]=1,dp[2]=3;
	F(i,3,n) dp[i]=(d[i-1]+dp[i-2]+2)%mod;
	cout<<dp[n];
}


#include "stdafx.h"
#include <iostream>

int main()
{
	int n(0);
	std::cin >> n;

	static int redStart[1000005] = { 0 }, blueStart[1000005] = { 0 };
	redStart[1] = 1;
	blueStart[1] = 0;
	for (int i = 2; i <= n; i++)
	{
		if (i % 2 == 0)
		{
			redStart[i] = 1 + (i >= 3 ? blueStart[i - 2] : 0) +
				(i >= 4 ? redStart[i - 3] : 0);
			blueStart[i] = blueStart[i - 2] + redStart[i - 1] + 1;
		}
		else
		{
			redStart[i] = redStart[i - 2] + blueStart[i - 1] + 1;
			blueStart[i] = 1 + (i >= 3 ? redStart[i - 2] : 0) +
				(i >= 4 ? blueStart[i - 3] : 0);
		}
	}

	std::cout << redStart[n] + blueStart[n] << std::endl;
	return 0;
}


By krijgertje, contest: Codeforces Round #470 (rated, Div. 1, based on VK Cup 2018 Round 1), problem: (F) Public Service, Accepted, #
 #include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <list>
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); }

const int MAXN = 10000;

struct T {
	int n;
	vector<int> adj[MAXN];

	bool alive[MAXN]; int nalive;
	int deg[MAXN];
	int afst[MAXN], alst[MAXN], anxt[MAXN], aprv[MAXN]; // doubly-linked lists for leaves adjacent to a node
	int bfst, blst, bnxt[MAXN], bprv[MAXN]; // doubly-linked lists for nodes adjacent to at least one leaf
	priority_queue<pair<int, int> > pq;

	void init() {
		nalive = n; REP(i, n) alive[i] = true, deg[i] = SZ(adj[i]), afst[i] = alst[i] = -1; bfst = blst = -1;
		REP(at, n) if (deg[at] == 1) aappend(at, adj[at][0]);
		REP(at, n) if (afst[at] != -1) bappend(at);
		pq = priority_queue<pair<int, int> >(); REP(i, n) pq.push(MP(deg[i], i));
	}
	void killleaf(int at) {
		assert(deg[at] == 1); alive[at] = false; --nalive;
		int to = -1; REPSZ(i, adj[at]) if (alive[adj[at][i]]) { assert(to == -1); to = adj[at][i]; } assert(to != -1);
		--deg[at]; if (deg[at] == 0) { aremove(at, to); if (afst[to] == -1) bremove(to); }
		--deg[to]; pq.push(MP(deg[to], to)); if (deg[to] == 0) { aremove(to, at); if (afst[at] == -1) bremove(at); }
		if (deg[to] == 1) {
			int oth = -1; REPSZ(i, adj[to]) if (alive[adj[to][i]]) { assert(oth == -1); oth = adj[to][i]; } assert(oth != -1);
			aappend(to, oth);
			if (afst[oth] == to&&anxt[to] == -1) bappend(oth);
		}
	}
	void aappend(int at, int to) {
		aprv[at] = alst[to], anxt[at] = -1; if (aprv[at] == -1) afst[to] = at; else anxt[aprv[at]] = at; alst[to] = at;
	}
	void aremove(int at, int to) {
		if (aprv[at] == -1) afst[to] = anxt[at]; else anxt[aprv[at]] = anxt[at];
		if (anxt[at] == -1) alst[to] = aprv[at]; else aprv[anxt[at]] = aprv[at];
	}
	void bappend(int at) {
		bprv[at] = blst, bnxt[at] = -1; if (bprv[at] == -1) bfst = at; else bnxt[bprv[at]] = at; blst = at;
	}
	void bremove(int at) {
		if (bprv[at] == -1) bfst = bnxt[at]; else bnxt[bprv[at]] = bnxt[at];
		if (bnxt[at] == -1) blst = bprv[at]; else bprv[bnxt[at]] = bprv[at];
	}
	bool getleavesatleastthreeapart(pair<int,int> &u, pair<int,int> &v) {
		if (bfst == -1 || bnxt[bfst] == -1) return false;
		int x = bfst, y = bnxt[bfst], r = maxdeg().second; if (afst[r] != -1 && x != r) y = r;
		u = MP(afst[x], x), v = MP(afst[y], y); assert(u.first != -1 && v.first != -1); return true;
	}
	pair<int, int> maxdeg() { while (!pq.empty() && (!alive[pq.top().second] || deg[pq.top().second] != pq.top().first)) pq.pop(); return !pq.empty() ? pq.top() : MP(0, -1); }
	bool isstar() { return maxdeg().first == nalive - 1; }
	bool issemistar() { return maxdeg().first == nalive - 2; }
	bool ispath() { return maxdeg().first <= 2; }
	bool getsemistar1(vector<int> &rem) {
		if (!issemistar()) return false; assert(bfst != -1 && bnxt[bfst] != -1 && bnxt[bnxt[bfst]] == -1);
		int w = maxdeg().second; assert(bfst == w || bnxt[bfst] == w); int v = bfst + bnxt[bfst] - w; assert(afst[v] != -1 && anxt[afst[v]] == -1); int u = afst[v];
		rem.clear(); rem.PB(u); rem.PB(v); rem.PB(w); REP(i, n) if (alive[i] && i != u&&i != v&&i != w) rem.PB(i); return true;
	}
	bool getsemistar2(vector<int> &rem) {
		if (isstar()) return false; assert(bfst != -1 && bnxt[bfst] != -1); int u = bfst, w = afst[u], v = afst[bnxt[bfst]]; assert(w != -1 && u != -1);
		rem.clear(); rem.PB(u); rem.PB(v); rem.PB(w); REP(i, n) if (alive[i] && i != u&&i != v&&i != w) rem.PB(i); return true;
	}
	bool getpath1(vector<int> &rem) {
		if (!ispath()) return false;
		int at = -1; REP(i, n) if (alive[i] && deg[i] <= 1) { at = i; break; } assert(at != -1);
		rem.PB(at); while (true) { int to = -1; REPSZ(i, adj[at]) if (alive[adj[at][i]] && (SZ(rem) == 1 || adj[at][i] != rem[SZ(rem) - 2])) { assert(to == -1); to = adj[at][i]; } if (to == -1) break; at = to; rem.PB(at); } return SZ(rem) == 5;
	}
	bool getpath2(vector<int> &rem) {
		if (!getpath1(rem)) return false;
		swap(rem[0], rem[2]); swap(rem[0], rem[4]); swap(rem[0], rem[3]); swap(rem[0], rem[1]); return true;
	}
};

int n;
T a, b;
int mp[MAXN];
struct Op { pair<int, int> au, av, bu, bv; };
vector<Op> ops;

void run() {
	scanf("%d", &n);
	a.n = n; REP(i, n - 1) { int u, v; scanf("%d%d", &u, &v); --u, --v; a.adj[u].PB(v); a.adj[v].PB(u); } a.init();
	b.n = n; REP(i, n - 1) { int u, v; scanf("%d%d", &u, &v); --u, --v; u -= n; v -= n; b.adj[u].PB(v); b.adj[v].PB(u); } b.init();

	if (a.isstar() || b.isstar()) { printf("No\n"); return; }
	REP(i, n) mp[i] = -1; ops.clear();
	while (true) {
		//printf("maxdeg: (%d,%d) (%d,%d)\n", a.maxdeg().first, a.maxdeg().second + 1, b.maxdeg().first, b.maxdeg().second + 1 + n);
		if (a.issemistar()) {
			//printf("a semistar\n");
			vector<int> arem; assert(a.getsemistar1(arem));
			vector<int> brem; assert(b.getsemistar2(brem));
			assert(a.nalive == b.nalive&&SZ(arem) == a.nalive&&SZ(brem) == b.nalive);
			REPSZ(i, arem) mp[arem[i]] = brem[i];
			break;
		}
		if (b.issemistar()) {
			//printf("b semistar\n");
			vector<int> arem; assert(a.getsemistar2(arem));
			vector<int> brem; assert(b.getsemistar1(brem));
			assert(a.nalive == b.nalive&&SZ(arem) == a.nalive&&SZ(brem) == b.nalive);
			REPSZ(i, arem) mp[arem[i]] = brem[i];
			break;
		}
		if (a.nalive == 5 || b.nalive == 5) {
			assert(a.nalive == 5 && b.nalive == 5 && a.ispath() && b.ispath());
			//printf("5 path\n");
			vector<int> arem; assert(a.getpath1(arem));
			vector<int> brem; assert(b.getpath2(brem));
			assert(a.nalive == b.nalive&&SZ(arem) == a.nalive&&SZ(brem) == b.nalive);
			REPSZ(i, arem) mp[arem[i]] = brem[i];
			break;
		}
		assert(a.nalive >= 6 && b.nalive >= 6);
		//printf("general case: ");
		pair<int,int> au, av; assert(a.getleavesatleastthreeapart(au, av));
		pair<int,int> bu, bv; assert(b.getleavesatleastthreeapart(bu, bv));
		//printf("(%d,%d) and (%d,%d)\n", au.first + 1, av.first + 1, bu.first + n + 1, bv.first + n + 1);
		a.killleaf(au.first); a.killleaf(av.first);
		b.killleaf(bu.first); b.killleaf(bv.first);
		Op op; op.au = au, op.av = av, op.bu = bu, op.bv = bv; ops.PB(op);
	}
	for (int i = SZ(ops) - 1; i >= 0; --i) {
		pair<int, int> au = ops[i].au, av = ops[i].av, bu = ops[i].bu, bv = ops[i].bv;
		if (mp[au.second] != bu.second&&mp[av.second] != bv.second) { mp[au.first] = bu.first; mp[av.first] = bv.first; continue; }
		if (mp[au.second] != bv.second&&mp[av.second] != bu.second) { mp[au.first] = bv.first; mp[av.first] = bu.first; continue; }
		assert(false);
	}
	printf("Yes\n");
	REP(i, n) { if (i != 0) printf(" "); printf("%d", mp[i] == -1 ? -1 : mp[i] + n + 1); } puts("");
}

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


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

#include <vector>
#include <set>
#include <map>
#include <queue>
#include <ctime>
#include <cassert>
#include <bitset>
typedef long long ll ;
#define fi first
#define se second
#define mp make_pair
#define rep(i, a, b) for (int i = a; i < b; ++ i)
const int N = 1e5 + 5, M = 1e5 ;
using namespace std ;
typedef pair<int,pair<ll,int> > state;

ll myrand() {
	return ((ll)(rand()&65535)<<32)+((ll)rand()<<16)+rand();
}
state st1[N],st2[N];
int vis[N],dis[N],off,pre[N],n,deg[N],deg2[N],u,v,ret[N];
vector<int> e[N],e2[N];
bitset<10100> adj[10100];
set<state> hs;
pair<int,int> E[N];

void del(int u) {
	off+=1;
	dis[u]=1;
	hs.erase(st1[u]);
	for (auto v:e[u]) if (!dis[v]) {
		hs.erase(st1[v]);
		st1[v].fi++;
		hs.insert(st1[v]);
	}
}

bool gao0() {
	rep(i,1,n+1) pre[i]=i;
	random_shuffle(pre+1,pre+n+1);
	rep(i,1,n) if (adj[pre[E[i].fi]][pre[E[i].se]]) return 0;
	rep(i,1,n+1) ret[pre[i]]=i;
	puts("Yes");
	rep(i,1,n+1) printf("%d ",ret[i]+n);
	puts("");
	return 1;
}
bool gao() {
	hs.clear(); off=0;
	rep(i,1,n+1) {
		st1[i]=mp(deg[i],mp(myrand(),i));
		st2[i]=mp(deg2[i],mp(myrand(),i));
		hs.insert(st1[i]);
		vis[i]=0; dis[i]=0;
	}

	rep(i,1,n+1) pre[i]=0;

	state val=st2[1];
	rep(i,2,n+1) val=min(val,st2[i]);

	priority_queue<state, vector<state>, greater<state> > q;

	q.push(val);
	pre[val.se.se]=hs.begin()->se.se;
	vis[val.se.se]=1;

	del(hs.begin()->se.se);
	while (!q.empty()) {
		state st=q.top(); q.pop();
		int u=st.se.se;
		int w=pre[u];
		for (auto v:e2[u]) if (!vis[v]) {
			st2[v].fi--; vis[v]=1;
			vector<state> tmp;
			while (1) {
				auto it=hs.lower_bound(mp(st2[v].fi+off,mp(-1,-1)));
				if (it==hs.end()) return 0;
				if (adj[w][it->se.se]) {
					tmp.push_back(*it);
					hs.erase(it);
				} else {
					pre[v]=it->se.se;
					for (auto p:tmp) hs.insert(p);
					del(it->se.se);
					q.push(st2[v]);
					break;
				}
			}
		}

	}
	rep(i,1,n+1) ret[pre[i]]=i;
	puts("Yes");
	rep(i,1,n+1) printf("%d ",ret[i]+n);
	puts("");
	return 1;
}

int main() {
	scanf("%d",&n);
	rep(i,1,n+1) deg[i]=n-1;
	rep(i,1,n) {
		scanf("%d%d",&u,&v);
		e[u].push_back(v),e[v].push_back(u);
		adj[u][v]=adj[v][u]=1;
		deg[u]--; deg[v]--;
	}
	rep(i,1,n) {
		scanf("%d%d",&u,&v); u-=n; v-=n;
		e2[u].push_back(v); e2[v].push_back(u);
		E[i]=make_pair(u,v);
		deg2[u]++; deg2[v]++;
	}
	rep(i,1,n+1) if (deg[i]==0||deg2[i]==n-1) {
		puts("No");
		return 0;
	}
	while (1) {
		if (gao()) return 0;
		if (gao0()) return 0;
	}
	puts("No");


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
priority_queue<ll,vector<ll>,greater<ll> >que;
int n;
vector<P>edge; vector<int>G[10005],G2[10005];
bool used[100050000];
int cnt[10005],cnt2[10005];
void brute(){
	vector<int>vec;
	for(int i=0;i<n;i++) vec.pb(i);
	do{
		rep(i,edge.size()){
			int x = edge[i].fi,y = edge[i].sc;
			if(used[vec[x]*n+vec[y]]) goto nxt;
		}
		puts("Yes");
		rep(i,vec.size()) printf("%d ",vec[i]+n+1);
		puts(""); return; nxt:;
	}while(next_permutation(vec.begin(),vec.end()));
	puts("No");
}
double beg;
bool used[10005]={};
void omikuji(){
	vector<int>vec;
	for(int i=0;i<n;i++) vec.pb(i);
	P p = mp(-1,-1);
	for(int i=0;i<n;i++) p = max(p,mp(cnt[i],i));
	if(p.fi == n-1){
		puts("No"); return;
	}
	vector<int>nt;
	for(int i=0;i<G[p.sc].size();i++){
		used[G[p.sc][i]] = 1;
	}
	for(int i=0;i<n;i++) if(!used[i] && i != p.sc) nt.pb(i);
	vector<int>leaf;
	for(int i=0;i<n;i++) if(cnt2[i] == 1) leaf.pb(i);
	srand((unsigned)time(NULL));
	assert(leaf.size() && nt.size());
	while(clock()-beg <= 3.9*CLOCKS_PER_SEC){
		int L = abs(rand());
		int x = leaf[L%leaf.size()];
		L = abs(rand());
		int y = nt[L%nt.size()];
		//vec[p,sc] = x
		//vec[y] = G2[x][0]
		random_shuffle(vec.begin(),vec.end());
		if(vec[p.sc] != x){
			for(int i=0;i<n;i++){
				if(vec[i] == x){
					swap(vec[i],vec[p.sc]);
					break;
				}
			}
		}
		if(vec[y] != G2[x][0]){
			for(int i=0;i<n;i++){
				if(vec[i] == G2[x][0]){
					swap(vec[i],vec[y]);
					break;
				}
			}
		}
		assert(vec[p.sc] == x && vec[y] == G2[x][0]);
		rep(i,edge.size()){
			int x = edge[i].fi,y = edge[i].sc;
			if(used[vec[x]*n+vec[y]]) goto nxt2;
		}
		puts("Yes");
		rep(i,vec.size()) printf("%d ",vec[i]+n+1);
		puts(""); return; nxt2:;
	}
	puts("No");
}
int main(){
	beg = clock();
	cin>>n;
	rep(i,n-1){
		int a,b;
		cin>>a>>b; a--; b--;
		edge.pb(mp(a,b)); cnt[a]++; cnt[b]++;
		G[a].pb(b);
		G[b].pb(a);
	}
	rep(i,n-1){
		int a,b;
		cin>>a>>b;
		a-=n+1; b-=n+1;
		used[a*n+b] = used[b*n+a] = 1; cnt2[a]++; cnt2[b]++;
		G2[a].pb(b);
		G2[b].pb(a);
	}
	if(n<=10){
		brute(); return 0;
	}
	else{
		omikuji(); return 0;
	}
}


# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) ((x)&1)
#define sqr(x) ((x)*(x))
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define mem(a,x) memset(a,x,sizeof(a))
#define rep(i,a,b) for (int i=(a); i<=(b); ++i)
#define per(i,a,b) for (int i=(a); i>=(b); --i)
#define rep_it(it,x) for (__typeof((x).begin()) it=(x).begin(); it!=(x).end(); it++)
#define ____ puts("\n_______________\n\n")
#define debug(x) ____; cout<< #x << " => " << (x) << endl
#define debug_pair(x) cout<<"\n{ "<<(x).fir<<" , "<<(x).sec<<" }\n"
#define debug_arr(x,n) ____; cout<<#x<<":\n"; rep(i,0,n) cout<<#x<<"["<<(i)<<"] => "<<x[i]<<endl
#define debug_arr2(x,n,m) ____; cout<<#x<<":\n"; rep(i,0,n) rep(j,0,m) cout<<#x<<"["<<(i)<<"]["<<(j)<<"]= "<<x[i][j]<<((j==m)?"\n\n":"    ")
#define debug_set(x) ____; cout<<#x<<": \n"; rep_it(it,x) cout<<(*it)<<" "; cout<<endl
#define debug_map(x) ____; cout<<#x<<": \n"; rep_it(it,x) debug_pair(*it)
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const ll ooo=9223372036854775807ll;
const int _cnt = 1000 * 1000 + 7;
const int _p = 1000 * 1000 * 1000 + 7;
const int N=10005;
const double PI=acos(-1.0);
const double eps=1e-9;
int o(int x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }

void file_put() {
    freopen("filename.in", "r", stdin);
    freopen("filename.out", "w", stdout);
}

int d1[N],d2[N],ans[N],n,x,y,u,v,w,num; bool vis1[N],vis2[N];
vector <int> V1[N],V2[N]; bitset <N> a[N];
struct Btype{ int x,y; } E[N];
struct Stype{ int d,id; ll r; } s1[N],s2[N]; set <Stype> S;
ll myrand() { return ((ll)(rand()&65535)<<32)+((ll)rand()<<16)+rand(); }
inline bool operator < (const Stype p,const Stype q) {
	return p.d<q.d || p.d==q.d && p.r<q.r || p.d==q.d && p.r==q.r && p.id<q.id;
}
inline bool operator > (const Stype p,const Stype q) {
	return p.d>q.d || p.d==q.d && p.r>q.r || p.d==q.d && p.r==q.r && p.id>q.id;
}

void print() { printf("Yes\n"); rep(i,1,n) printf("%d ",ans[i]+n); printf("\n");  }
void D(int x) {
	vis1[x]=1,num++; S.erase(s1[x]);
	for (auto y: V1[x]) if (!vis1[y]) S.erase(s1[y]),s1[y].d++,S.insert(s1[y]);
}

bool _work() {
	rep(i,1,n) ans[i]=i; random_shuffle(ans+1,ans+n+1);
	rep(i,1,n-1) if (a[ans[E[i].x]][ans[E[i].y]]) return 0;
	print(); return 1;
}

bool work() {
	mem(vis1,0),mem(vis2,0),mem(ans,0),num=0; S.clear();
	rep(i,1,n) S.insert(s1[i]=Stype{d1[i],i,myrand()}),s2[i]=Stype{d2[i],i,myrand()};
	priority_queue <Stype, vector<Stype>, greater<Stype> > Q;
	Stype s=s2[1]; rep(i,2,n) s=min(s,s2[i]);
	Q.push(s),ans[s.id]=S.begin()->id,vis2[s.id]=1,D(S.begin()->id);
	while (!Q.empty()) {
		Stype s=Q.top(); Q.pop(); u=ans[x=s.id];
		for (auto y: V2[x]) if (!vis2[y]) {
			s2[y].d--; auto it=S.lower_bound(Stype{s2[y].d+num,-1,-1});
			for (; it!=S.end(); it++) if (!a[u][v=it->id]) { ans[y]=v; break; }
			if (!ans[y]) return 0; D(v),vis2[y]=1,Q.push(s2[y]);
		}
	}
	print(); return 1;
}

int main() {
    //file_put();

    scanf("%d",&n);
	rep(i,1,n-1) {
		scanf("%d%d",&x,&y),d2[x]++,d2[y]++;
		V2[x].pb(y),V2[y].pb(x); E[i]=Btype{x,y};
	}
	rep(i,1,n-1) {
		scanf("%d%d",&x,&y),x-=n,y-=n,d1[x]--,d1[y]--;
		V1[x].pb(y),V1[y].pb(x); a[x][y]=a[y][x]=1;
	}
	rep(i,1,n) d1[i]+=n-1;
	rep(i,1,n) if (!d1[i] || d2[i]==n-1) return 0*printf("No\n");
	for (; !work() /*&& !_work()*/; ) ;

    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define f first
#define s second
#define pb push_back
#define INF 1000000000

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;

typedef tree<
ll,
null_type,
greater<ll>,
rb_tree_tag,
tree_order_statistics_node_update> ordered_set;

int main()
{
    ll n;
    cin >> n;
    ll a[n];
    for (ll i = 0; i < n; i++) cin >> a[i];
    for (ll i = 0; i < n - 2; i++)
        if ((a[i] ^ a[i + 1]) > a[i + 2] || (a[i + 1] ^ a[i + 2]) < a[i])
    {
        cout << 1;
        return 0;
    }
    assert(n < 100);
    ll ans = 1e9;
    for (int i = 0; i < n; i++)
    {
      ll x = 0;
      for (int j = i; j < n; j++)
      {
          x ^= a[j];
          ll x1 = 0;
          for (int c = j + 1; c < n; c++)
          {
              x1 ^= a[c];
              if (x > x1) ans = min(ans, (j - i) + (c - (j + 1)));
          }
      }
    }
    ans == 1e9?cout << -1 : cout << ans;
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <deque>
#include <queue>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <fstream>
typedef long long ll;
using namespace std;
#define PI 3.141592653589
#define MOD 1000000007

void Solve()
{
	int n;
	cin >> n;
	vector<int> vec(n);
	for (auto& el : vec)
		cin >> el;
	int ans = INT_MAX;
	for (int i = 0; i < n - 1; ++i)
	{
		int t = vec[i];
		for (int j = 1; i + j < n && pow(2, j) <= long long(vec[i]) << 1ll; ++j)
		{
			t ^= vec[i + j];
			if (i > 0 && vec[i - 1] > t || i + j + 1 < n && vec[i + j + 1] < t)
			{
				ans = min(ans, j);
				break;
			}
		}
	}
	if (ans == INT_MAX)
		cout << -1 << endl;
	else
		cout << ans << endl;
}

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


#include <bits/stdc++.h>

using namespace std;

#define int long long
#define vi vector<int>
#define vp vector<pair<int,int>>

void ans() {
    int n;
    cin >> n;
    if (n > 100) {
        cout << 1 << "\n";
    }
    int a[n];
    for (int i = 0; i < n; i++)
        cin >> a[i];
    int ans = 1e9;
    for (int i = 0; i < n; i++) {
        int f = 0;
        for (int l = i; l >= 0; l--) {
            f ^= a[l];
            int s = 0;
            for (int k = i + 1; k < n; k++) {
                s ^= a[k];
                if (f > s) {
                    ans = min(ans, i - l + k - i - 1);
                }
            }
        }
    }
    if (ans == int(1e9)) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }
}

signed main() {
    ans();
    return 0;
}


#include <bits/stdc++.h>
#include <string>
#include <cmath>
#include <sstream>
#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 pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
typedef long long int ll;
using namespace std;
ll mod1=1000000007;
ll mod2=67280421310721;
ll mod3=998244353;
ll INF=1e18;

ll binpow1(ll a,ll b){
    ll res=1;
    while (b>0){
        if (b&1)
        res=res*a;
        a=a*a;
        b>>=1;
    }
    return res;
}

ll binpow2(ll a,ll b,ll m){
    a%=m;
    ll res=1;
    while (b>0){
        if (b & 1)
        res=res*a%m;
        a=a*a%m;
        b>>=1;
    }
    return res;
}

ll gcd(ll a,ll b){
    if (b==0)
        return a;
    else
        return gcd(b,a%b);
}

map<ll,ll> fact(ll n) {
    map<ll,ll> factorization;ll c=0;
    while (n % 2 == 0) {
        c++;
        n /= 2;
    }
    if(c>0)
    {
        factorization.insert({2,c});
    }c=0;
    for (ll d = 3; d * d <= n; d += 2) {
        while (n % d == 0) {
            c++;
            n /= d;
        }
        if(c>0)
    {
        factorization.insert({d,c});
    }c=0;
    }
    if (n > 1)
       {
           factorization.insert({n,1});
       }
    return factorization;
}

int main()
{ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
    ll n;
    cin>>n;
    ll a[n];ll b[n];ll f=0;
    FOR(i,0,n)
    {
        cin>>a[i];
        b[i]=floor(log2(a[i]));
    }
    FOR(i,1,n-1)
    {
        if(b[i-1]==b[i] && b[i]==b[i+1])
        {
            f=1;break;
        }
    }
    if(f)
    {
        cout<<1<<'\n';
        return 0;
    }
    ll ans=INF;ll p=0;ll q=0;
    FOR(i,0,n)
    {
        p=p^a[i];
        FOR(j,i+1,n)
        {
            q=q^a[i];
            if(p>q)
            {
                ans=min(ans,j-i-1);
            }
        }
        q=0;
    }
    if(ans==INF)
    {
        ans=-1;
    }
    cout<,ans<<'\n';

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 1510;
vector<int> G[N];
struct node{
	int x,y,id;
};
bool vis[N];
int son[N];
int ans[N];
node C{-1e9-100,-1e9-100};
//极角排序
vector<node> pt;
bool cmp(node& a,node& b)
{
	node A{a.x-C.x,a.y-C.y};
	node B{b.x-C.x,b.y-C.y};
	return 1ll*A.x*B.y - 1LL*A.y-B.x < 0;
}
//

void dfs(int x,vector<node > pt){
	int mx = 0;
	vis[x] = true;
	for(int i= 0;i < pt.size();i ++){
		if(pt[i].x < pt[mx].x )mx = i;
	}
	ans[pt[mx].id]  = x;
	pt.erase(pt.begin() + mx);
	int bef = 0;
	for(int i= 0;i < G[x].size();i ++){
		int v = G[x][i];
		if(vis[v]) continue;
		vector<node > npt;
		npt.clear();
		for(int j = bef;j < bef+son[v];j ++){
			npt.push_back(pt[j]);
		}
		bef += son[v];

		dfs(v,npt);
	}
}
int ddfs(int x){
	vis[x] = true;
	int cnt = 1;
	for(int i = 0;i < G[x].size();i ++){
		int v= G[x][i];
		if(vis[v]) continue;
		cnt += ddfs(v);
	}
	return son[x] = cnt;
}
int main(){
	int n;
	cin >>n;
	for(int i= 1;i < n;i ++){
		int a,b;
		scanf("%d %d",&a,&b);
		G[a].push_back(b);
		G[b].push_back(a);
	}
	for(int i= 1;i <= n;i ++){
		int a,b;
		scanf("%d %d",&a,&b);
		pt.push_back((node){a,b});
		pt[i-1].id = i;
	}
	sort(pt.begin(),pt.end(),cmp);
	memset(vis,false,sizeof(vis));
	ddfs(1);
	memset(vis,false,sizeof(vis));
	dfs(1,pt);
	for(int i = 1;i <= n;i ++){
		printf("%d%c",ans[i],i==n?'\n':' ');
	}

	return 0;
}
/*
10
4 3
7 6
5 7
9 5
7 4
7 8
2 5
1 7
5 10

-10 -2
-5 -7
-9 9
8 -8
0 6
-10 -7
-2 0
7 10
8 9
6 1
*/


#define _USE_MATH_DEFINES
#include <iostream>
#include <stdio.h>
#include <sstream>
#include <string>
#include <string.h>
#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 s, int r, int root, vector<PIII> ps, vector<bool> c)
{
	int min_y = INT_MAX, min_i = -1;
	for(int i = s;i <= r;++i) if(!c[i] && ps[i].F.S < min_y) {min_y = ps[i].F.S; min_i = i;}
	c[min_i] = true;
	res.push_back(MP(ps[min_i].S,root));
	for(int i = 1;i <= n;++i) if(adj[root][i]) {
		vector<PIII> nps(1);
		vector<bool> nchk;
		while(nps.size() < vtx[i]+1) {
			if(!c[s]) nps.push_back(ps[s]);
			++s;
		}
		adj[i][root] = false;
		nchk.resize(nps.size(),false);
		go(1,nps.size()-1,i,nps,nchk);
	}
}

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,n,1,points,chk);

	st(res);

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

	return 0;
}


#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long int ll ;
const int maxn=1501 ;
struct point
{
	int x,y,name ;
	point *dad ;
	bool operator <(const point &w) const
	{
		return (ll)(x-dad->x)*(w.y-dad->y)-(ll)(y-dad->y)*(w.x-dad->x)<0 ;
	}
}poses[maxn] ;
struct node
{
	int ans,subtree ;
	vector<int> neighbor ;
	node()
	{
		subtree=1 ;
	}
	int &operator[](int a)
	{
		return neighbor[a] ;
	}
	int size()
	{
		return neighbor.size() ;
	}
	void push(int v)
	{
		neighbor.push_back(v) ;
	}
}graph[maxn] ;
bool cmp(const point &a,const point &b)
{
	if(a.x!=b.x)
		return a.x<b.x ;
	return a.y<b.y ;
}
int dfs(int v,int dad)
{
	for(int i=0;i<graph[v].size();i++)
		if(graph[v][i]!=dad)
			graph[v].subtree+=dfs(graph[v][i],v) ;
	return graph[v].subtree ;
}
void solve(int v,int dad,int l,int r)
{
	graph[v].ans=poses[l].name ;
	for(int i=l+1;i<r;i++)
		poses[i].dad=&poses[l] ;
	sort(poses+l+1,poses+r) ;
	int t=l+1 ;
	for(int i=0;i<graph[v].size();i++)
		if(graph[v][i]!=dad)
		{
			solve(graph[v][i],v,t,t+graph[graph[v][i]].subtree) ;
			t+=graph[graph[v][i]].subtree ;
		}
}
int anses[maxn] ;
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{`
		int u,v ;
		scanf("%d %d",&u,&v) ;
		graph[v].push(u) ;
		graph[u].push(v) ;
	}
	for(int i=0;i<n;i++)
	{
		scanf("%d %d",&poses[i].x,&poses[i].y) ;
		poses[i].name=i+1 ;
	}
	sort(poses,poses+n,cmp) ;
	dfs(1,-1) ;
	solve(1,-1,0,n) ;
	for(int i=1;i<n+1;i++)
		anses[graph[i].ans]=i ;
	for(int i=1;i<n+1;i++)
		printf("%d ",anses[i]) ;
}


#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

struct Point {
	int num;
	int x;
	int y;
	double cosV;

	void CosV(double dx, double dy) {
		this->cosV = dx/(sqrt(dx*dx + dy*dy));
	}
};

bool cmp(const Point &a, const Point &b) {
	return a.cosV < b.cosV;
};

int n;
vector<vector<int> > g;
vector<int> ans;
vector<bool> usedV;

void DFS(int p, int v, int &cnt) {
	++cnt;
	for (int i = 0; i < (int)g[v].size(); ++i) {
		if (g[v][i] != p) {
			DFS(v, g[v][i], cnt);
		}
	}
}

void Sort(vector<Point> &points, int pStart) {
	//usedP[points[pStart].num] = true;
	Point &p0 = points[pStart];
	for (int i = 0; i < (int)points.size(); ++i) {
		Point &pi = points[i];
		if (i != pStart) {
		//if (!usedP[pi.num]) {
			pi.CosV(double(pi.x - p0.x), double(pi.y - p0.y));

		//}
		}
		//printf("%f ", pi.cosV);
	}
	//cout << endl;
	sort(points.begin(), points.end(), cmp);
}

void Rec(int v, vector<Point> &points) {
	usedV[v] = true;
	int pStart = 0;
	for (int i = 1; i < (int)points.size(); ++i) {
		Point &p = points[i];
		if ((p.y < points[pStart].y) || (p.y == points[pStart].y && p.x < points[pStart].x)) {
			pStart = i;
		}
	}
	//cout << (int)points.size() << " ";
	//cout << pStart << " ";
	int pStartNum = points[pStart].num;
//	cout << pStartNum << endl;
	//cout << pStart << endl;
	//cout << points[pStart].num << endl;
	ans[points[pStart].num] = v;

	//cout << ans[points[pStart].num] << endl;
	Sort(points, pStart);

	vector<Point> points1;
	int pos = 0;
	for (int i = 0; i < (int)g[v].size(); ++i) {
		if (!usedV[g[v][i]]) {
			int cnt = 0;
			DFS(v, g[v][i], cnt);

			//cout << cnt << endl;
			int j = 1;
			points1.clear();
			while (j <= cnt) {
				if (points[pos].num != pStartNum) {
					//cout << "LOL" << endl;
					points1.push_back(points[pos]);
					++j;
				}
				++pos;
			}
			//cout << (int)points1.size() << endl;
			Rec(g[v][i], points1);
		}
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	scanf("%d", &n);
	g.resize(n + 1);
	ans.resize(n + 1);
	usedV.resize(n + 1, false);
	for (int i = 1; i <= n - 1; ++i) {
		int x;
		int y;
		scanf("%d %d", &x, &y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	vector<Point> points(n);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &points[i].x, &points[i].y);
		points[i].num = i + 1;
		points[i].cosV = -2;
		//cout << points[i].num << endl;
	}
	//cout << endl;

	Rec(1, points);

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

	return 0;
}