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 <vector>
#include <algorithm>
using namespace std;

struct DOLL{
	int h;
	int r;
};

int f(vector<DOLL> &d1, vector<DOLL> &d2, int h, int r)
{
	int ans = 0;
	for (DOLL &d : d1){
		if (d.h>h && d.r>r){
			int a = f(d1, d2, d.h, d.r)+1;
			ans = max(a,ans);
			break;
		}
	}
	for (DOLL &d : d2){
		if (d.h>h && d.r>r){
			int a = f(d1, d2, d.h, d.r)+1;
			ans = max(a,ans);
			break;
		}
	}
	return ans;
}

int main() {

	while (true){
		vector<DOLL> d1;
		vector<DOLL> d2;
		int n,m;

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

		for (int i = 0; i<n; i++){
			DOLL d;
			cin >> d.h >> d.r;
			d1.push_back(d);
		}

		cin >> m;

		for (int i = 0; i<m; i++){
			DOLL d;
			cin >> d.h >> d.r;
			d2.push_back(d);
		}

		int ans = f(d1, d2, 0, 0);
		cout << ans << endl;
	}

	return 0;
}

C++: #include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <string>
#include <bitset>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <sstream>
#include <fstream>
//#include <tuple>
#include <set>
#include <string.h>
#include <functional>

#define X first
#define Y second
#define MP make_pair
//#define MT make_tuple
#define REP(i, a, n) for(int (i) = (a); (i) < (n); ++(i))
#define FOR(i, n) REP(i, 0, n)
typedef long long ll;
using namespace std;
const int MAX = 101;

template<class T, class U>
void convert(T &t, U &u){
	stringstream ss;
	ss << t;
	ss >> u;
}

class a
{
public:

};

int count(vector<pair<int, int> >& a)
{
	int ans = 0;
	pair<int, int> tmp;
	FOR(i, a.size()){
		if (i){
			if (tmp.first > a[i].first){
				if (tmp.second > a[i].second){
					tmp = a[i];
					ans++;
				}
			}
		}
		else tmp = a[i], ans++;
	}

	return ans;
}

int main()
{

	int n;
	while (cin >> n && n){
		vector<pair<int, int> > a, b;
		FOR(i, n){
			int s, t; cin >> s >> t;
			a.push_back( MP( s, t ) );
			b.push_back( MP( t, s ) );
		}

		int m; cin >> m;
		FOR(i, m){
			int s, t; cin >> s >> t;
			a.push_back( MP( s, t ) );
			b.push_back( MP( t, s ) );
		}

		sort( a.begin(), a.end(), greater<pair<int, int> >() );
		sort( b.begin(), b.end(), greater<pair<int, int> >() );
		cout << max( count( a ), count( b ) ) << endl;
	}

	return 0;
}

C++: #define _USE_MATH_DEFINES
#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>

using namespace std;

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

static const double eps = 10e-8;

class mycmp{
public:
	bool operator()(const P p1, const P p2){
		if(p1.first < p2.first) return true;
		else if(p1.second < p2.second) return true;
		else false;
	}
};

int main(){
	int n;

	while(~scanf("%d",&n)){
		if(n==0) break;
		vector<P> dolls;

		for(int i=0;i<n;i++){
			int h,r;
			scanf("%d %d",&h,&r);
			dolls.push_back(P(h,r));
		}

		int m;
		scanf("%d",&m);
		for(int i=0;i<m;i++){
			int h,r;
			scanf("%d %d",&h,&r);
			dolls.push_back(P(h,r));
		}


		sort(dolls.begin(),dolls.end());

		int* dp = new int[n+m];
		memset(dp,0,sizeof(dp));
		for(int i=0;i<n+m;i++) dp[i] = 1;

		for(int i=0;i<dolls.size();i++){
			for(int j=0;j<dolls.size();j++){
				if(dolls[j].first < dolls[i].first
					&& dolls[j].second < dolls[i].second){
						dp[i] = max(dp[i],dp[j] + 1);
				}
			}
		}

		cout << dp[dolls.size()-1] << endl;
		delete[] dp;
	}
}

C++: #include <vector>
#include <algorithm>
#include <cstdio>
int x[100001],d[100001],c[100001];

