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 <bits/stdc++.h>
struct Matr {
    int h;
    int r;
};

int solve(Matr const &prev, std::vector<Matr> const &A, int n) {
    int ret = n;
    for (auto &x: A) {
        if (prev.h < x.h && prev.r < x.r) {
            int tmp = solve(x, A, n+1);
            if (tmp > ret) ret = tmp;
        }
    }
    return ret;
}

int main(void)
{
    while (true) {
        int n, m;
        std::cin >> n;
        if (n == 0) break;
        std::vector<Matr> I(n);
        for (int i = 0; i < n; i++) {
            int h, r;
            std::cin >> h >> r;
            I[i] = {h, r};
        }
        assert(I.size() == n);
        std::cin >> m;
        std::vector<Matr> J(m);
        for (int i = 0; i < m; i++) {
            int h, r;
            std::cin >> h >> r;
            J[i] = {h, r};
        }
        assert(J.size() == m);

        std::vector<Matr> A; A.reserve(n+m);
        std::copy(I.begin(), I.end(), std::back_inserter(A));
        std::copy(J.begin(), J.end(), std::back_inserter(A));

        assert(A.size() == n+m);

        int max_k = 0;
        for (int i = 0; i < n+m; i++) {
            int k = solve(A[i], A, 1);
            if (k > max_k) max_k = k;
        }
        std::cout << max_k << std::endl;
    }

    return 0;
}

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


int n,m;
static int h[200], r[200];
static int dp[200];

int calc(int i) {
  if(dp[i] == -1) {
    dp[i] = 1;
    for(int j = 0; j < n+m; j++) {
      if(h[j] < h[i] && r[j] < r[i]) {
        dp[i] = max(dp[i], calc(j)+1);
      }
    }
  }
  return dp[i];
}


int main() {
  for(int tci = 0; ; tci++) {
    scanf("%d", &n); if(n==0) break;
    for(int i = 0; i < n; i++) {
      scanf("%d%d", h+i, r+i);
    }
    scanf("%d", &m);
    for(int i = 0; i < m; i++) {
      scanf("%d%d", h+n+i, r+n+i);
    }
    fill(dp, dp+n+m, -1);
    int mv = 0;
    for(int i = 0; i < n+m; i++) {
      mv = max(mv, calc(i));
      // fprintf(stderr, "%d / %d+%d : %d\n", i, n, m, calc(i));
    }
    printf("%d\n", mv);
  }
  return 0;
}

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

using namespace std;

typedef pair<int, int> doll;

int main()
{
	int n, m, i, j;
	vector<doll> vc;
	int dp[200];
	
	vc.reserve(200);
	
	while( cin >> n, n)
	{
		vc.clear();
		memset( dp, 0, sizeof(dp));
		
		for( i = 0; i < n; i++)
		{
			doll d;
			cin >> d.first >> d.second;
			vc.push_back(d);
		}
		
		cin >> m;
		
		for( i = 0; i < m; i++)
		{
			doll d;
			cin >> d.first >> d.second;
			vc.push_back(d);
		}
		
		std::sort(vc.begin(), vc.end());
		

		
		dp[0] = 1;
		doll surface(vc[0].first, vc[0].second);

		for( i = 1; i < n+m; i++)
		{
			if( surface.first < vc[i].first && surface.second < vc[i].second )
			{
				dp[i] = dp[i-1] + 1;
				surface.first = vc[i].first;
				surface.second = vc[i].second;
			}
			else
			{
				dp[i] = dp[i-1];
			}
		}
		
		
		cout << dp[n+m-1] << endl;
	}
	
	return 0;
}

C++: #include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<map>
using namespace std;

int loop,ichirou,zirou,ningyo[110][110],dp[110][110];


int main(){
  while(true){
    for(int i=0;i<101;i++){
      for(int j=0;j<101;j++){
	ningyo[i][j]=dp[i][j]=0;
      }
    }

    cin>>ichirou;
    if(ichirou==0){break;}
    for(int i=0;i<ichirou;i++){
      int a,b; 
      cin>>a;
      cin>>b;
      ningyo[a][b]=1;
    }
    cin>>zirou;
    for(int i=0;i<zirou;i++){
      int a,b; 
      cin>>a;
      cin>>b;
      ningyo[a][b]=1;
    }

    int a,b;
    for(b=1;b<101;b++){
      for(a=1;a<101;a++){
	if(ningyo[a][b]==1){
	  dp[a][b]=dp[a-1][b-1]+1;
	}
	else{
	  dp[a][b]=max(dp[a-1][b],dp[a][b-1]);
	}
      }
    }
    cout<<dp[100][100]<<endl;
  }
}