Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)
var (
	dat = [5000][5]int{}
	m = [5]int{}
)

func main() {
	for scanner.Scan() {
		for i := range dat {
			for j := range dat[i] {
				dat[i][j] = 0
			}
		}
		for i := range m {
			m[i] = 0
		}
		n, _ := strconv.Atoi(scanner.Text())
		if n == 0 {
			break
		}
		count := 0
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf := strings.Split(scanner.Text(), " ")
			d, _ := strconv.Atoi(buf[0])
			p, _ := strconv.Atoi(buf[1])
			q, _ := strconv.Atoi(buf[2])
			q--
			count += p
			if d == 2 {
				for j := 0; j < p; j++ {
					dat[m[q]][q] = 1
					ok := true
					for k := 0; k < 5; k++ {
						if dat[m[q]][k] == 0 {
							ok = false
						}
					}
					if ok {
						for k := 0; k < 5; k++ {
							dat[m[q]][k] = 0
							for l := m[q]; l < 4999; l++ {
								dat[l][k] = dat[l+1][k]
							}
							for l := 4999; l >= 0; l-- {
								if dat[l][k] != 0 {
									m[k] = l+1
									break
								}
								if l == 0 {
									m[k] = 0
								}
							}
						}
						count -= 5
					} else {
						m[q]++
					}
				}
			} else {
				h := 0
				for i := 0; i < p; i++ {
					h = max(h, m[i+q])
				}
				for i := 0; i < p; i++ {
					dat[h][i+q] = 1
				}
				for i := 0; i < p; i++ {
					m[i+q] = h+1
				}
				ok := true
				for j := 0; j < 5; j++ {
					if dat[h][j] == 0 {
						ok = false
					}
				}
				if ok {
					for j := 0; j < 5; j++ {
						dat[h][j] = 0
						for k := h; k < 4999; k++ {
							dat[k][j]=dat[k+1][j]
						}
						for k := 4999; k>= 0; k-- {
							if dat[k][j] != 0 {
								m[j]=k+1
								break
							}
							if k == 0 {
								m[j] = 0
							}
						}
					}
					count -= 5
				}
			}
		}
		fmt.Println(count)
	}
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

C++: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int main(){
  int N;
  while(cin >> N && N){
    const int H = 5010;
    const int W = 5;
    bool block[H][W] = {};
    int height[W] = {};
    int n_h = 0;
    REP(iter, N){
      int d, l, bx;
      cin >> d >> l >> bx;
      bx --;
      if(d == 1){
        // yoko
        int h = 0;
        for(int x = bx; x < bx + l; x++) h = max(h, height[x]);
        for(int x = bx; x < bx + l; x++) block[h][x] = true;
        bool line = true;
        for(int x = 0; x < W; x++) if(!block[h][x]) line = false;
        if(line){
          for(int x = 0; x < W; x++) block[h][x] = false;
        }
      }else if(d == 2){
        // tate
        for(int y = height[bx]; y < height[bx] + l; y++)
          block[y][bx] = true;
        for(int y = height[bx]; y < height[bx] + l; y++){
          bool line = true;
          for(int x = 0; x < W; x++) if(!block[y][x]) line = false;
          if(!line) continue;
          for(int x = 0; x < W; x++) block[y][x] = false;
        }
      }
      bool new_block[H][W] = {};
      int new_height[W] = {};
      int new_nh = 0;
      int curr = 0;
      /*
      for(int y = n_h + 5; y >= 0; y--){
        debug(block[y], block[y] + 5);
      }
      cout << endl;
      */
      for(int y = 0; y < n_h + 5; y++){
        bool clear = true;
        for(int x = 0; x < W; x++) if(block[y][x]) clear = false;
        if(clear) continue;
        for(int x = 0; x < W; x++)if(block[y][x]){
          new_block[curr][x] = true;
          new_height[x] = curr + 1;
        }
        new_nh = ++curr;
      }
      memcpy(block, new_block, sizeof(block));
      memcpy(height, new_height, sizeof(height));
      n_h = new_nh;
    }
    int ans = 0;
    REP(y, H)REP(x, W) ans += block[y][x];
    cout << ans << endl;
  }
  return 0;
}

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