int lis(int n){
	int i,j,I;
/*
	for(i=-1;I=0,++i<n;d[i]=I+1)
		for(j=i-1;~j;j--)
			if(x[j]<x[i]&&I<d[j])I=d[j];
*/
	// http://stackoverflow.com/questions/6129682/longest-increasing-subsequenceonlogn
	int sz = 1;
	c[1] = x[0];
	d[0] = 1;
	for(i=0;++i<n;){
		if(x[i] < c[1]){
			c[1] = x[i];
			d[i] = 1;
		}else if(x[i] > c[sz]){
			c[sz+1] = x[i];
			d[i] = sz+1;
			sz++;
		}else{
			int k = std::lower_bound(c,c+sz,x[i])-c;
			c[k] = x[i];
			d[i] = k;
		}
	}
	for(i=j=0;i<n;i++)
		if(d[i]>d[j])j=i;
	return d[j];
}

int n;
int main(){
	for(;;){
		n=0;
		std::vector<std::pair<int,int>>v;
		int a,b;
		for(int k=0;k<2;k++){
			int n0;
			if((!~scanf("%d",&n0)||!n0) && k==0)return 0;
			for(n+=n0;n0--;){
				scanf("%d%d",&a,&b);
				v.emplace_back(a,-b);
			}
		}
		std::sort(v.begin(),v.end());
		for(int i=0;i<n;i++)x[i]=-v[i].second;
		printf("%d\n",lis(n));
	}
}

C++: #include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;

int main(){
	int n[2],c[2];
	while(cin>>n[0],n[0]){
		int h[2][110],r[2][110],mx[2][110];
		rep(q,2){
			rep(i,n[q])mx[q][i]=0,cin>>h[q][i]>>r[q][i];
			if(!q)cin>>n[1];
		}
		mx[0][0]=(h[0][0]>h[1][0]&&r[0][0]>r[1][0])+1;
		mx[1][0]=(h[0][0]<h[1][0]&&r[0][0]<r[1][0])+1;
		int p;
		c[0]=c[1]=p=0;
		while(c[0]<n[0]||c[1]<n[1]){
			int tmax=0,f;
			rep(k,2){
				rep(i,n[k]){
					f=h[k][i]<h[p][c[p]]&&r[k][i]<r[p][c[p]];
					if(f&&tmax<mx[k][i])tmax=mx[k][i];
					if((f&&!mx[k][i])||c[p]==n[p]){
						p^=1;
						goto NEXT;
					}
				}
			}
			mx[p][c[p]++]=tmax+1;
			NEXT:;
		}
		cout<<max(mx[0][n[0]-1],mx[1][n[1]-1])<<endl;
	}
	return 0;
}

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

struct Doll{
  int h,r;
  Doll(int a,int b){h=a;r=b;};
};

int n;
int h,r;
int m;
vector<Doll>doll;
int memo[201]={0};

bool comp(Doll a, Doll b){return a.h<b.h && a.r<b.r;};

int rec(int id)
{
  if(memo[id]!=0)return memo[id];

  int ans=0;
  for(int i=0;i<n+m;i++){
    if(comp(doll[i],doll[id]))ans=max(rec(i)+1,ans);
  }

  return memo[id]=ans;
}

int main()
{
  while(cin>>n,n){
    doll.clear();
    for(int i=0;i<200;i++)memo[i]=0;

    for(int i=0;i<n;i++){
      cin>>h>>r;
      doll.push_back(Doll(h,r));
    }
    cin>>m;
    for(int i=0;i<m;i++){
      cin>>h>>r;
      doll.push_back(Doll(h,r));
    }

    doll.push_back(Doll(1001,1001));

    cout<<rec(n+m)<<endl;
  }
}

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

typedef pair<int,int> pii;

int main(){
	int n, h, r;
	const int INF = 1 << 30;
	while(1){
		vector<pii> v;
		for(int i = 0; i < 2; ++i){
			if(scanf("%d", &n) == EOF){ return 0; }
			for(int j = 0; j < n; ++j){
				scanf("%d%d", &h, &r);
				v.push_back(pii(h, -r));
			}
		}
		sort(v.begin(), v.end());

		vector<int> dp(v.size() + 1, INF);
		for(int i = 0; i < v.size(); ++i){
			r = -v[i].second;
			*lower_bound(dp.begin(), dp.end(), r) = r;
		}
		printf("%d\n", lower_bound(dp.begin(), dp.end(), INF) - dp.begin());
	}
}