Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"sort"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		n, _ := strconv.Atoi(scanner.Text())
		if n == 0 {
			break
		}
		hr := make([]entry, 0)
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf := strings.Split(scanner.Text(), " ")
			first, _ := strconv.Atoi(buf[0])
			second, _ := strconv.Atoi(buf[1])
			mt := entry{first, second}
			hr = append(hr, mt)
		}
		scanner.Scan()
		m, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < m; i++ {
			scanner.Scan()
			buf := strings.Split(scanner.Text(), " ")
			first, _ := strconv.Atoi(buf[0])
			second, _ := strconv.Atoi(buf[1])
			mt := entry{first, second}
			hr = append(hr, mt)
		}
		sort.Sort(ByFirst(hr))
		fmt.Println(LIS(hr))
	}
}

type entry struct {
	first, second int
}

type ByFirst []entry

func(f ByFirst) Len() int {
	return len(f)
}

func (f ByFirst) Swap(i, j int) {
	f[i], f[j] = f[j], f[i]
}

func (f ByFirst) Less(i, j int) bool {
	return f[i].first < f[j].first
}

func LIS(hr []entry) int {
	n := len(hr)
	lis := make([]int, n)
	lis[n-1] = 1
	for i := n-2; i > -1; i-- {
		m := 0
		for j := i+1; j < n; j++ {
			if hr[i].first < hr[j].first && hr[i].second < hr[j].second && lis[j] > m {
				m = lis[j]
			}
		}
		lis[i] = m+1
	}
	return lis[0]
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
using namespace std;


class doll;


int n, m;
vector<doll> d;
vector<int> dp = { 0 };


class doll{
public:
	int h;
	int r;
	doll(int h, int r) : h(h), r(r){}
	int operator[](char member){
		if (member == 'h') return h;
		else if(member == 'r') return r;
		else return -1;
	}
};


int solve(char member){
	dp[0] = d[0][member];
	for (int i = 1; i < d.size(); i++){
		if (dp.back() < d[i][member]){
			dp.push_back(d[i][member]);
		}
		else{
			*lower_bound(dp.begin(), dp.end(), d[i][member]) = d[i][member];
		}
	}
	return dp.size();
}


template<typename T>
void clear(vector<T>& v){
	vector<T> emp;
	swap(v, emp);
}


int main(){
	while (cin >> n, n != 0){
		for (int i = 0; i < n; i++){
			int h, r;
			cin >> h >> r;
			d.push_back({ h, r });
		}
		cin >> m;
		for (int i = n; i < n + m; i++){
			int h, r;
			cin >> h >> r;
			d.push_back({ h, r });
		}

		sort(d.begin(), d.end(), [](doll& d1, doll& d2){
			return (d1.h < d2.h);
		});

		int ans = solve('r');

		cout << ans << endl;

		clear(d);
		clear(dp);
		dp.push_back(0);
	}

	return 0;
}

C++: #include <iostream>
using namespace std;

#define REP(i,n,m) for(int i=n;i<m;i++)
#define rep(i,n) REP(i,0,n)

typedef struct{
	int h,r;
}Doll;

int main(void){
	int n,m;
	Doll t[200];

	while(cin>>n && n){
		rep(i,n) cin>>t[i].h>>t[i].r;
		cin>>m;
		REP(i,n,n+m) cin>>t[i].h>>t[i].r;

		n += m;

		rep(i,n-1)REP(j,i+1,n){
			if(t[i].h < t[j].h || t[i].h == t[j].h && t[i].r < t[j].r){
				Doll tmp = t[i];
				t[i] = t[j];
				t[j] = tmp;
			}
		}

		int ans = 0;
		rep(i,n){
			int sum = 1;
			Doll now = t[i];

			REP(j,i+1,n){
				if(now.h > t[j].h && now.r > t[j].r){
					now = t[j];
					sum++;
				}
			}

			ans = max(ans,sum);
		}

		cout<<ans<<endl;
	}

	return 0;
}

C++: #include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Matryoshka{
public:
  int h;
  int r; 

};

bool LessMatryoshka(const Matryoshka &a, const Matryoshka &b){
  if( a.h < b.h && a.r < b.r ){
    return true;
  }else if( a.h == b.h ){
    return true;
  }else{
    return false;
  }
} 

typedef vector< Matryoshka > Dolls;

void MaxSubSequenceLength( Dolls &d, vector< int > &ans ){
  ans[0] = 0;
  for(int i = 1; i < d.size(); i++){
    int maxSub = 0, maxj = -1;
    for(int j = i - 1; j >= 0; j--){
      if( d[j].r < d[i].r && d[j].h < d[i].h ){
	if( maxSub < ans[j] ){
	  maxj = j;
	  maxSub = ans[j];
	}
      }
    }
    if( maxj < 0 ){
      ans[i] = 1;
    }else{
      ans[i] = ans[maxj] + 1;
    }
  }
}

void InputMatryoshka( Dolls &d, int num ){
  for(int i = 0; i < num; i++){
    Matryoshka m;
    
    cin >> m.h;
    cin >> m.r;
    d.push_back( m );
  }
}