class Tetoris{
    public:
    int stack[MAX+1], top;
    Tetoris(){ stack[0] = 31; top = 0; }
    
    void insert( int o, int p, int q ){
        int value = (o == 1 ? (((2 << p-1)-1) << (q-1)) : (1 << (q-1)));
        int target = getTarget( value );
        for ( int i = target;  i < target + ((o == 2) ? p : 1); i++ ){
            if ( i > top ){
                stack[i] = value;
                top = i;
            } else {
                stack[i] += value;
            }
        }
        
        while( erase());
    }
    
    bool erase(){
        for ( int i = 1; i <= top; i++ ){
            if ( stack[i] == 31 ){
                for ( int j = i+1; j <= top; j++ ) stack[j-1] = stack[j];
                top--; return true;
            }
        }
        return false;
    }
    
    int getResult(){
        int sum = 0;
        for ( int i = top; i >= 1; i-- ){
            int val = stack[i];
            while( val ){
                if ( val%2 ) sum++;
                val /= 2;
            }
        }
        return sum;
    }
    
    int getTarget( int value ){
        int target = top;
        while( (stack[target] & value) == 0 ) target--;
        return target + 1;
    }
};

int main(){
    int n, o, p, q;
    while( cin >> n && n ){
        Tetoris tetoris;
        for ( int i = 0; i < n; i++ ) {
            cin >> o >> p >> q;
            tetoris.insert(o, p, q);
        }
        cout << tetoris.getResult() << endl;
    }
    return 0;
}

C++: #define _USE_MATH_DEFINES
#include <iostream>
#include <complex>
#include <algorithm>
#include <vector>
#include <stack>
#include <string>
#include <queue>
#include <cmath>
#include <math.h>
#include <numeric>
#include <list>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <climits>
#include <set>
#include <memory.h>
#include <memory>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cassert>
#include <map>
#include <cassert>
#include <time.h>
#include <ctime>

using namespace std;

typedef complex<double> xy_t;
typedef pair<xy_t, xy_t> line;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int , P> PP;
typedef pair<int, string> Ps;
typedef vector<int> vec;
typedef vector<vec> mat;
const int INF = 1 << 30;
const double EPS = 1e-9;
const double PI = 3.1415926535897932384626433832795;
const int CLK = CLOCKS_PER_SEC;

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

bool field[5005][5];

int block(int d, int p, int q){
	int x, y;
	if(d == 1) { x = p; y = 1;}
	else {y = p; x = 1;}
	for(int i = 5000; i >= 1; i--){
		bool f = false;
		rep(j, x){
			if(field[i-1][q+j]) f = true;
		}
		if(f){
			rep(j, y){
				rep(k, x){
					field[i+j][q+k] = true;
				}
			}
			return i;
		}
	}
	rep(i, y)rep(j, x) field[i][q+j] = true;
	return 0;
}

void mov(int pos){
	rep(i, 5) field[pos][i] = false;
	rep2(i, pos, 5000)rep(j, 5) swap(field[i+1][j], field[i][j]);
}

void update(int pos){
	int cnt = 0;
	for(int i = 4; i >= 0; i--){
		bool f = true;
		rep(j, 5){
			if(!field[pos+i][j]) f = false;
		}
		if(f) mov(pos + i);
	}
}

void drop(){
	int d, p, q;
	cin >> d >> p >> q;
	int pos = block(d, p, --q);
	update(pos);
}

int cnt(){
	int res = 0;
	rep(i, 5000)rep(j, 5) if(field[i][j]) res++;
	return res;
}

int main(){
	int n;
	while(cin >> n && n){
		memset(field, false, sizeof(field));
		rep(i, n){
			drop();
	//		cout << i << " " << cnt() << endl;
		}
		cout << cnt() << endl;
	}
	return 0;
}