#include <bits/stdc++.h>

using namespace std;

struct node
{
	int val, prio, size, rev;
	node *l, *r;
};

inline int size(node *u) { return u ? u->size : 0; }

node* update(node *u)
{
	if (u) u->size = 1 + size(u->l) + size(u->r);
	return u;
}

void push(node *u)
{
	if (u && u->rev)
	{
		swap(u->l, u->r);
		if (u->l) u->l->rev ^= 1;
		if (u->r) u->r->rev ^= 1;
		u->rev = 0;
	}
}

node* merge(node *u, node *v)
{
	push(u); push(v);
	if (!u || !v) return u ? u : v;
	if (u->prio > v->prio)
	{
		u->r = merge(u->r, v);
		update(u);
		return u;
	}
	else
	{
		v->l = merge(u, v->l);
		update(v);
		return v;
	}
}

pair<node*, node*> split(node *u, int k)
{
	if (!u) return make_pair(u, u);
	push(u);
	if (size(u->l) >= k)
	{
		pair<node*, node*> ans = split(u->l, k);
		u->l = ans.second;
		update(u);
		ans.second = u;
		return ans;
	}
	else
	{
		pair<node*, node*> ans = split(u->r, k - size(u->l) - 1);
		u->r = ans.first;
		update(u);
		ans.first = u;
		return ans;
	}
}

vector<int> ans;

void p(node* t)
{
          if(!t) return;
          push(t);
          p(t->l);
          ans.push_back(t->val);
          p(t->r);
}

int n,m,l,r,q,b,a,t;
node* root;

int main()
{
          ios_base::sync_with_stdio(0);
          cin>>n>>q>>m;
          for(int i=0;i<n;i++)
          {
                    cin>>a;
                    root = merge(root, new node{a, rand(), 1, 0, 0, 0});
          }
          int pos=0;
          while(q--)
          {
                    cin>>t>>l>>r;
                    if(t==1)
                    {
auto x = split(root, r);
			auto y = split(x.first, l - 1);
			auto z = split(y.second, r - l);
			root = merge(z.second, z.first);
			root = merge(y.first, root);
			root = merge(root, x.second);
                    }
                    else
                    {
                              pair<node*, node*> x=split(root,r);
                              pair<node*, node*> y=split(x.first,l-1);
                              y.second->rev=1;
                              root=merge(y.first,y.second);
                              root=merge(root,x.second);
                    }
          }
          p(root);
          for(int i=0;i<m;i++)
          {
                    cin>>b;
                    cout<<ans[b-1]<<" ";
          }
}


#include <bits/stdc++.h>

using namespace std;

struct node
{
	int val, prio, size, rev;
	node *l, *r;
};

inline int size(node *u) { return u ? u->size : 0; }

node* update(node *u)
{
	if (u) u->size = 1 + size(u->l) + size(u->r);
	return u;
}

void push(node *u)
{
	if (u && u->rev)
	{
		swap(u->l, u->r);
		if (u->l) u->l->rev ^= 1;
		if (u->r) u->r->rev ^= 1;
		u->rev = 0;
	}
}

node* merge(node *u, node *v)
{
	push(u); push(v);
	if (!u || !v) return u ? u : v;
	if (u->prio > v->prio)
	{
		u->r = merge(u->r, v);
		update(u);
		return u;
	}
	else
	{
		v->l = merge(u, v->l);
		update(v);
		return v;
	}
}

pair<node*, node*> split(node *u, int k)
{
	if (!u) return make_pair(u, u);
	push(u);
	if (size(u->l) >= k)
	{
		pair<node*, node*> ans = split(u->l, k);
		u->l = ans.second;
		update(u);
		ans.second = u;
		return ans;
	}
	else
	{
		pair<node*, node*> ans = split(u->r, k - size(u->l) - 1);
		u->r = ans.first;
		update(u);
		ans.first = u;
		return ans;
	}
}

vector<int> ans;

void p(node* t)
{
          if(!t) return;
          push(t);
          p(t->l);
          ans.push_back(t->val);
          p(t->r);
}

int main()
{
          ios_base::sync_with_stdio(0);
          int n,q,m;
          cin>>n>>q>>m;
          node* root=0;
          for(int i=0;i<n;i++)
          {
                    int a;
                    cin>>a;
                    root = merge(root, new node{a, rand()*rand(), 1, 0, 0, 0});
          }
	while (q--)
	{
		int t, l, r;
		cin >> t >> l >> r;

		if (t == 1)
		{
			auto x = split(root, r);
			auto y = split(x.first, l - 1);
			auto z = split(y.second, r - l);
			root = merge(z.second, z.first);
			root = merge(y.first, root);
			root = merge(root, x.second);
		}
		else
		{
			auto x = split(root, r);
			auto y = split(x.first, l - 1);
			y.second->rev = 1;
			root = merge(y.first, y.second);
			root = merge(root, x.second);
		}
	}
	vector<int> ord;

	function<void(node*)> dfs = [&](node *u)
	{
		if (!u) return;
		push(u);
		dfs(u->l);
		ord.emplace_back(u->val);
		dfs(u->r);
	};

	dfs(root);

	for (int i = 0; i < m; ++i)
	{
		int b;
		cin >> b;
		cout << ord[--b] << " \n"[i+1==m];
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

struct node
{
	int val, prio, size, rev;
	node *l, *r;
};

inline int size(node *u) { return u ? u->size : 0; }

node* update(node *u)
{
	if (u) u->size = 1 + size(u->l) + size(u->r);
	return u;
}

void push(node *u)
{
	if (u && u->rev)
	{
		swap(u->l, u->r);
		if (u->l) u->l->rev ^= 1;
		if (u->r) u->r->rev ^= 1;
		u->rev = 0;
	}
}

node* merge(node *u, node *v)
{
	push(u); push(v);
	if (!u || !v) return u ? u : v;
	if (u->prio > v->prio)
	{
		u->r = merge(u->r, v);
		update(u);
		return u;
	}
	else
	{
		v->l = merge(u, v->l);
		update(v);
		return v;
	}
}

pair<node*, node*> split(node *u, int k)
{
	if (!u) return make_pair(u, u);
	push(u);
	if (size(u->l) >= k)
	{
		pair<node*, node*> ans = split(u->l, k);
		u->l = ans.second;
		update(u);
		ans.second = u;
		return ans;
	}
	else
	{
		pair<node*, node*> ans = split(u->r, k - size(u->l) - 1);
		u->r = ans.first;
		update(u);
		ans.first = u;
		return ans;
	}
}

vector<int> ans;

void p(node* t)
{
          if(!t) return;
          push(t);
          p(t->l);
          ans.push_back(t->val);
          p(t->r);
}

int n,m,l,r,q,b,a,t;
node* root;

int main()
{
          ios_base::sync_with_stdio(0);
          cin>>n>>q>>m;
          for(int i=0;i<n;i++)
          {
                    cin>>a;
                    root = merge(root, new node{a, rand(), 1, 0, 0, 0});
          }
          for(int i=0;i<q;i++)
          {
                    cin>>t>>l>>r;
                    if(t==1)
                    {
                              pair<node*, node*> x=split(root,r);
                              pair<node*, node*> y=split(x.first,l-1);
                              pair<node*, node*> z=split(y.second,r-1);
                              root=merge(y.first,z.second);
                              root=merge(root,z.first);
                              root=merge(root,x.second);
                    }
                    else
                    {
                              pair<node*, node*> x=split(root,r);
                              pair<node*, node*> y=split(x.first,l-1);
                              y.second->rev=1;
                              root=merge(y.first,y.second);
                              root=merge(root,x.second);
                    }
          }
          vector<int> ord;

	function<void(node*)> dfs = [&](node *u)
	{
		if (!u) return;
		push(u);
		dfs(u->l);
		ord.emplace_back(u->val);
		dfs(u->r);
	};

	dfs(root);
          for(int i=0;i<m;i++)
          {
                    cin>>b;
                    cout<<ord[b-1]<<" ";
          }
}


#include <bits/stdc++.h>

using namespace std;

struct node
{
	int val, prio, size, rev;
	node *l, *r;
};

inline int size(node *u) { return u ? u->size : 0; }

node* update(node *u)
{
	if (u) u->size = 1 + size(u->l) + size(u->r);
	return u;
}

void push(node *u)
{
	if (u && u->rev)
	{
		swap(u->l, u->r);
		if (u->l) u->l->rev ^= 1;
		if (u->r) u->r->rev ^= 1;
		u->rev = 0;
	}
}

node* merge(node *u, node *v)
{
	push(u); push(v);
	if (!u || !v) return u ? u : v;
	if (u->prio > v->prio)
	{
		u->r = merge(u->r, v);
		update(u);
		return u;
	}
	else
	{
		v->l = merge(u, v->l);
		update(v);
		return v;
	}
}

pair<node*, node*> split(node *u, int k)
{
	if (!u) return make_pair(u, u);
	push(u);
	if (size(u->l) >= k)
	{
		pair<node*, node*> ans = split(u->l, k);
		u->l = ans.second;
		update(u);
		ans.second = u;
		return ans;
	}
	else
	{
		pair<node*, node*> ans = split(u->r, k - size(u->l) - 1);
		u->r = ans.first;
		update(u);
		ans.first = u;
		return ans;
	}
}

vector<int> ans;

void p(node* t)
{
          if(!t) return;
          push(t);
          p(t->l);
          ans.push_back(t->val);
          p(t->r);
}

int main()
{
          ios_base::sync_with_stdio(0);
          int n,q,m;
          cin>>n>>q>>m;
          node* root=0;
          for(int i=0;i<n;i++)
          {
                    int a;
                    cin>>a;
                    root = merge(root, new node{a, rand()*rand(), 1, 0, 0, 0});
          }
          for(int i=0;i<q;i++)
          {
                    int t,l,r;
                    cin>>t>>l>>r;
                    if(t==1)
                    {
                              pair<node*, node*> x=split(root,r);
                              pair<node*, node*> y=split(x.first,l-1);
                              pair<node*, node*> z=split(y.second,r-1);
                              root=merge(z.second,z.first);
                              root=merge(y.first,root);
                              root=merge(root,x.second);
                    }
                    else
                    {
                              pair<node*, node*> x=split(root,r);
                              pair<node*, node*> y=split(x.first,l-1);
                              y.second->rev=1;
                              root=merge(y.first,y.second);
                              root=merge(root,x.second);
                    }
          }
          p(root);
          for(int i=0;i<m;i++)
          {
                    int b;
                    cin>>b;
                    cout<<ans[b-1]<<" ";
          }
}


#include <bits/stdc++.h>

using namespace std;

struct node
{
	int val, prio, size, rev;
	node *l, *r;
};

inline int size(node *u) { return u ? u->size : 0; }

node* update(node *u)
{
	if (u) u->size = 1 + size(u->l) + size(u->r);
	return u;
}

void push(node *u)
{
	if (u && u->rev)
	{
		swap(u->l, u->r);
		if (u->l) u->l->rev ^= 1;
		if (u->r) u->r->rev ^= 1;
		u->rev = 0;
	}
}

node* merge(node *u, node *v)
{
	push(u); push(v);
	if (!u || !v) return u ? u : v;
	if (u->prio > v->prio)
	{
		u->r = merge(u->r, v);
		update(u);
		return u;
	}
	else
	{
		v->l = merge(u, v->l);
		update(v);
		return v;
	}
}

pair<node*, node*> split(node *u, int k)
{
	if (!u) return make_pair(u, u);
	push(u);
	if (size(u->l) >= k)
	{
		pair<node*, node*> ans = split(u->l, k);
		u->l = ans.second;
		update(u);
		ans.second = u;
		return ans;
	}
	else
	{
		pair<node*, node*> ans = split(u->r, k - size(u->l) - 1);
		u->r = ans.first;
		update(u);
		ans.first = u;
		return ans;
	}
}

vector<int> ans;

void p(node* t)
{
          if(!t) return;
          push(t);
          p(t->l);
          ans.push_back(t->val);
          p(t->r);
}

int n,m,l,r,q,b,a,t;
node* root;

int main()
{
          ios_base::sync_with_stdio(0);
          cin>>n>>q>>m;
          for(int i=0;i<n;i++)
          {
                    cin>>a;
                    root = merge(root, new node{a, rand(), 1, 0, 0, 0});
          }
          int pos=0;
          while(q--)
          {
                    cin>>t>>l>>r;
                    if(t==1)
                    {
                              auto x=split(root,r);
                              auto y=split(x.first,l-1);
                              auto z=split(y.second,r-1);
			root = merge(z.second, z.first);
			root = merge(y.first, root);
			root = merge(root, x.second);
                    }
                    else
                    {
                              auto x=split(root,r);
                              auto y=split(x.first,l-1);
                              y.second->rev=1;
                              root=merge(y.first,y.second);
                              root=merge(root,x.second);
                    }
          }
          p(root);
          for(int i=0;i<m;i++)
          {
                    cin>>b;
                    cout<<ans[b-1]<<" ";
          }
}


#include <bits/stdc++.h>

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

#define INF 0x2F2F2F2F

using namespace std;

typedef pair<int, int> pii;
typedef pair<int, pii> piii;

const int maxn = 1e5 + 17;

int N, Q, M;
int in[maxn];
piii query[maxn];

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

    cin >> N >> Q >> M;
    for (int i = 1; i <= N; i++) cin >> in[i];
    for (int i = 1; i <= Q; i++) cin >> query[i].f >> query[i].s.f >> query[i].s.s;

    while (M--) {
        int x; cin >> x;

        for (int i = Q; i; i--)
            if (query[i].s.f <= x && x <= query[i].s.s) {
                if (query[i].f == 1)
                    if (--x < query[i].s.f) x = query[i].s.s;

                if (query[i].f == 2) x = query[i].s.f + query[i].s.s - x;
            }

        cout << in[x] << endl;
    }

    return 0;
}


#include <bits/stdc++.h>

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

#define INF 0x2F2F2F2F

using namespace std;

typedef pair<int, int> pii;
typedef pair<int, pii> piii;

const int maxn = 2e5 + 17;

int N, Q, M;
int in[maxn];
piii query[maxn];

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

    cin >> N >> Q >> M;
    for (int i = 1; i <= N; i++) cin >> in[i];
    for (int i = 1; i <= Q; i++) cin >> query[i].f >> query[i].s.f >> query[i].s.s;

    while (M--) {
        int x; cin >> x;

        for (int i = Q; i; i--)
            if (query[i].s.f <= x && x <= query[i].s.s) {
                if (query[i].f == 1 && --x < query[i].s.f) x = query[i].s.s;

                if (query[i].f == 2) x = query[i].s.f + query[i].s.s - x;
            }

        cout << in[x] << endl;
    }

    return 0;
}


