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<string>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
#include<set>
#include<complex>
#include<map>
#define vi vector<int>
#define vvi vector<vector<int> >
#define ll long long int
#define vl vector<ll>
#define vvl vector<vector<ll>>
#define vb vector<bool>
#define vc vector<char>
#define vs vector<string>
#define ld long double
#define INF 1e9
#define EPS 0.0000000001
#define rep(i,n) for(int i=0;i<n;i++)
#define loop(i,s,n) for(int i=s;i<n;i++)
#define CC puts("-------ok--------");
#define all(in) in.begin(), in.end()
using namespace std;
typedef pair<int, int> pii;
#define MAX 99999999
int main(){
    int n;
    while(cin>>n,n){
        vvi d(1040,vi(1040,0));
        vvi dp(1040,vi(1040,0));
        rep(i,n){
            pii temp; cin>>temp.first>>temp.second;
            d[temp.first][temp.second]++;
        }
        int m;
        cin>>m;
        rep(i,m){
            pii temp;
            cin>>temp.first>>temp.second;
            d[temp.first][temp.second]++;
        }
        loop(i,1,1001){
            loop(j,1,1001){
                dp[i][j]=max(max(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1]+d[i][j]);
        
            }
        }
        cout<<dp[999][999]<<endl;
    }
    
}

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

typedef std::pair<int,int> P;

int dp[200];//何番目のまとりょーしかが一番大きいか＝数

int main(){
	int ichiro,jiro,M=0;
	while(true){
		P dool[200];//高さ　半径
		std::cin>>ichiro;
		if(!ichiro){
			break;
		}
		for(int i=0;i<ichiro;i++){
			std::cin>>dool[i].first>>dool[i].second;
		}
		std::cin>>jiro;
		for(int i=0;i<jiro;i++){
			std::cin>>dool[i+ichiro].first>>dool[i+ichiro].second;
		}
		std::sort(dool,dool+ichiro+jiro);
		for(int i=0;i<ichiro+jiro;i++)dp[i]=1;
		for(int i=1;i<ichiro+jiro;i++){
			for(int j=i-1;j>=0;j--){
				dp[i]=std::max(dp[i],dp[j]+(dool[i].second>dool[j].second));
			}
			M=std::max(M,dp[i]);
		}
		std::cout<<M<<std::endl;
		M=0;
		for(int i=0;i<ichiro+jiro;i++)dp[i]=0;
	}
	return 0;
}

C++: // AOJ 0157
#include<iostream>
#include<map>
#include<vector>
#include<string>
#include<sstream>
#define REP(i,n) for(int i=0;i<(int)(n);i++)
using namespace std;
typedef pair<int,int> P;

const int NMAX = 150;

vector<P> ichiro, jiro;
int n, m;
int idp[NMAX], jdp[NMAX];
int index[NMAX], jndex[NMAX];

void init() {
  REP(i, NMAX) {
    idp[i] = jdp[i] = 0;
    index[i] = jndex[i] = 0;
  }
  jiro.clear();
  ichiro.clear();

  jiro.push_back(make_pair(0,0));
  ichiro.push_back(make_pair(0,0));
}

bool bigger(P big, P small) {
  return (big.first > small.first and big.second > small.second);
}

int lowerb(P mine, vector<P> his, int len) {
  for (int i = 1; i < len; i++) {
    if (not bigger(mine, his[i])) {
      return i - 1;
    }
  }
  return len - 1;
}

int rec(int i, int* mine, int* his) {
  if (i < 0) throw 1;
  if (i == 0) {
    return 0;
  } else {
    return 1 + max(rec(i - 1, mine, his), rec(mine[i], his, mine));
  }
}

int solve() {
  for (int i = 1; i <= n; i++) {
    index[i] = lowerb(ichiro[i], jiro, m);
  }

  for (int j = 1; j <= m; j++) {
    jndex[j] = lowerb(jiro[j], ichiro, n);
  }

  return max(rec(n, index, jndex), rec(m, jndex, index));
}

int main() {
  while (cin >> n and n) {
    init();
    REP(i, n) {
      int h, r;
      cin >> h >> r;
      ichiro.push_back(make_pair(h, r));
    }

    cin >> m;
    REP(i, m) {
      int h, r;
      cin >> h >> r;
      jiro.push_back(make_pair(h, r));
    }

    cout << solve() << endl;
  }
}

C++: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) begin(a),end(a)
#define MS(m,v) memset(m,v,sizeof(m))
#define D10  fixed<<setprecision(5)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<short, short> P;
typedef complex<double> Point;
typedef long long ll;
const int INF = 114514810;
const int MOD = 100000007;
const double EPS = 1e-10;
const double PI = acos(-1.0);
struct edge
{
	int from, to, cost;
	bool operator < (const edge& e) const { return cost < e.cost; }
	bool operator >(const edge& e) const { return cost > e.cost; }
};
///*************************************************************************************///
///*************************************************************************************///
///*************************************************************************************///

vector<P> v;
int n, m;
int dp[201][1001];

int solve(int i, int r)
{
	if (i == v.size()) return 0;
	if (dp[i][r] >= 0) return dp[i][r];
	int res;
	if (v[i].second > r)
	{
		res = max(solve(i + 1, r), solve(i + 1, v[i].second) + 1);
	}
	else res = solve(i + 1, r);
	return dp[i][r] = res;
}

int main()
{
	while (cin >> n, n)
	{
		v.clear();
		MS(dp, -1);
		REP(i, n)
		{
			int a, b; cin >> a >> b;
			v.push_back(P(a, b));
		}
		cin >> m;
		REP(i, m)
		{
			int a, b; cin >> a >> b;
			v.push_back(P(a, b));
		}
		sort(ALL(v));
		cout << solve(0, 0) << endl;
	}
	return 0;

}

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

int main(){
  int n,m;
  int h[200],r[200];

  while(1){
    cin >> n;
    if(!n)break;

    for(int i=0;i<n;i++)cin >> h[i] >> r[i];

    cin >> m;
    for(int i=n;i<n+m;i++)cin >> h[i] >> r[i];

    for(int i=0;i<n+m;i++)
      for(int j=i+1;j<n+m;j++)
	if(h[i]<h[j] || (h[i]==h[j] && r[i]<r[j])){
	  swap(h[i],h[j]);
	  swap(r[i],r[j]);
	}
    
    int ans1 = 1;
    int prvh = h[0],prvr=r[0];
    for(int i=1;i<n+m;i++)
      if(prvh>h[i] && prvr>r[i]){
	ans1++;
	prvh = h[i];
	prvr = r[i];
      }

    for(int i=0;i<n+m;i++)
      for(int j=i+1;j<n+m;j++)
	if(r[i]<r[j] || (r[i]==r[j] && h[i]<h[j])){
	  swap(h[i],h[j]);
	  swap(r[i],r[j]);
	}
    
    int ans2 = 1;
    prvh = h[0],prvr=r[0];
    for(int i=1;i<n+m;i++)
      if(prvh>h[i] && prvr>r[i]){
	ans2++;
	prvh = h[i];
	prvr = r[i];
      }



    cout << max(ans1,ans2) << endl;
  }
}