int main(void){
  while( 1 ){
    int n, m;
    Dolls dolls;
    Matryoshka matryoBanpei;
    int maxMatryoshkaNum = 0;
    vector<int> ans;

    cin >> n;
    if( n == 0 ){
      break;
    }

    matryoBanpei.h = -1;
    matryoBanpei.r = -1;
    dolls.push_back( matryoBanpei );
    
    InputMatryoshka( dolls, n );

    cin >> m;
    InputMatryoshka( dolls, m );

    sort( dolls.begin(), dolls.end(), LessMatryoshka );
    ans.resize( n+m+1, 0 );
    MaxSubSequenceLength( dolls, ans );

    //output
    for(int i = 0; i < ans.size(); i++){
      maxMatryoshkaNum = max( maxMatryoshkaNum, ans[i] );
    }
    cout << maxMatryoshkaNum << '\n';
  }
  return 0;
}

C++: #include <iostream>
using namespace std;

#define REP(i,n,m) for(int i=n;i<m;i++)
#define rep(i,n) REP(i,0,n)

typedef struct{
	int h,r;
}Doll;

int main(void){
	int n,m;
	Doll t1[200],t2[200];

	while(cin>>n && n){
		rep(i,n){
			cin>>t1[i].h>>t1[i].r;
			t2[i] = t1[i];
		}
		cin>>m;
		REP(i,n,n+m){
			cin>>t1[i].h>>t1[i].r;
			t2[i] = t1[i];
		}

		n += m;

		rep(i,n-1)REP(j,i+1,n){
			if(t1[i].h < t1[j].h || t1[i].h == t1[j].h && t1[i].r < t1[j].r){
				Doll tmp = t1[i];
				t1[i] = t1[j];
				t1[j] = tmp;
			}
			if(t2[i].r < t2[j].r || t2[i].r == t2[j].r && t2[i].h < t2[j].h){
				Doll tmp = t2[i];
				t2[i] = t2[j];
				t2[j] = tmp;
			}
		}

		int ans = 0;
		//ツ開ツ始ツ暗環置
		rep(i,n){
			int sum = 1;
			Doll now = t1[i];

			rep(j,n){
				if(now.h > t2[j].h && now.r > t2[j].r){
					now = t2[j];
					rep(k,n) if(now.h > t1[k].h && now.r > t1[k].r){
						now = t1[k];
						sum++;
						break;
					}
					sum++;
				}
			}

			ans = max(ans,sum);
		}

		cout<<ans<<endl;
	}

	return 0;
}

C++: #include<iostream>
#include<utility>
#include<algorithm>
using namespace std;
#define INF (1<<29)



pair<int,int> doll[200];
int dp[200];


int main(){
	int n,m;
	while(cin>>n&&n){
		for(int	i=0;i<n;i++)cin>>doll[i].first>>doll[i].second;
		cin>>m;
		for(int i=0;i<m;i++)cin>>doll[n+i].first>>doll[n+i].second;
		sort(doll,doll+n+m);
		for(int i=0;i<n+m;i++)dp[i]=1;
		for(int i=0;i<n+m;i++){
			for(int j=i+1;j<n+m;j++){
				if(doll[i].first<doll[j].first && doll[i].second<doll[j].second){
					dp[j]=max(dp[j],dp[i]+1);
				}
			}
		}
		cout<<*max_element(dp,dp+n+m)<<endl;
	}
	return 0;
}

C++: #include<bits/stdc++.h>
#define rep(i,n)for(int i=0;i<n;i++)
using namespace std;
typedef pair<int, int>P;

P v1[200], v2[200];
bool used1[200], used2[200];
int main() {
	int n;
	while (scanf("%d", &n), n) {
		memset(used1, 0, sizeof(used1));
		memset(used2, 0, sizeof(used2));
		rep(i, n) {
			int h, r; scanf("%d%d", &h, &r);
			v1[i] = P(h, r);
		}
		int m; scanf("%d", &m);
		rep(i, m) {
			int h, r; scanf("%d%d", &h, &r);
			v2[i] = P(h, r);
		}
		sort(v1, v1 + n);
		sort(v2, v2 + m);
		v1[n] = v2[n] = P(2000, 2000);
		int cnt1 = 0;
		rep(i, n + 1) {
			rep(j, m) {
				if ((!i || (v1[i - 1].first < v2[j].first&&v1[i - 1].second < v2[j].second)) &&
					v2[j].first < v1[i].first&&v2[j].second < v1[i].second && !used1[j]) {
					used1[j] = true;
					cnt1++;
				}
			}
		}
		int cnt2 = 0;
		rep(i, m + 1) {
			rep(j, n) {
				if ((!i || (v2[i - 1].first < v1[j].first&&v2[i - 1].second < v2[j].second)) &&
					v1[j].first < v2[i].first&&v1[j].second < v2[i].second && !used2[j]) {
					used2[j] = true;
					cnt2++;
				}
			}
		}
		printf("%d\n", max(cnt1 + n, cnt2 + m));
	}
}