#include <bits/stdc++.h>

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

#define INF 0x2F2F2F2F

using namespace std;

typedef pair<int, int> pii;
typedef pair<int, pii> piii;

const int maxn = 2e5 + 17;

int N, Q, M;
int in[maxn];
piii query[maxn];

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

    cin >> N >> Q >> M;
    for (int i = 1; i <= N; i++) cin >> in[i];
    for (int i = 1; i <= Q; i++) cin >> query[i].f >> query[i].s.f >> query[i].s.s;

    while (M--) {
        int x; cin >> x;

        for (int i = Q; i; i--)
            if (query[i].s.f <= x && x <= query[i].s.s) {
                if (query[i].f == 1)
                    if (--x < query[i].s.f) x = query[i].s.s;

                if (query[i].f == 2) x = query[i].s.f + query[i].s.s - x;
            }

        cout << in[x] << endl;
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, q, m;
ll a[111111], t[111111], l[111111], r[111111];
ll solve(ll x){
    for (int i = q; i > 0; --i){
        if (l[i] <= x && x<= r[i]){
            if (t[i] == 1){
                x--;
                if (x<l[i]){
                    x=r[i];
                }
            }else{
                if (x-l[i] < r[i]-x){
                    x=r[i]-(x-l[i]);
                }else{
                    x=l[i]+(r[i]-x);
                }
            }
        }
    }
    return a[x];
}
int main (){
    cin >> n >> q >> m;
    for (int i = 1; i <= n; ++i){
        cin >> a[i];
    }
    for (int i = 1; i <= q; ++i){
        cin >> t[i] >> l[i] >> r[i];
    }
    vector <ll> vec;
    for (int i = 1; i <= m; ++i){
        int x;
        cin >> x;
        vec.push_back(solve(x));
    }
    for (int i = 0; i < vec.size(); ++i){
        cout << vec[i] << " ";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, q, m;
ll a[1111111], t[1111111], l[1111111], r[1111111];
ll solve(ll x){
    for (int i = q; i > 0; --i){
        if (l[i] <= x && x <= r[i]){
            if (t[i] == 1){
                x--;
                if (x<l[i]){
                    x=r[i];
                }
            }else{
                x=r[i]-x+l[i];
            }
        }
    }
    return a[x];
}
int main (){
    cin >> n >> q >> m;
    for (int i = 1; i <= n; ++i){
        cin >> a[i];
    }
    for (int i = 1; i <= q; ++i){
        cin >> t[i] >> l[i] >> r[i];
    }
    vector <ll> vec;
    for (int i = 1; i <= m; ++i){
        ll x;
        cin >> x;
        vec.push_back(solve(x));
    }
    for (int i = 0; i < vec.size(); ++i){
        cout << vec[i] << " ";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, q, m;
ll a[111111], t[111111], l[111111], r[111111];
int solve(ll x){
    for (int i = q; i > 0; --i){
        if (l[i] <= x && x<= r[i]){
            if (t[i] == 1){
                x--;
                if (x<l[i]){
                    x=r[i];
                }
            }else{
                if (x-l[i] < x-r[i]){
                    x=r[i]-(x-l[i]);
                }else{
                    x=l[i]+(r[i]-x);
                }
            }
        }
    }
    return a[x];
}
int main (){
    cin >> n >> q >> m;
    for (int i = 1; i <= n; ++i){
        cin >> a[i];
    }
    for (int i = 1; i <= q; ++i){
        cin >> t[i] >> l[i] >> r[i];
    }
    vector <ll> vec;
    for (int i = 1; i <= m; ++i){
        int x;
        cin >> x;
        vec.push_back(solve(x));
    }
    for (int i = 0; i < vec.size(); ++i){
        cout << vec[i] << " ";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, q, m;
ll a[111111], t[111111], l[111111], r[111111];
ll solve(ll x){
    for (int i = q; i > 0; --i){
        if (l[i] <= x && x<= r[i]){
            if (t[i] == 1){
                x--;
                if (x<l[i]){
                    x=r[i];
                }
            }else{
                if (x-l[i] < x-r[i]){
                    x=r[i]-(x-l[i]);
                }else{
                    x=l[i]+(r[i]-x);
                }
            }
        }
    }
    return a[x];
}
int main (){
    cin >> n >> q >> m;
    for (int i = 1; i <= n; ++i){
        cin >> a[i];
    }
    for (int i = 1; i <= q; ++i){
        cin >> t[i] >> l[i] >> r[i];
    }
    vector <ll> vec;
    for (int i = 1; i <= m; ++i){
        int x;
        cin >> x;
        vec.push_back(solve(x));
    }
    for (int i = 0; i < vec.size(); ++i){
        cout << vec[i] << " ";
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, q, m;
ll a[111111], t[111111], l[111111], r[111111];
int solve(ll x){
    for (int i = q; i > 0; --i){
        if (l[i] <= x && x<= r[i]){
            if (t[i] == 1){
                x--;
                if (x<l[i]){
                    x=r[i];
                }
            }else{
                if (x-l[i] < x-r[i]){
                    x=r[i]-(x-l[i]);
                }else{
                    x=l[i]+(r[i]-x);
                }
            }
        }
    }
    return x;
}
int main (){
    cin >> n >> q >> m;
    for (int i = 1; i <= n; ++i){
        cin >> a[i];
    }
    for (int i = 1; i <= q; ++i){
        cin >> t[i] >> l[i] >> r[i];
    }
    vector <ll> vec;
    for (int i = 1; i <= m; ++i){
        int x;
        cin >> x;
        vec.push_back(solve(x));
    }
    for (int i = 0; i < vec.size(); ++i){
        cout << vec[i] << " ";
    }
    return 0;
}


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

using namespace std;

int n, q, m, op, begin_id, end_id, temp;
vector<int> a;

int main(){
  scanf("%d %d %d", &n, &q, &m);

  for(int i = 0; i < n; i++){
    scanf("%d", &temp);
    a.push_back(temp);
  }

  for(int i = 0; i < q; i++){
    scanf("%d %d %d", &op, &begin_id, &end_id);
    if(op == 2){
      reverse(a.begin() + begin_id - 1, a.begin() + end_id);
    }else if(op == 1){
      temp = a[end_id - 1];
      for(int j = end_id - 1; j >= begin_id; j--){
        a[j] = a[j - 1];
      }
      a[begin_id - 1] = temp;
    }
  }

  for(int i = 0; i < m; i++){
    scanf("%d", &temp);
    printf("%d ", a[temp - 1]);
  }
  printf("%c", '\n');
}


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

using namespace std;

int n, q, m, b, temp;
vector<int> a;

int main(){
  scanf("%d %d %d", &n, &q, &m);

  int op[q]; int l[q]; int r[q];

  for(int i = 0; i < n; i++){
    scanf("%d", &temp);
    a.push_back(temp);
  }

  for(int i = 0; i < q; i++){
    scanf("%d %d %d", &op[i], &l[i], &r[i]);
  }

  for(int i = 0; i < m; i++){
    scanf("%d", &b);

    for(int j = q - 1; j >= 0; j--){
      if(b >= l[j] && b <= r[j]){
        if(op[j] == 2){
          b = l[j] + r[j] - b;
        }else{
          if(b == l[j]){
            b = r[j];
          }else{
            b--;
          }
        }
      }
    }
    printf("%d ", a[b - 1]);
  }
  printf("%c", '\n');
}


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

using namespace std;

int n, q, m, op, begin_id, end_id, temp;
vector<int> a;

int main(){
  scanf("%d %d %d", &n, &q, &m);

  for(int i = 0; i < n; i++){
    scanf("%d", &temp);
    a.push_back(temp);
  }

  for(int i = 0; i < q; i++){
    scanf("%d %d %d", &op, &begin_id, &end_id);
    if(op == 2){
      reverse(a.begin() + begin_id - 1, a.begin() + end_id);
    }else if(op == 1){
      temp = a[end_id - 1];
      for(int j = end_id - 1; j >= begin_id; j--){
        a[j] = a[j - 1];
      }
      a[begin_id - 1] = temp;
    }
    for(int i = 0; i < n; i++){
      printf("%d ", a[i]);
    }
    printf("%c", '\n');
  }

  for(int i = 0; i < m; i++){
    scanf("%d", &temp);
    printf("%d ", a[temp - 1]);
  }
  printf("%c", '\n');
}


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

using namespace std;

int n, q, m, b;

int main(){
  scanf("%d %d %d", &n, &q, &m);

  int op[q]; int l[q]; int r[q]; int a[n];

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

  for(int i = 0; i < q; i++){
    scanf("%d %d %d", &op[i], &l[i], &r[i]);
  }

  for(int i = 0; i < m; i++){
    scanf("%d", &b);

    for(int j = q - 1; j >= 0; j--){
      if(b >= l[j] && b <= r[j]){
        if(op[j] == 2){
          b = l[j] + r[j] - b;
        }else{
          if(b == l[j]){
            b = r[j];
          }else{
            b--;
          }
        }
      }
    }
    printf("%d ", a[b - 1]);
  }
  printf("%c", '\n');
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define newline '\n'
main(){
    ios :: sync_with_stdio(false);
    cin.tie(false);
    cout.tie(false);
    int n , cases , m;
    cin >>n >>cases >>m;
    int arr[n *2];
    for(int i =1 ; i <=n ; i ++) cin >>arr[i];
    int type [n *2] , left[n *2] , right[n *2];
    int i =1;
    for(int i =1 ; i <=cases ; i ++) cin >>type[i] >>left[i] >>right[i];
    for(int i =1 ; i <=m ; i ++){
        int idx;
        cin >>idx;
        for(int j =cases ; j >=1 ; j --){
            if(left[j] <=idx && right[j] >=idx){
                if(type[j] ==2){
                    idx =left[j] +right[j] -idx;
                }
                if(type[j] ==1){
                    if(idx ==left[j]) idx =right[j];
                    else idx --;
                }
            }
        //    cerr <<idx <<newline;
        }
        cout <<arr[idx] <<" ";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define newline '\n'
main(){
    ios :: sync_with_stdio(false);
    cin.tie(false);
    cout.tie(false);
    int n , cases , m;
    cin >>n >>cases >>m;
    int arr[n *2];
    for(int i =1 ; i <=n ; i ++) cin >>arr[i];
    int type [cases *2] , left[cases *2] , right[cases *2];
    int i =1;
    for(int i =1 ; i <=cases ; i ++) cin >>type[i] >>left[i] >>right[i];
    for(int i =1 ; i <=m ; i ++){
        int idx;
        cin >>idx;
        for(int j =cases ; j >=1 ; j --){
            if(left[j] <=idx && right[j] >=idx){
                if(type[j] ==2){
                    idx =left[j] +right[j] -idx;
                }
                if(type[j] ==1){
                    if(idx ==left[j]) idx =right[j];
                    else idx --;
                }
            }
        //    cerr <<idx <<newline;
        }
        cout <<arr[idx] <<" ";
    }
    return 0;
}


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

struct Node {
    Node* lef;
    Node* rig;
    int cnt;
    bool rev;
    int value;
    int pri;
    Node(int value, int pri = rand()) : lef(NULL), rig(NULL), cnt(1), rev(false), value(value), pri(pri) {
    }
    void up() {
        cnt = 1 + (lef ? lef->cnt : 0) + (rig ? rig->cnt : 0);
    }
    void down() {
        if (rev) {
            if (lef) lef->rev ^= true;
            if (rig) rig->rev ^= true;
            swap(lef, rig);
            rev = false;
        }
    }
};

typedef Node* PNode;
typedef pair<Node*, Node*> PairNode;

PNode build(int lef, int rig, int& priority, const vector<int>& a) {
    if (lef > rig) {
        return NULL;
    }
    if (lef == rig) {
        return new Node(a[lef], priority);
    }
    int mid = (lef + rig) >> 1;
    PNode t = new Node(a[mid], priority--);
    t->lef = build(lef, mid - 1, priority, a);
    t->rig = build(mid + 1, rig, priority, a);
    t->up();
    return t;
}

void debug_iter(PNode root) {
    if (!root) {
        return;
    }
    root->down();
    debug_iter(root->lef);
    cout << root->value << " ";
    debug_iter(root->rig);
}

void debug(PNode root) {
    debug_iter(root);
    cout << "\n";
}

PairNode split(PNode root, int key) {
    if (!root) {
        return {NULL, NULL};
    }
    root->down();
    int cur = 1 + (root->lef ? root->lef->cnt : 0);
    if (cur > key) {
        PairNode t = split(root->lef, key);
        root->lef = t.second;
        root->up();
        return {t.first, root};
    } else {
        PairNode t = split(root->rig, key - cur);
        root->rig = t.first;
        root->up();
        return {root, t.second};
    }
}

void split(PNode root, int cnt, PNode& t1, PNode& t2) {
    PairNode t = split(root, cnt);
    t1 = t.first;
    t2 = t.second;
}

PNode merge(PNode a, PNode b) {
    if (!a || !b) {
        return a ? a : b;
    }
    a->down();
    b->down();
    if (a->pri > b->pri) {
        PNode t = merge(a->rig, b);
        a->rig = t;
        a->up();
        return a;
    } else {
        PNode t = merge(a, b->lef);
        b->lef = t;
        b->up();
        return b;
    }
}

void solve() {
    int n, q, m;
    cin >> n >> q >> m;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    PNode treap = build(1, n, n, a);

    while (q--) {
        char type;
        cin >> type;
        if (type == '1') {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3, t4;
            split(treap, l - 1, t1, t2);
            split(t2, r - l, t2, t3);
            split(t3, 1, t3, t4);
            treap = merge(merge(t1, t3), merge(t2, t4));
        } else {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3;
            split(treap, l - 1, t1, t2);
            split(t2, r - l + 1, t2, t3);
            t2->rev = true;
            treap = merge(merge(t1, t2), t3);
        }
    }
    while (m--) {
        int x;
        cin >> x;
        PNode t1, t2, t3;
        split(treap, x - 1, t1, t2);
        split(t2, 1, t2, t3);
        cout << t2->value << " ";
        treap = merge(t1, merge(t2, t3));
    }
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int tt = 1;
    for (int it = 1; it <= tt; ++it) {
        solve();
    }
    cerr << fixed << setprecision(5) << double(clock()) * 1000 / CLOCKS_PER_SEC << " ms\n";
    return 0;
}


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

struct Node {
    Node* lef;
    Node* rig;
    int cnt;
    bool rev;
    int value;
    int pri;
    Node(int value, int pri = rand()) : lef(NULL), rig(NULL), cnt(1), rev(false), value(value), pri(pri) {
    }
    void up() {
        cnt = 1 + (lef ? lef->cnt : 0) + (rig ? rig->cnt : 0);
    }
    void down() {
        if (rev) {
            if (lef) lef->rev ^= true;
            if (rig) rig->rev ^= true;
            swap(lef, rig);
            rev = false;
        }
    }
};

typedef Node* PNode;
typedef pair<Node*, Node*> PairNode;

PNode build(int lef, int rig, int& priority, const vector<int>& a) {
    if (lef > rig) {
        return NULL;
    }
    if (lef == rig) {
        return new Node(a[lef], rand());
    }
    int mid = (lef + rig) >> 1;
    PNode t = new Node(a[mid], priority--);
    t->lef = build(lef, mid - 1, priority, a);
    t->rig = build(mid + 1, rig, priority, a);
    t->up();
    return t;
}

void debug_iter(PNode root) {
    if (!root) {
        return;
    }
    root->down();
    debug_iter(root->lef);
    cout << root->value << " ";
    debug_iter(root->rig);
}

void debug(PNode root) {
    debug_iter(root);
    cout << "\n";
}

PairNode split(PNode root, int key) {
    if (!root) {
        return {NULL, NULL};
    }
    root->down();
    int cur = 1 + (root->lef ? root->lef->cnt : 0);
    if (cur > key) {
        PairNode t = split(root->lef, key);
        root->lef = t.second;
        root->up();
        return {t.first, root};
    } else {
        PairNode t = split(root->rig, key - cur);
        root->rig = t.first;
        root->up();
        return {root, t.second};
    }
}

void split(PNode root, int cnt, PNode& t1, PNode& t2) {
    PairNode t = split(root, cnt);
    t1 = t.first;
    t2 = t.second;
}

PNode merge(PNode a, PNode b) {
    if (!a || !b) {
        return a ? a : b;
    }
    a->down();
    b->down();
    if (a->pri > b->pri) {
        PNode t = merge(a->rig, b);
        a->rig = t;
        a->up();
        return a;
    } else {
        PNode t = merge(a, b->lef);
        b->lef = t;
        b->up();
        return b;
    }
}

void solve() {
    int n, q, m;
    cin >> n >> q >> m;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
  //  PNode treap = build(1, n, n, a);
    PNode treap = NULL;
    for (int i = 1; i <= n; ++i) {
        treap = merge(treap, new Node(a[i]));
    }

    while (q--) {
        char type;
        cin >> type;
        if (type == '1') {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3, t4;
            split(treap, l - 1, t1, t2);
            split(t2, r - l, t2, t3);
            split(t3, 1, t3, t4);
            treap = merge(merge(t1, t3), merge(t2, t4));
        } else {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3;
            split(treap, l - 1, t1, t2);
            split(t2, r - l + 1, t2, t3);
            t2->rev = true;
            treap = merge(merge(t1, t2), t3);
        }
    }
    while (m--) {
        int x;
        cin >> x;
        PNode t1, t2, t3;
        split(treap, x - 1, t1, t2);
        split(t2, 1, t2, t3);
        cout << t2->value << " ";
        treap = merge(t1, merge(t2, t3));
    }
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int tt = 1;
    for (int it = 1; it <= tt; ++it) {
        solve();
    }
    cerr << fixed << setprecision(5) << double(clock()) * 1000 / CLOCKS_PER_SEC << " ms\n";
    return 0;
}


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

struct Node {
    Node* lef;
    Node* rig;
    int cnt;
    bool rev;
    int value;
    int pri;
    Node(int value, int pri = rand()) : lef(NULL), rig(NULL), cnt(1), rev(false), value(value), pri(pri) {
    }
    void up() {
        cnt = 1 + (lef ? lef->cnt : 0) + (rig ? rig->cnt : 0);
    }
    void down() {
        if (rev) {
            if (lef) lef->rev ^= true;
            if (rig) rig->rev ^= true;
            swap(lef, rig);
            rev = false;
        }
    }
};

typedef Node* PNode;
typedef pair<Node*, Node*> PairNode;

PNode build(int lef, int rig, int& priority, const vector<int>& a) {
    if (lef > rig) {
        return NULL;
    }
    if (lef == rig) {
        return new Node(a[lef], priority);
    }
    int mid = (lef + rig) >> 1;
    PNode t = new Node(a[mid], priority--);
    t->lef = build(lef, mid - 1, priority, a);
    t->rig = build(mid + 1, rig, priority, a);
    t->up();
    return t;
}

void debug_iter(PNode root) {
    if (!root) {
        return;
    }
    root->down();
    debug_iter(root->lef);
    cout << root->value << " ";
    debug_iter(root->rig);
}

void debug(PNode root) {
    debug_iter(root);
    cout << "\n";
}

PairNode split(PNode root, int cnt) {
    if (!root) {
        return {NULL, NULL};
    }
    int cur = (root->lef ? root->lef->cnt : 0);
    root->down();
    if (cur >= cnt) {
        PairNode t = split(root->lef, cnt);
        root->lef = t.second;
        root->up();
        return {t.first, root};
    }
    ++cur;
    if (cur == cnt) {
        PNode t = root->rig;
        root->rig = NULL;
        root->up();
        return {root, t};
    }
    PairNode t = split(root->rig, cnt - cur);
    root->rig = t.first;
    root->up();
    return {root, t.second};
}

void split(PNode root, int cnt, PNode& t1, PNode& t2) {
    PairNode t = split(root, cnt);
    t1 = t.first;
    t2 = t.second;
}

PNode merge(PNode a, PNode b) {
    if (!a || !b) {
        return a ? a : b;
    }
    a->down();
    b->down();
    if (a->pri > b->pri) {
        PNode t = merge(a->rig, b);
        a->rig = t;
        a->up();
        return a;
    } else {
        PNode t = merge(a, b->lef);
        b->lef = t;
        b->up();
        return b;
    }
}

void solve() {
    int n, q, m;
    cin >> n >> q >> m;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    PNode treap = build(1, n, n, a);

    while (q--) {
        char type;
        cin >> type;
        if (type == '1') {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3, t4;
            split(treap, l - 1, t1, t2);
            split(t2, r - l, t2, t3);
            split(t3, 1, t3, t4);
            treap = merge(merge(t1, t3), merge(t2, t4));
        } else {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3;
            split(treap, l - 1, t1, t2);
            split(t2, r - l + 1, t2, t3);

            t2->rev = true;
            treap = merge(merge(t1, t2), t3);
        }
    }
    while (m--) {
        int x;
        cin >> x;
        PNode t1, t2, t3;
        split(treap, x - 1, t1, t2);
        split(t2, 1, t2, t3);
        cout << t2->value << " ";
        treap = merge(t1, merge(t2, t3));
    }
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int tt = 1;
    for (int it = 1; it <= tt; ++it) {
        solve();
    }
    cerr << fixed << setprecision(5) << double(clock()) * 1000 / CLOCKS_PER_SEC << " ms\n";
    return 0;
}


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

struct Node {
    Node* lef;
    Node* rig;
    int cnt;
    bool rev;
    int value;
    int pri;
    Node(int value, int pri = rand()) : lef(NULL), rig(NULL), cnt(1), rev(false), value(value), pri(pri) {
    }
    void up() {
        cnt = 1 + (lef ? lef->cnt : 0) + (rig ? rig->cnt : 0);
    }
    void down() {
        if (rev) {
            if (lef) lef->rev ^= true;
            if (rig) rig->rev ^= true;
            swap(lef, rig);
            rev = false;
        }
    }
};

typedef Node* PNode;
typedef pair<Node*, Node*> PairNode;

PNode build(int lef, int rig, int& priority, const vector<int>& a) {
    if (lef > rig) {
        return NULL;
    }
    if (lef == rig) {
        return new Node(a[lef], priority);
    }
    int mid = (lef + rig) >> 1;
    PNode t = new Node(a[mid], priority--);
    t->lef = build(lef, mid - 1, priority, a);
    t->rig = build(mid + 1, rig, priority, a);
    t->up();
    return t;
}

void debug_iter(PNode root) {
    if (!root) {
        return;
    }
    root->down();
    debug_iter(root->lef);
    cout << root->value << " ";
    debug_iter(root->rig);
}

void debug(PNode root) {
    debug_iter(root);
    cout << "\n";
}

PairNode split(PNode root, int cnt) {
    if (!root) {
        return {NULL, NULL};
    }
    int cur = (root->lef ? root->lef->cnt : 0);
    root->down();
    if (cur >= cnt) {
        PairNode t = split(root->lef, cnt);
        root->lef = t.second;
        root->up();
        return {t.first, root};
    }
    ++cur;
    if (cur == cnt) {
        PNode t = root->rig;
        root->rig = NULL;
        root->up();
        return {root, t};
    }
    PairNode t = split(root->rig, cnt - cur);
    root->rig = t.first;
    root->up();
    return {root, t.second};
}

void split(PNode root, int cnt, PNode& t1, PNode& t2) {
    PairNode t = split(root, cnt);
    t1 = t.first;
    t2 = t.second;
}

PNode merge(PNode a, PNode b) {
    if (!a || !b) {
        return a ? a : b;
    }
    a->down();
    b->down();
    if (a->pri > b->pri) {
        PNode t = merge(a->rig, b);
        a->rig = t;
        a->up();
        return a;
    } else {
        PNode t = merge(a, b->lef);
        b->lef = t;
        b->up();
        return b;
    }
}

void solve() {
    int n, q, m;
    cin >> n >> q >> m;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    PNode treap = build(1, n, n, a);

    while (q--) {
        char type;
        cin >> type;
        if (type == '1') {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3, t4;
            split(treap, l - 1, t1, t2);
            split(t2, r - l, t2, t3);
            split(t3, 1, t3, t4);
            treap = merge(merge(t1, t3), merge(t2, t4));
        } else {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3;
            split(treap, l - 1, t1, t2);
            split(t2, r - l + 1, t2, t3);
            if (t2) {
                t2->rev = true;
            }
            treap = merge(merge(t1, t2), t3);
        }
    }
    while (m--) {
        int x;
        cin >> x;
        PNode t1, t2, t3;
        split(treap, x - 1, t1, t2);
        split(t2, 1, t2, t3);
        cout << t2->value << " ";
        treap = merge(t1, merge(t2, t3));
    }
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int tt = 1;
    for (int it = 1; it <= tt; ++it) {
        solve();
    }
    cerr << fixed << setprecision(5) << double(clock()) * 1000 / CLOCKS_PER_SEC << " ms\n";
    return 0;
}


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

struct Node {
    Node* lef;
    Node* rig;
    int cnt;
    bool rev;
    int value;
    int pri;
    Node(int value, int pri = rand()) : lef(NULL), rig(NULL), cnt(1), rev(false), value(value), pri(pri) {
    }
    void up() {
        cnt = 1 + (lef ? lef->cnt : 0) + (rig ? rig->cnt : 0);
    }
    void down() {
        if (rev) {
            if (lef) lef->rev ^= true;
            if (rig) rig->rev ^= true;
            swap(lef, rig);
            rev = false;
        }
    }
};

typedef Node* PNode;
typedef pair<Node*, Node*> PairNode;

PNode build(int lef, int rig, int& priority, const vector<int>& a) {
    if (lef > rig) {
        return NULL;
    }
    if (lef == rig) {
        return new Node(a[lef], rand());
    }
    int mid = (lef + rig) >> 1;
    PNode t = new Node(a[mid], priority--);
    t->lef = build(lef, mid - 1, priority, a);
    t->rig = build(mid + 1, rig, priority, a);
    t->up();
    return t;
}

void debug_iter(PNode root) {
    if (!root) {
        return;
    }
    root->down();
    debug_iter(root->lef);
    cout << root->value << " ";
    debug_iter(root->rig);
}

void debug(PNode root) {
    debug_iter(root);
    cout << "\n";
}

PairNode split(PNode root, int key) {
    if (!root) {
        return {NULL, NULL};
    }
    root->down();
    int cur = 1 + (root->lef ? root->lef->cnt : 0);
    if (cur > key) {
        PairNode t = split(root->lef, key);
        root->lef = t.second;
        root->up();
        return {t.first, root};
    } else {
        PairNode t = split(root->rig, key - cur);
        root->rig = t.first;
        root->up();
        return {root, t.second};
    }
}

void split(PNode root, int cnt, PNode& t1, PNode& t2) {
    PairNode t = split(root, cnt);
    t1 = t.first;
    t2 = t.second;
}

PNode merge(PNode a, PNode b) {
    if (!a || !b) {
        return a ? a : b;
    }
    a->down();
    b->down();
    if (a->pri > b->pri) {
        PNode t = merge(a->rig, b);
        a->rig = t;
        a->up();
        return a;
    } else {
        PNode t = merge(a, b->lef);
        b->lef = t;
        b->up();
        return b;
    }
}

void solve() {
    int n, q, m;
    cin >> n >> q >> m;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    PNode treap = build(1, n, n, a);

    while (q--) {
        char type;
        cin >> type;
        if (type == '1') {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3, t4;
            split(treap, l - 1, t1, t2);
            split(t2, r - l, t2, t3);
            split(t3, 1, t3, t4);
            treap = merge(merge(t1, t3), merge(t2, t4));
        } else {
            int l, r;
            cin >> l >> r;
            PNode t1, t2, t3;
            split(treap, l - 1, t1, t2);
            split(t2, r - l + 1, t2, t3);
            t2->rev = true;
            treap = merge(merge(t1, t2), t3);
        }
    }
    while (m--) {
        int x;
        cin >> x;
        PNode t1, t2, t3;
        split(treap, x - 1, t1, t2);
        split(t2, 1, t2, t3);
        cout << t2->value << " ";
        treap = merge(t1, merge(t2, t3));
    }
    cout << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int tt = 1;
    for (int it = 1; it <= tt; ++it) {
        solve();
    }
    cerr << fixed << setprecision(5) << double(clock()) * 1000 / CLOCKS_PER_SEC << " ms\n";
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iomanip>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define debug(x) cerr<<#x<<"="<<x<<endl
#define INF 0x7f7f7f7f
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
inline int init()
{
    int now=0,ju=1;char c;bool flag=false;
    while(1)
    {
        c=getchar();
        if(c=='-')ju=-1;
        else if(c>='0'&&c<='9')
        {
            now=now*10+c-'0';
            flag=true;
        }
        else if(flag)return now*ju;
    }
}
inline long long llinit()
{
    long long now=0,ju=1;char c;bool flag=false;
    while(1)
    {
        c=getchar();
        if(c=='-')ju=-1;
        else if(c>='0'&&c<='9')
        {
            now=now*10+c-'0';
            flag=true;
        }
        else if(flag)return now*ju;
    }
}
int a[100005];
struct node
{
	int l,r,x;
}query[100005];
int n,q,m,x;
int main()
{
	n=init();q=init();m=init();
	for(int i=1;i<=n;i++)a[i]=init();
	for(int i=1;i<=q;i++)
	{
		query[i].x=init();query[i].l=init();query[i].r=init();
	}
	for(int i=1;i<=m;i++)
	{
		x=init();
		for(int j=q;j>=1;j--)
		{
			if(x<=query[j].r&&x>=query[j].l)
			{
				if(query[j].x==1)
				{
					x--;
					if(x<query[j].l)x=query[j].r;
				}
				else
				{
					x=query[j].r-x+query[j].l;
				}
			}
		}
		printf("%d\n",a[x]);
	}
	return 0;
}
/*
srO xudyh davidlee1999WTK linkct1999 zlser Orz
*/


#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iomanip>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define debug(x) cerr<<#x<<"="<<x<<endl
#define INF 0x7f7f7f7f
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
inline int init()
{
    int now=0,ju=1;char c;bool flag=false;
    while(1)
    {
        c=getchar();
        if(c=='-')ju=-1;
        else if(c>='0'&&c<='9')
        {
            now=now*10+c-'0';
            flag=true;
        }
        else if(flag)return now*ju;
    }
}
inline long long llinit()
{
    long long now=0,ju=1;char c;bool flag=false;
    while(1)
    {
        c=getchar();
        if(c=='-')ju=-1;
        else if(c>='0'&&c<='9')
        {
            now=now*10+c-'0';
            flag=true;
        }
        else if(flag)return now*ju;
    }
}
int a[1000005];
struct node
{
	int l,r,x;
}query[1000005];
int n,q,m,x;
int main()
{
	n=init();q=init();m=init();
	for(int i=1;i<=n;i++)a[i]=init();
	for(int i=1;i<=q;i++)
	{
		query[i].x=init();query[i].l=init();query[i].r=init();
	}
	for(int i=1;i<=m;i++)
	{
		x=init();
		for(int j=q;j>=1;j--)
		{
			if(x<=query[j].r&&x>=query[j].l)
			{
				if(query[j].x==1)
				{
					x--;
					if(x<query[j].l)x=query[j].r;
				}
				else
				{
					x=query[j].r-x+query[j].l;
				}
			}
		}
		printf("%d\n",a[x]);
	}
	return 0;
}
/*
srO xudyh davidlee1999WTK linkct1999 zlser Orz
*/


#include <cstdio>
#include <iostream>
#include <string>
#include <limits>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

using ll = long long;

const int N = 2e5 + 5;

int arr[N];

struct {
    int t, l, r;
} reqs[N];

int ms[105];

bool solve() {
    int n, q, m;
    cin >> n >> q >> m;
    for (int i = 0; i < n; ++i)
        scanf("%d", arr + i);
    for (int i = 0; i < q; ++i) {
        int l, r;
        scanf("%d %d %d", &reqs[i].t, &l, &r);
        reqs[i].l = l - 1;
        reqs[i].r = r;
    }
    for (int i = 0; i < m; ++i) {
        int d;
        scanf("%d", &d);
        ms[i] = d - 1;
    }
    for (int j = 0; j < m; ++j) {
        for (int i = n - 1; i >= 0; --i) {
            int l = reqs[i].l;
            int r = reqs[i].r;
            if (ms[j] >= l && ms[j] < r) {
                if (reqs[i].t == 1)
                    ms[j] = (ms[j] == l ? r - 1 : ms[j] - 1);
                else
                    ms[j] = l + r - 1 - ms[j];
            }
        }
    }
    for (int i = 0; i < m; ++i)
        printf("%d ", arr[ms[i]]);
    cout << endl;

    return 0;
}

int main() {
#ifdef LOCALHOST
    freopen("input", "r", stdin);
#endif
    while (solve());

    return 0;
}


#include <cstdio>
#include <iostream>
#include <string>
#include <limits>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

using ll = long long;

const int N = 1e5 + 5;

int arr[N];

struct {
    int t, l, r;
} reqs[N];

int ms[105];

bool solve() {
    int n, q, m;
    cin >> n >> q >> m;
    for (int i = 0; i < n; ++i)
        scanf("%d", arr + i);
    for (int i = 0; i < q; ++i) {
        int l, r;
        scanf("%d %d %d", &reqs[i].t, &l, &r);
        reqs[i].l = l - 1;
        reqs[i].r = r;
    }
    for (int i = 0; i < m; ++i) {
        int d;
        scanf("%d", &d);
        ms[i] = d - 1;
    }
    for (int j = 0; j < m; ++j) {
        for (int i = n - 1; i >= 0; --i) {
            int l = reqs[i].l;
            int r = reqs[i].r;
            if (ms[j] >= l && ms[j] < r) {
                if (reqs[i].t == 1)
                    ms[j] = (ms[j] == l ? r - 1 : ms[j] - 1);
                else
                    ms[j] = l + r - 1 - ms[j];
            }
        }
    }
    for (int i = 0; i < m; ++i)
        printf("%d ", arr[ms[i]]);
    cout << endl;

    return 0;
}

int main() {
#ifdef LOCALHOST
    freopen("input", "r", stdin);
#endif
    while (solve());

    return 0;
}


#include <cstdio>
#include <iostream>
#include <string>
#include <limits>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;

using ll = long long;

const int N = 2e5 + 5;

int arr[N];

struct {
    int t, l, r;
} reqs[N];

int ms[105];

bool solve() {
    int n, q, m;
    cin >> n >> q >> m;
    for (int i = 0; i < n; ++i)
        scanf("%d", arr + i);
    for (int i = 0; i < q; ++i) {
        int l;
        scanf("%d %d %d", &reqs[i].t, &l, &reqs[i].r);
        reqs[i].l = l - 1;
    }
    for (int i = 0; i < m; ++i) {
        int d;
        scanf("%d", &d);
        ms[i] = d - 1;
    }
    for (int j = 0; j < m; ++j) {
        for (int i = q - 1; i >= 0; --i) {
            int l = reqs[i].l;
            int r = reqs[i].r;
            if (ms[j] >= l && ms[j] < r) {
                if (reqs[i].t == 1)
                    ms[j] = (ms[j] == l ? r - 1 : ms[j] - 1);
                else
                    ms[j] = l + r - 1 - ms[j];
            }
        }
    }
    for (int i = 0; i < m; ++i)
        printf("%d ", arr[ms[i]]);
    cout << endl;

    return 0;
}

int main() {
#ifdef LOCALHOST
    freopen("input", "r", stdin);
#endif
    while (solve());

    return 0;
}


#include <bits/stdc++.h>
#define db(x) cout << (x) << '\n';
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define f first
#define s second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
typedef pair<double,ll> pdi;
typedef pair<double,pii> pdp;
typedef pair<string,ll> psi;
typedef pair<ll,string> pls;
typedef pair<string,string> pss;
typedef pair<ll,pii> pip;
typedef pair<pii,pii> ppp;
typedef complex<ld> point;
#define mod (ll)(1e9+7)
#define oo (ll)(0x3f3f3f3f3f3f3f3f)
#define MAXN 200005

int a[MAXN];

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

    int n,q,m,l,r,t;
    cin >> n >> q >> m;
    for(int i=0;i<n;i++)
        cin >> a[i];

    vector<pip> qs;
    for(int i=0;i<q;i++)
    {
        cin >> t >> l >> r;
        qs.push_back(pip(t,pii(l,r)));
    }

    vector<int> b(m);
    for(int i=0;i<m;i++)
        cin >> b[i];

    for(int i=q-1;i>=0;i--)
    {
        t=qs[i].f;
        l=qs[i].s.f;
        r=qs[i].s.s;
        for(int j=0;j<m;j++)
        {
            if(t==1)
            {
                if(b[j]>l && b[j]<=r)
                    b[j]--;
                else if(b[j]==l)
                    b[j]=r;
            }
            if(t==2 && l<=b[j] && b[j]<=r)
                b[j]=(l+r-b[j]);
        }
//        for(int j=0;j<m;j++)
//            cout << b[j] << ' ';
//        cout << '\n';
    }

    for(int i=0;i<m;i++)
        cout << a[b[i]-1] << ' ';
    cout << '\n';

    return 0;
}
/**
6 3 5
1 2 3 4 5 6
2 1 3
2 3 6
1 1 6
2 2 1 5 3
**/


#include <bits/stdc++.h>
#define db(x) cout << (x) << '\n';
#define all(v) (v).begin(),(v).end()
#define allr(v) (v).rbegin(),(v).rend()
#define f first
#define s second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pii;
typedef pair<double,ll> pdi;
typedef pair<double,pii> pdp;
typedef pair<string,ll> psi;
typedef pair<ll,string> pls;
typedef pair<string,string> pss;
typedef pair<ll,pii> pip;
typedef pair<pii,pii> ppp;
typedef complex<ld> point;
#define MAXN (ll)(4e5+5)

mt19937 rng(time(0));

template<typename T>
struct treap
{
    ///1-indexed functions
    ///this treap extends array functionalities
    struct node{
        node *l,*r;
        int sz,prior;
        bool rev;
        T v;
        node(T v) : v(v),l(0),r(0),sz(1),rev(0),prior(rng()) {}
    };
    typedef node* pnode;
    pnode root;
    treap() : root(0) {}

    int sz(pnode p) { return p ? p->sz : 0; }

    void update(pnode p)
    {
        if(!p)
            return ;
        p->sz=1+sz(p->l)+sz(p->r);
    }

    void push(pnode p)
    {
        if(!p)
            return ;
        if(p->rev)
        {
            swap(p->l,p->r);
            if(p->l)
                p->l->rev^=1;
            if(p->r)
                p->r->rev^=1;
            p->rev=0;
        }
    }

    void split(pnode p,int key,pnode &l,pnode &r)
    {
        push(p);
        if(!p)
        {
            l=r=0;
            return ;
        }
        int cur_pos=sz(p->l);
        if(key<=cur_pos)
        {
            split(p->l,key,l,p->l);
            r=p;
        }
        else
        {
            split(p->r,key-cur_pos-1,p->r,r);
            l=p;
        }
        update(p);
    }

    void merge(pnode &p,pnode l,pnode r)
    {
        push(l);
        push(r);
        if(!l || !r)
        {
            if(l)
                p=l;
            else
                p=r;
        }
        else if(l->prior>r->prior)
        {
            merge(l->r,l->r,r);
            p=l;
        }
        else
        {
            merge(r->l,l,r->l);
            p=r;
        }
        update(p);
    }

    ///0 means at the begining of the treap(array)
    void insert(T v,int pos)
    {
        pos=max(0,pos);
        pos=min(sz(root),pos);
        pnode it=new node(v);
        pnode l,r;
        split(root,pos,l,r);
        merge(l,l,it);
        merge(root,l,r);
    }

    void erase(int pos) { erase_interval(pos,pos); }

    void erase_interval(int l,int r)
    {
        if(l>r)
            swap(l,r);
        if(l<=0 || r>sz(root))
            return ;

        pnode pl,pr,_discard;
        split(root,l-1,pl,pr);
        split(pr,r-l+1,_discard,pr);
        merge(root,pl,pr);
    }

    void reverse(int l,int r)
    {
        pnode l1,r1,m;
        split(root,l-1,l1,r1);
        split(r1,r-l+1,m,r1);
        m->rev^=1;
        merge(r1,m,r1);
        merge(root,l1,r1);
    }

    ///intervals have to be disjoint and non-empty
    ///(both ends inclusive: [l1,r1]->[l2,r2])
    void swap_intervals(int l1,int r1,int l2,int r2)
    {
        if(l1>l2)
        {
            swap(l1,l2);
            swap(r1,r2);
        }
        pnode i1,i2;
        pnode m1,m2,m3;

        split(root,l1-1,m1,i1);
        split(i1,r1-l1+1,i1,m2);
        split(m2,l2-r1-1,m2,i2);
        split(i2,r2-l2+1,i2,m3);

        merge(m1,m1,i2);
        merge(m1,m1,m2);
        merge(m3,i1,m3);
        merge(root,m1,m3);
    }

    ///position has to exist(1<=i<=sz(root))
    T operator[](int i)
    {
        return find_kth(root,i);
    }

    T find_kth(pnode p,int k)
    {
        push(p);
        if(sz(p->l)<k-1)
            return find_kth(p->r,k-sz(p->l)-1);
        else if(sz(p->l)==k-1)
            return p->v;
        return find_kth(p->l,k);
    }
};

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

    int n,q,m,a;
    cin >> n >> q >> m;
    treap<int> t;
    for(int i=0;i<n;i++)
    {
        cin >> a;
        t.insert(a,i);
    }
    for(int i=0;i<q;i++)
    {
        int ty,l,r;
        cin >> ty >> l >> r;
        if(ty==1)
        {
            if(l==r)
                continue;
            t.swap_intervals(l,r-1,r,r);
        }
        if(ty==2)
            t.reverse(l,r);
    }

    for(int i=0;i<m;i++)
    {
        cin >> a;
        cout << t[a] << ' ';
    }
    cout << '\n';

    return 0;
}
/**
6 3 5
1 2 3 4 5 6
2 1 3
2 3 6
1 1 6
2 2 1 5 3
**/


#include <iostream>
#include <cstdio>
using namespace std;

const int N = 2e5;

struct query
{
    int type, l, r;
    void scan()
    {
        scanf("%d%d%d", &type, &l, &r);
    }
};

int a[N], b[100];
query q[N];

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input_cf.txt", "r", stdin);
#endif // ONLINE_JUDGE

    int n, Q, m;
    scanf("%d%d%d", &n, &Q, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    for (int i = 0; i < Q; ++i)
        q[i].scan();
    for (int i = 0; i < m; ++i)
        scanf("%d", b + i);

    for (int i = 0; i < Q; ++i)
    {
        if (q[i].type == 1)
        {
            for (int j = 0; j < m; ++j)
            {
                if (b[j] < q[i].l || b[j] > q[i].r)
                    continue;
                if (b[j] == q[i].r)
                    b[j] = q[i].l;
                else
                    ++b[j];
            }
        }
        else
        {
            for (int j = 0; j < m; ++j)
            {
                if (b[j] < q[i].l || b[j] > q[i].r)
                    continue;
                b[j] = q[i].l + q[i].r - b[j];
            }
        }
    }

    for (int i = 0; i < m; ++i)
        printf("%d ", a[b[i] - 1]);
}


#include <iostream>
using namespace std;

int a[200000];
void cycle(int l, int r);
void rev(int l, int r);

int main()
{
    int n, q, m;
    cin >> n >> q >> m;
    for (int i = 0; i < n; i++)
        cin >> a[i];

    int x, l, r;
    for (int i = 0; i < q; i++)
    {
        cin >> x >> l >> r;
        if (x == 1)
        {
            cycle(l, r);
        }
        if (x == 2)
        {
            rev(l, r);
        }
        /*for (int i = 0; i < n; i++)
            cout << a[i] << " ";
        cout << endl;*/
    }
    int* ans = new int[m];
    int b;
    for (int i = 0; i < m; i++)
    {
        cin >> b;
        ans[i] = a[b - 1];
    }
    for (int i = 0; i < m; i++)
        cout << ans[i] << " ";
    delete []a;
    delete []ans;
}

void cycle(int l, int r)
{
    l--;
    r--;
    int x = a[r];
    for (int i = r; i > l; i--)
        a[i] = a[i - 1];
    a[l] = x;
}

void rev(int l, int r)
{
    l--;
    r--;
    for (int i = l; i <= (l + r) / 2; i++)
        swap(a[i], a[r - (i - l)]);
}


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

const int N = 2e5;

struct query
{
    int type, l, r;
    void scan()
    {
        scanf("%d%d%d", &type, &l, &r);
        --l; --r;
    }
};

int a[N], id[100], b[100], ord[100];
query q[N];
bool used[N];

bool cmp(int i, int j)
{
    return id[i] > id[j];
}

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input_cf.txt", "r", stdin);
#endif // ONLINE_JUDGE

    int n, Q, m;
    scanf("%d%d%d", &n, &Q, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    for (int i = 0; i < Q; ++i)
        q[i].scan();
    for (int i = 0; i < m; ++i)
    {
        scanf("%d", id + i);
        --id[i];
        ord[i] = i;
    }

    sort(ord, ord + m, cmp);

    int l, r, valR;
    bool f;
    for (int i = 0; i < Q; ++i)
    {
        l = q[i].l; r = q[i].r;
        if (q[i].type == 1)
        {
            valR = a[r];
            f = false;
            for (int j = 0, k; j < m; ++j)
            {
                k = id[ord[j]];
                if (k < l || k > r)
                    continue;
                if (k == l)
                {
                    f = true;
                }
                else
                    a[k] = a[k - 1];
            }
            if (f)
                a[l] = valR;
        }
        else
        {
            for (int j = 0; j < m; ++j)
                used[id[j]] = false;
            for (int j = 0; j < m; ++j)
            {
                if (id[j] < l || id[j] > r || used[id[j]])
                    continue;
                swap(a[id[j]], a[l + r - id[j]]);
                used[id[j]] = true;
                used[l + r - id[j]] = true;
            }
        }
        /*
        for (int i = 0; i < m; ++i)
            printf("%d ", a[id[i]]);
        printf("\n");
        */
    }

    for (int i = 0; i < m; ++i)
        printf("%d ", a[id[i]]);
}


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

const int N = 2e5;

struct query
{
    int type, l, r;
    void scan()
    {
        scanf("%d%d%d", &type, &l, &r);
        --l; --r;
    }
};

int a[N], id[100], b[100], ord[100];
query q[N];
bool used[N];

bool cmp(int i, int j)
{
    return id[i] > id[j];
}

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input_cf.txt", "r", stdin);
#endif // ONLINE_JUDGE

    int n, Q, m;
    scanf("%d%d%d", &n, &Q, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    for (int i = 0; i < Q; ++i)
        q[i].scan();
    for (int i = 0; i < m; ++i)
    {
        scanf("%d", id + i);
        --id[i];
        ord[i] = i;
    }

    sort(ord, ord + m, cmp);

    int l, r, valR;
    bool f;
    for (int i = 0; i < Q; ++i)
    {
        l = q[i].l; r = q[i].r;
        if (q[i].type == 1)
        {
            valR = a[r];
            f = false;
            for (int j = 0, k; j < m; ++j)
            {
                k = id[ord[j]];
                if (k < l || k > r)
                    continue;
                if (k == l)
                {
                    f = true;
                }
                else
                    a[k] = a[k - 1];
            }
            if (f)
                a[l] = valR;
        }
        else
        {
            for (int j = 0; j < m; ++j)
                used[id[j]] = false;
            for (int j = 0; j < m; ++j)
            {
                if (id[j] < l || id[j] > r || used[id[j]])
                    continue;
                swap(a[id[j]], a[l + r - id[j]]);
                used[l + r - id[j]] = true;
            }
        }
        /*
        for (int i = 0; i < m; ++i)
            printf("%d ", a[id[i]]);
        printf("\n");
        */
    }

    for (int i = 0; i < m; ++i)
        printf("%d ", a[id[i]]);
}


#include <iostream>
using namespace std;

int n, q, m;
int* a = new int[n];
void cycle(int l, int r);
void rev(int l, int r);

int main()
{
    cin >> n >> q >> m;
    for (int i = 0; i < n; i++)
        cin >> a[i];

    int x, l, r;
    for (int i = 0; i < q; i++)
    {
        cin >> x >> l >> r;
        if (x == 1)
        {
            cycle(l, r);
        }
        else
        {
            rev(l, r);
        }
        /*for (int i = 0; i < n; i++)
            cout << a[i] << " ";
        cout << endl;*/
    }
    int* ans = new int[m];
    int b;
    for (int i = 0; i < m; i++)
    {
        cin >> b;
        ans[i] = a[b - 1];
    }
    for (int i = 0; i < m; i++)
        cout << ans[i] << " ";
}

void cycle(int l, int r)
{
    l--;
    r--;
    int x = a[r];
    for (int i = r; i > l; i--)
        a[i] = a[i - 1];
    a[l] = x;
}

void rev(int l, int r)
{
    l--;
    r--;
    for (int i = l; i <= (l + r) / 2; i++)
        swap(a[i], a[r - (i - l)]);
}


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

const int N = 2e5;

struct query
{
    int type, l, r;
    void scan()
    {
        scanf("%d%d%d", &type, &l, &r);
        --l; --r;
    }
};

int a[N], id[100];
query q[N];

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input_cf.txt", "r", stdin);
#endif // ONLINE_JUDGE

    int n, Q, m;
    scanf("%d%d%d", &n, &Q, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", a + i);
    for (int i = 0; i < Q; ++i)
        q[i].scan();
    for (int i = 0; i < m; ++i)
    {
        scanf("%d", id + i);
        --id[i];
    }

    int l, r;
    for (int i = Q - 1; i >= 0; --i)
    {
        l = q[i].l; r = q[i].r;
        if (q[i].type == 1)
        {
            for (int j = 0; j < m; ++j)
            {
                if (id[j] < l || id[j] > r)
                    continue;
                if (id[j] == l)
                    id[j] = r;
                else
                    --id[j];
            }
        }
        else
        {
            for (int j = 0; j < m; ++j)
            {
                if (id[j] < l || id[j] > r)
                    continue;
                id[j] = l + r - id[j];
            }
        }
        /*
        for (int i = 0; i < m; ++i)
            printf("%d ", a[id[i]]);
        printf("\n");
        */
    }

    for (int i = 0; i < m; ++i)
        printf("%d ", a[id[i]]);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
//#include<set>
//#include<map>
#include<queue>
//#include<iostream>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define dep(i,x,y) for(int i=x;i>=y;--i)
#define rev(it,v) for(vector<int>::iterator it=v.begin();it!=v.end();it++)
using namespace std;
#define N 100005
#define LL long long

int n,sn[N],nx[N<<1],ed[N<<1],x,y,f[N],sz[N];

void dfs(int x,int fa,int v){
	sz[x]=0;
	for(int j=sn[x];j;j=nx[j])
		if(ed[j]^fa){
			dfs(ed[j],x,v^1);
			sz[x]+=sz[ed[j]];
		}
	if(sz[x]==0){
		sz[x]=1;
		f[x]=1;
		return;
	}
	f[x]=sz[x];
	for(int j=sn[x];j;j=nx[j])
		if(ed[j]^fa){
			f[x]=min(f[x],sz[ed[j]]-f[ed[j]]+1);
		}
}

int main(){
	scanf("%d",&n);
	rep(i,2,n){
		scanf("%d%d",&x,&y);
		nx[i]=sn[x],sn[x]=i,ed[i]=y;
		nx[i+n]=sn[y],sn[y]=i+n,ed[i+n]=x;
	}
	if(n==1){
		puts("1 1");
		return 0;
	}
	dfs(1,0,0);
	//printf("%d\n",f[2]);
	int ans=0;
	for(int j=sn[1];j;j=nx[j]) ans+=sz[ed[j]]-f[ed[j]];
	printf("%d %d\n",sz[1]-f[1]+1,sz[1]-ans);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
//#include<set>
//#include<map>
#include<queue>
//#include<iostream>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define dep(i,x,y) for(int i=x;i>=y;--i)
#define rev(it,v) for(vector<int>::iterator it=v.begin();it!=v.end();it++)
using namespace std;
#define N 200005
#define LL long long

int n,sn[N],nx[N<<1],ed[N<<1],x,y,f[N],sz[N];

void dfs1(int x,int fa,int v){
	sz[x]=0;
	for(int j=sn[x];j;j=nx[j])
		if(ed[j]^fa){
			dfs1(ed[j],x,v^1);
			sz[x]+=sz[ed[j]];
		}
	if(sz[x]==0){
		sz[x]=1;
		f[x]=1;
		return;
	}
	if(v==0){

		f[x]=sz[x];
		for(int j=sn[x];j;j=nx[j])
			if(ed[j]^fa){
				f[x]=min(f[x],sz[ed[j]]-f[ed[j]]+1);
			}
	}else{
		int tot=0;
		for(int j=sn[x];j;j=nx[j])
			if(ed[j]^fa)
				tot+=sz[ed[j]]-f[ed[j]];
		f[x]=tot+1;
	}
}

int main(){
	scanf("%d",&n);
	rep(i,2,n){
		scanf("%d%d",&x,&y);
		nx[i]=sn[x],sn[x]=i,ed[i]=y;
		nx[i+n]=sn[y],sn[y]=i+n,ed[i+n]=x;
	}
	if(n==1){
		puts("1 1");
		return 0;
	}
	dfs1(1,0,0);
	printf("%d ",sz[1]-f[1]+1);
	dfs1(1,0,1);
	printf("%d\n",sz[1]-f[1]+1);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
//#include<set>
//#include<map>
#include<queue>
//#include<iostream>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define dep(i,x,y) for(int i=x;i>=y;--i)
#define rev(it,v) for(vector<int>::iterator it=v.begin();it!=v.end();it++)
using namespace std;
#define N 100005
#define LL long long

int n,sn[N],nx[N<<1],ed[N<<1],x,y,f[N],sz[N];

void dfs(int x,int fa,int v){
	sz[x]=0;
	for(int j=sn[x];j;j=nx[j])
		if(ed[j]^fa){
			dfs(ed[j],x,v^1);
			sz[x]+=sz[ed[j]];
		}
	if(sz[x]==0){
		sz[x]=1;
		f[x]=1;
		return;
	}
	f[x]=sz[x];
	for(int j=sn[x];j;j=nx[j])
		if(ed[j]^fa){
			f[x]=min(f[x],sz[ed[j]]-f[ed[j]]+1);
		}
}

int main(){
	scanf("%d",&n);
	rep(i,2,n){
		scanf("%d%d",&x,&y);
		nx[i]=sn[x],sn[x]=i,ed[i]=y;
		nx[i+n]=sn[y],sn[y]=i+n,ed[i+n]=x;
	}
	if(n==1){
		puts("1 1");
		return 0;
	}
	dfs(1,0,0);
	//printf("%d\n",f[1]);
	int ans=n;
	for(int j=sn[1];j;j=nx[j]) ans=min(ans,sz[1]-(sz[ed[j]]-f[ed[j]]+1)+1);
	printf("%d %d\n",sz[1]-f[1]+1,ans);
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
//#include<set>
//#include<map>
#include<queue>
//#include<iostream>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define dep(i,x,y) for(int i=x;i>=y;--i)
#define rev(it,v) for(vector<int>::iterator it=v.begin();it!=v.end();it++)
using namespace std;
#define N 200005
#define LL long long

int n,sn[N],nx[N<<1],ed[N<<1],x,y,f[N],sz[N];

void dfs(int x,int fa,int v){
	sz[x]=0;
	for(int j=sn[x];j;j=nx[j])
		if(ed[j]^fa){
			dfs(ed[j],x,v^1);
			sz[x]+=sz[ed[j]];
		}
	if(sz[x]==0){
		sz[x]=1;
		f[x]=1;
		return;
	}
	f[x]=sz[x];
	for(int j=sn[x];j;j=nx[j])
		if(ed[j]^fa){
			f[x]=min(f[x],sz[ed[j]]-f[ed[j]]+1);
		}
}

int main(){
	scanf("%d",&n);
	rep(i,2,n){
		scanf("%d%d",&x,&y);
		nx[i]=sn[x],sn[x]=i,ed[i]=y;
		nx[i+n]=sn[y],sn[y]=i+n,ed[i+n]=x;
	}
	if(n==1){
		puts("1 1");
		return 0;
	}
	dfs(1,0,0);
	//printf("%d\n",f[2]);
	int ans=0;
	for(int j=sn[1];j;j=nx[j]) ans+=sz[ed[j]]-f[ed[j]];
	printf("%d %d\n",sz[1]-f[1]+1,sz[1]-ans);
}


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

using namespace std;

vector<vector<int> > tree;
int firstmin[200100], firstmax[200100], secondmin[200100], secondmax[200100], leaf[200100], inf = 200100;
//first  tries to maximize the result
//second tries to minimize the result

void dfs(int u){
	if(tree[u].size() == 1 && u != 0){
		firstmin[u] = 1; secondmin[u] = 1;
		firstmax[u] = 1; secondmax[u] = 1;
		leaf[u] = 1;

		//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
		return;
	}

	int v;
	leaf[u] = 0;
	secondmax[u] = -1; secondmin[u] = inf;
	firstmin[u] = 1; firstmax[u] = -inf;
	for(int i = 0; i < tree[u].size(); i++){
		v = tree[u][i];
		if(leaf[v] == -1){
			dfs(v);
			leaf[u] += leaf[v];
			secondmax[u] = max(secondmax[u], firstmax[v]);
			secondmin[u] = min(secondmin[u], firstmin[v]);

			firstmin[u] = min(firstmin[u], secondmin[v] - leaf[v]);
			firstmax[u] = max(firstmax[u], secondmax[v] - leaf[v]);
		}
	}
	firstmin[u] += leaf[u];
	firstmax[u] += leaf[u];
	//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
	return;
}

int main(){
	int n, a, b;
	cin >> n;
	tree.assign(n, vector<int> () );
	for(int i = 0; i < n-1; i++){
		cin >> a >> b;
		tree[a-1].push_back(b-1);
		tree[b-1].push_back(a-1);
	}
	memset(leaf, -1, sizeof leaf);
	dfs(0);
	cout << firstmax[0] << ' ' << firstmin[0] << endl;

	return 0;
}


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

using namespace std;

vector<vector<int> > tree;
int firstmin[200100], firstmax[200100], secondmin[200100], secondmax[200100], leaf[200100], inf = 200100;
//first  tries to maximize the result
//second tries to minimize the result

void dfs(int u){
	if(tree[u].size() == 0){
		firstmin[u] = 1; secondmin[u] = 1;
		firstmax[u] = 1; secondmax[u] = 1;
		leaf[u] = 1;

		//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
		return;
	}

	int v;
	leaf[u] = 0;
	secondmax[u] = -1; secondmin[u] = inf;
	firstmin[u] = 1; firstmax[u] = -inf;
	for(int i = 0; i < tree[u].size(); i++){
		v = tree[u][i];
		dfs(v);
		leaf[u] += leaf[v];
		secondmax[u] = max(secondmax[u], firstmax[v]);
		secondmin[u] = min(secondmin[u], firstmin[v]);

		firstmin[u] = min(firstmin[u], secondmin[v] - leaf[v]);
		firstmax[u] = max(firstmax[u], secondmax[v] - leaf[v]);
	}
	firstmin[u] += leaf[u];
	firstmax[u] += leaf[u];
	//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
	return;
}

int main(){
	int n, a, b;
	cin >> n;
	tree.assign(n, vector<int> () );
	for(int i = 0; i < n-1; i++){
		cin >> a >> b;
		tree[a-1].push_back(b-1);
	}
	memset(leaf, -1, sizeof leaf);
	dfs(0);
	cout << firstmax[0] << ' ' << firstmin[0] << endl;

	return 0;
}


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

using namespace std;

vector<vector<int> > tree;
int firstmin[200100], firstmax[200100], secondmin[200100], secondmax[200100], leaf[200100], inf = 200100;
//first  tries to maximize the result
//second tries to minimize the result

void dfs(int u){
	if(tree[u].size() == 0){
		firstmin[u] = 1; secondmin[u] = 1;
		firstmax[u] = 1; secondmax[u] = 1;
		leaf[u] = 1;

		//cout << u+1 << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
		return;
	}

	int v;
	leaf[u] = 0;
	secondmax[u] = 0; secondmin[u] = inf;
	firstmin[u] = 0; firstmax[u] = -inf;
	for(int i = 0; i < tree[u].size(); i++){
		v = tree[u][i];
		dfs(v);
		leaf[u] += leaf[v];
		secondmax[u] += firstmax[v]-1;
		secondmin[u] = min(secondmin[u], firstmin[v]);

		firstmin[u] -= secondmin[v] - leaf[v];
		firstmax[u] = max(firstmax[u], secondmax[v] - leaf[v]);
	}
	secondmax[u]++;
	firstmax[u] += leaf[u];
	firstmin[u] = leaf[u]-firstmin[u];
	//cout << u+1 << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
	return;
}

int main(){
	int n, a, b;
	cin >> n;
	tree.assign(n, vector<int> () );
	for(int i = 0; i < n-1; i++){
		cin >> a >> b;
		tree[a-1].push_back(b-1);
	}
	memset(leaf, -1, sizeof leaf);
	dfs(0);
	cout << firstmax[0] << ' ' << firstmin[0] << endl;

	return 0;
}


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

using namespace std;

vector<vector<int> > tree;
int firstmin[200100], firstmax[200100], secondmin[200100], secondmax[200100], leaf[200100], inf = 200100;
//first  tries to maximize the result
//second tries to minimize the result

void dfs(int u){
	if(tree[u].size() == 1 && u != 0){
		firstmin[u] = 1; secondmin[u] = 1;
		firstmax[u] = 1; secondmax[u] = 1;
		leaf[u] = 1;

		//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
		return;
	}

	int v;
	leaf[u] = 0;
	secondmax[u] = -1; secondmin[u] = inf;
	firstmin[u] = 1; firstmax[u] = -inf;
	for(int i = 0; i < tree[u].size(); i++){
		v = tree[u][i];
		if(leaf[v] == -1){
			dfs(v);
			leaf[u] += leaf[v];
			secondmax[u] = max(secondmax[u], firstmax[v]);
			secondmin[u] = min(secondmin[u], firstmin[v]);

			firstmin[u] = min(firstmin[u], secondmin[v] - leaf[v]);
			firstmax[u] = max(firstmax[u], secondmax[v] - leaf[v]);
		}
	}
	firstmin[u] += leaf[u];
	firstmax[u] += leaf[u];
	//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
	return;
}

int main(){
	int n, a, b;
	cin >> n;
	if(n == 1){
		cout << 1 << ' ' << 1 << endl;
		return 0;
	}
	tree.assign(n, vector<int> () );
	for(int i = 0; i < n-1; i++){
		cin >> a >> b;
		tree[a-1].push_back(b-1);
		tree[b-1].push_back(a-1);
	}
	memset(leaf, -1, sizeof leaf);
	dfs(0);
	cout << firstmax[0] << ' ' << firstmin[0] << endl;

	return 0;
}


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

using namespace std;

vector<vector<int> > tree;
int firstmin[200100], firstmax[200100], secondmin[200100], secondmax[200100], leaf[200100], inf = 200100;
//first  tries to maximize the result
//second tries to minimize the result

void dfs(int u){
	if(tree[u].size() == 1 && u != 0){
		firstmin[u] = 1; secondmin[u] = 1;
		firstmax[u] = 1; secondmax[u] = 1;
		leaf[u] = 1;

		//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
		return;
	}

	int v;
	leaf[u] = 0;
	secondmax[u] = -1; secondmin[u] = inf;
	firstmin[u] = 1; firstmax[u] = -inf;
	for(int i = 0; i < tree[u].size(); i++){
		v = tree[u][i];
		if(leaf[v] == -1){
			dfs(v);
			leaf[u] += leaf[v];
			secondmax[u] = max(secondmax[u], firstmax[v]);
			secondmin[u] = min(secondmin[u], firstmin[v]);

			firstmin[u] = min(firstmin[u], secondmin[v] - leaf[v]);
			firstmax[u] = max(firstmax[u], secondmax[v] - leaf[v]);
		}
	}
	firstmin[u] += leaf[u];
	firstmax[u] += leaf[u];
	//cout << u << ' ' << firstmin[u] << ' ' << secondmin[u] << ' ' << firstmax[u]  << ' ' <<  secondmax[u] << endl;
	return;
}

int main(){
	int n, a, b;
	cin >> n;
	if(n == 1) cout << 1 << ' ' << 1 << endl;
	tree.assign(n, vector<int> () );
	for(int i = 0; i < n-1; i++){
		cin >> a >> b;
		tree[a-1].push_back(b-1);
		tree[b-1].push_back(a-1);
	}
	memset(leaf, -1, sizeof leaf);
	dfs(0);
	cout << firstmax[0] << ' ' << firstmin[0] << endl;

	return 0;
}


#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=200000+10;
int f[maxn];
int h[maxn],go[maxn],next[maxn],d[maxn];
int i,j,k,l,r,mid,t,n,m,tot;
void add(int x,int y){
	d[x]++;
	if (d[x]==1) m--;
	go[++tot]=y;
	next[tot]=h[x];
	h[x]=tot;
}
void solve1(int x,int y){
	int t=h[x];
	f[x]=0;
	if (!t) f[x]=1;
	else{
		while (t){
			solve1(go[t],1-y);
			if (y) f[x]+=f[go[t]];
			else if (!f[x]||f[go[t]]<f[x]) f[x]=f[go[t]];
			t=next[t];
		}
	}
}
void solve2(int x,int y){
	int t=h[x];
	f[x]=0;
	if (!t) f[x]=1;
	else{
		while (t){
			solve2(go[t],1-y);
			if (!y) f[x]+=f[go[t]];
			else if (!f[x]||f[go[t]]<f[x]) f[x]=f[go[t]];
			t=next[t];
		}
	}
}
bool check1(int ans){
	solve1(1,0);
	if (f[1]<=n-ans+1) return 1;else return 0;
}
bool check2(int ans){
	solve2(1,0);
	if (f[1]<=ans) return 1;else return 0;
}
int main(){
	scanf("%d",&n);
	m=n;
	fo(i,1,n-1){
		scanf("%d%d",&j,&k);
		add(j,k);
	}
	l=1;r=m;
	while (l<r){
		mid=(l+r+1)/2;
		if (check1(mid)) l=mid;else r=mid-1;
	}
	printf("%d ",l);
	l=1;r=m;
	while (l<r){
		mid=(l+r)/2;
		if (check2(mid)) r=mid;else l=mid+1;
	}
	printf("%d\n",l);
}


#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=200000+10;
int f[maxn],d[maxn],h[maxn],go[maxn],next[maxn];
int i,j,k,l,r,mid,n,m,ans,tot;
void add(int x,int y){
    go[++tot]=y;
    next[tot]=h[x];
    h[x]=tot;
}
void dfs(int x){
    int t=h[x];
    if (!t){
        m++;
        return;
    }
    while (t){
        d[go[t]]=d[x]+1;
        dfs(go[t]);
        t=next[t];
    }
}
void dg(int x){
    int t=h[x];
    if (!t){
        f[x]=1;
        return;
    }
    if (d[x]%2==0){
        f[x]=m+1;
        while (t){
            dg(go[t]);
            f[x]=min(f[x],f[go[t]]);
            t=next[t];
        }
    }
    else{
        f[x]=0;
        while (t){
            dg(go[t]);
            f[x]+=f[go[t]];
            t=next[t];
        }
    }
}
void dg2(int x){
    int t=h[x];
    if (!t){
        f[x]=1;
        return;
    }
    if (d[x]%2==1){
        f[x]=m+1;
        while (t){
            dg2(go[t]);
            f[x]=min(f[x],f[go[t]]);
            t=next[t];
        }
    }
    else{
        f[x]=0;
        while (t){
            dg2(go[t]);
            f[x]+=f[go[t]];
            t=next[t];
        }
    }
}
int main(){
    scanf("%d",&n);
    fo(i,1,n-1){
        scanf("%d%d",&j,&k);
        add(j,k);
    }
    dfs(1);
    dg(1);
    printf("%d ",m-f[1]+1);
    dg2(1);
    printf("%d\n",f[1]);
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,tot - sz[v] + dp[v][0]);
		}
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,tot - sz[v] + dp[v][0]);
		}
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	if (n == 230) cout <<"!! "<<sz[1]<<endl;
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	if (!G[x].size()){
		dp[x][id] = 1; return;
	}
	if (id){
		int cnt = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			dfs(v,0);
			cnt += dp[v][0];
		}
		dp[x][id] = cnt;
	}else{
		int MIN = 0x7ffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}
}
int main()
{
	for (int i = 0;i < maxn;i++) G[i].clear();
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b);
	}
	int leaves = 0,root;
	for (int i = 1;i <= n;i++){
		if (!G[i].size()) leaves++;
		if (G[i].size()) root = i;
	}
	dfs(1,0); dfs(1,1);
	printf("%d %d\n",leaves - dp[1][0] + 1,dp[1][1]);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	if (!G[x].size()){
		sz[x] = dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = 0,tot = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (dp[v][1] == -1) dfs(v,1);
			tot += sz[v];
		}
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX + G[x].size() - 1;
	}else{
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (dp[v][0] == -1) dfs(v,0);
			MIN = min(MIN,dp[v][0]);
		}
		dp[x][id] = MIN;
	}
	for (int i = 0;i < G[x].size();i++){
		sz[x] += sz[G[x][i]];
	}
}

int main()
{
	for (int i = 0;i < maxn;i++) G[i].clear();
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b);
	}
        if (n == 1){
cout<<"1 1"<<endl;
return 0;
}
	memset(sz,0,sizeof(sz));
	int root,leaves = 0;
	for (int i = 1;i <= n;i++)
		if (!G[i].size()) leaves++;
	for (int i = 1;i <= n;i++)
		if (G[i].size()){
			root = i;
			break;
		}
	memset(dp,-1,sizeof(dp));
	dfs(root,1);
	memset(sz,0,sizeof(sz));
	dfs(root,0);
	printf("%d %d\n",leaves - dp[root][1] + 1,dp[root][0]);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
			MAX = max(MAX,dp[v][0]);
		}
		dp[x][id] = MAX + G[x].size() - 2;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
		MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,tot - sz[v] + dp[v][0]);
		}
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	if (!G[x].size()){
		sz[x] = dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = 0,tot = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (dp[v][1] == -1) dfs(v,1);
			tot += sz[v];
		}
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX + G[x].size() - 1;
	}else{
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (dp[v][0] == -1) dfs(v,0);
			MIN = min(MIN,dp[v][0]);
		}
		dp[x][id] = MIN;
	}
	for (int i = 0;i < G[x].size();i++){
		sz[x] += sz[G[x][i]];
	}
}

