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 <map>
using namespace std;
typedef pair<int, int> P;

const int MAX_N = 1001;
int dp[MAX_N];
//int h[MAX_N * 2], r[MAX_N * 2];
vector<P> vec;
// ???????????????

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	
	int n;
	while(cin >> n && n != 0){
	cin >> n;
	
	for(int i = 0; i < n; ++i){
		int h, r;
		cin >> h >> r;
		vec.push_back(P(h, r));
		//cin >> h[i] >> r[i];
	}
	
	int m;
	cin >> m;
	
	for(int i = n; i < n + m; ++i){
		int h, r;
		cin >> h >> r;
		vec.push_back(P(h, r));
		//cin >> h[i] >> r[i];
	}
	
	sort(vec.begin(), vec.end());
	
	for(int i = 0; i < n + m; ++i){
		//cout << vec[i].first << " " << vec[i].second << endl;
		dp[i] = 1;
	}
	
	int ans = 0;
	for(int i = 0; i < n + m; ++i){
		for(int j = 0; j < n + m; ++j){
			if(vec[i].first > vec[j].first && vec[i].second > vec[j].second){
				dp[i] = max(dp[i], dp[j] + 1);
			}
			ans = max(ans, dp[i]);
		}
	}
	
	cout << ans << endl;
	}
}

C++: #include <bits/stdc++.h>
using namespace std;
const int dx[]={0,1,0,-1,1,-1,-1,1};
const int dy[]={-1,0,1,0,1,1,-1,-1};
const int INF = 1<<30;
const double EPS = 1e-15;
#define PB push_back
#define mk make_pair
#define fi first
#define se second
#define ll long long
#define reps(i,j,k) for(int i = (j); i < (k); i++)
#define rep(i,j) reps(i,0,j)
#define MOD 1000000007
typedef pair<int,int> Pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
vector < Pii > data;
int N,M;
int memo[256][128][128];
int solve(int dep,int prev1,int prev2){
	if(dep == N+M){
		return 0;
	}
	if(memo[dep][prev1][prev2])return memo[dep][prev1][prev2];
	int ret = 0;
	reps(i,dep,N+M){
		if(prev1 < data[i].fi && prev2 < data[i].se){
			ret = max(ret , max(1 + solve(i+1,data[i].fi,data[i].se),solve(i+1,prev1,prev2)));
		}
		else{
			ret = max(ret,solve(i+1,prev1,prev2));
		}
	}
	return memo[dep][prev1][prev2] = ret;
}
int main(){
	while(scanf("%d",&N),N){
		data.clear();
		memset(memo,0,sizeof(memo));
		rep(i,N){
			int a,b;
			scanf("%d%d",&a,&b);
			data.PB(Pii(a,b));
		}
		scanf("%d",&M);
		rep(i,M){
			int a,b;
			scanf("%d%d",&a,&b);
			data.PB(Pii(a,b));
		}
		sort(data.begin(),data.end());
		printf("%d\n",solve(0,0,0));
	}

    return 0;
}

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

#define iota(i,n,b,s) for(int i=int(b);i!=int((b)+(s)*(n));i+=(s))
#define range(i,n,m) iota(i,(((n)>(m))?((n)-(m)):((m)-(n))),(n),((n)>(m)?-1:1))
#define rep(i,n) iota(i,(n),0,1)
#define loop for(;;)

#define INF (1e9)
#define EPS (1e-9)
#define cons(a,b) (make_pair(a,b))
#define car(a) (a.first)
#define cdr(a) (a.second)
#define cadr(a) (car(cdr(a)))
#define cddr(a) (cdr(cdr(a)))
#define all(a) a.begin(), a.end()
#define trace(var) cerr<<">>> "<<#var<<" = "<<var<<endl;

typedef long long Integer;
typedef double Real;
typedef vector<int> vi;
typedef vector<string> vs;
typedef map<string,int> Dictionary;
const Real PI = acos(-1);

template<class S, class T>
ostream& operator<<(ostream& os, pair<S,T> p) {
  os << '(' << car(p) << ", " << cdr(p) << ')';
  return os;
}

template<class T>
ostream& operator<<(ostream& os, vector<T> v) {
  if (v.size() == 0) {
    os << "(empty)";
    return os;
  }
  os << v[0];
  for (int i=1, len=v.size(); i<len; ++i) os << ' ' << v[i];
  return os;
}

int dx[] = { -1, 0, 1, 0 };
int dy[] = {  0, -1, 0, 1 };

int main() {

more:

  vector<int> hs;
  vector<int> rs;

  {
    int n; cin >> n;
    if (!n) return 0;
    rep (_, n) {
      int h, r; cin >> h >> r;
      hs.push_back(h);
      rs.push_back(r);
    }
  }

  {
    int n; cin >> n;
    rep (_, n) {
      int h, r; cin >> h >> r;
      hs.push_back(h);
      rs.push_back(r);
    }
  }

  const int N = hs.size();
  int d[N][N];

  rep (i, N) {
    rep (j, N) {
      if ((hs[i] < hs[j] && rs[i] < rs[j])) {
        d[i][j] = 1;
      } else {
        d[i][j] = 0;
      }
    }
  }

  int ans = 0;
  rep (i, N) {
    stack<pair<int,int>> s;
    s.push(cons(i, 1));
    while (!s.empty()) {
      auto t = s.top(); s.pop();
      rep (j, N) {
        if (d[car(t)][j]) s.push(cons(j, cdr(t) + 1));
      }
      ans = max(ans, cdr(t));
    }
  }
  cout << ans << endl;

  goto more;
}

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

#define MAX 100

struct doll{
	int high, r;
	doll() {}
	doll(int H, int R) : high(H), r(R) {}
	bool operator<(doll d){
		return (high < d.high&&r < d.r);
	}
};

struct doll_c{
	doll d;
	int count;
};

int n, m;

doll K[MAX * 2];
doll_c dp[MAX * 2];

int main(){
	while (1){
		int h, r;
		scanf("%d", &n);
		if (n == 0)
			break;
		for (int i = 1; i <= n; ++i){
			scanf("%d %d", &h, &r);
			K[i].high = h; K[i].r = r;
		}
		scanf("%d", &m);
		for (int i = n+1; i < m; ++i){
			scanf("%d %d", &h, &r);
			K[i].high = h;
			K[i].r = r;
		}
		std::sort(K+1, K + 1 + n + m);
		dp[0].d = doll(-1, -1); dp[0].count = 0;
		for (int i = 1; i <= n + m; ++i){
			if (dp[i - 1].d < K[i])
				dp[i].d = K[i]; dp[i].count += 1;
		}
	}
	printf("%d\n", dp[n + m].count);
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
int N,M,T;
P H[311];
int dp[311];

int solve(int id){
  if( dp[id] != -1 ) return dp[id];
  if( id == 0 ) return 0;
  int res = 0;
  for(int i=0;i<id;i++){
    if( H[id].first > H[i].first && H[id].second > H[i].second )
      res = max( res, solve(i) + 1 );
  }
  return dp[id] = res;
}

int main(){

  while( cin >> N && N ){
    memset(dp,-1,sizeof(dp));
    for(int i=0;i<N;i++) cin >> H[i].first >> H[i].second;
    cin >> M;
    for(int i=0;i<M;i++) cin >> H[i+N].first >> H[i+N].second;
    
    sort(H,H+N+M);
    H[N+M] = P(100000,100000);
    cout << solve(N+M) << endl;
  }
}