int main()
{
	for (int i = 0;i < maxn;i++) G[i].clear();
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b);
	}
	memset(sz,0,sizeof(sz));
	int root,leaves = 0;
	for (int i = 1;i <= n;i++)
		if (!G[i].size()) leaves++;
	for (int i = 1;i <= n;i++)
		if (G[i].size()){
			root = i;
			break;
		}
	memset(dp,-1,sizeof(dp));
	dfs(root,1);
	memset(sz,0,sizeof(sz));
	dfs(root,0);
	printf("%d %d\n",leaves - dp[root][1] + 1,dp[root][0]);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,tot - sz[v] + dp[v][0]);
		}
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	if (n == 230) cout << "!! "<<dp[4][1]<<endl;
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	if (n == 230) cout <<"!!! "<<dp[4][1] <<endl;
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			MAX = max(MAX,tot - sz[v] + dp[v][0]);
		}
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
			MAX = max(MAX,dp[v][0]);
		}
		dp[x][id] = MAX + G[x].size() - 2;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 200000 + 10;
#define pb push_back
vector<int> G[maxn];
int n;
int sz[maxn],vis[maxn];
int dp[maxn][3];
void dfs(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MIN = 0x7fffffff;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs(v,1);
			MIN = min(MIN,dp[v][1]);
		}
		dp[x][id] = MIN;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs(v,0);
			MAX = max(MAX,dp[v][0]);
		}
		dp[x][id] = MAX + G[x].size() - 1;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
void dfs1(int x,int id){
	vis[x] = 1;
	if (x != 1 && G[x].size() == 1){
		sz[x] = 1;
		dp[x][id] = 1;
		return;
	}
	if (id == 0){
		int MAX = -1;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][1] == -1) dfs1(v,1);
			MAX = max(MAX,dp[v][1]);
		}
		dp[x][id] = MAX;
	}else if (id == 1){
		int MAX = 0;
		for (int i = 0;i < G[x].size();i++){
			int v = G[x][i];
			if (vis[v]) continue;
			if (dp[v][0] == -1) dfs1(v,0);
		}
		int tot = 0;
		for (int i = 0;i < G[x].size();i++)
			tot += sz[G[x][i]];
		for (int i = 0; i < G[x].size();i++)
			MAX = max(MAX,dp[G[x][i]][0] + tot - sz[G[x][i]]);
		dp[x][id] = MAX;
	}
	for (int i = 0;i < G[x].size();i++)
		sz[x] += sz[G[x][i]];
}
int main()
{
	scanf("%d",&n);
	for (int i = 1;i < n;i++){
		int a,b; scanf("%d%d",&a,&b);
		G[a].pb(b); G[b].pb(a);
	}
	if (n == 1){
		cout <<"1 1"<<endl;
		return 0;
	}
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs(1,0);
	printf("%d ",sz[1] - dp[1][0] + 1);
	memset(sz,0,sizeof(sz));
	memset(dp,-1,sizeof(dp));
	memset(vis,0,sizeof(vis));
	dfs1(1,0);
	printf("%d\n",sz[1] - dp[1][0] + 1);
	return 0;
}