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++: // * template

#include <bits/stdc++.h>
#ifdef LOCAL
#include "dump.hpp"
#else
#define dump(...)
#endif

using namespace std;

template<class T> inline void chmax(T &a, const T &b) { if(a < b) a = b; }
template<class T> inline void chmin(T &a, const T &b) { if(a > b) a = b; }

template<class T, class U> inline void fill_array(T &e, const U &v) { e = v; }
template<class T, class U, size_t s> inline void fill_array(T (&a)[s], const U &v) {for(auto&e:a)fill_array(e,v);}
template<class T, class U, size_t s> inline void fill_array(array<T, s> &a, const U &v) {for(auto&e:a)fill_array(e,v);}
template<class T, class U> inline void fill_array(vector<T> &a, const U &v) {for(auto&e:a)fill_array(e,v);}

struct range {
	typedef int Int;
	struct iter {
		Int i;
		const Int s;
		constexpr iter(const Int &i_, const Int &s_):i(i_), s(s_) {}
		constexpr bool operator!=(const iter &r) const { return s > 0 ? i < r.i : i > r.i; }
		constexpr const Int &operator*() const { return i; }
		iter &operator++() { i += s; return *this; }
	};
	const Int f, l, s;
	constexpr range(const Int &f_, const Int &l_, const Int &s_):f(f_), l(l_), s(s_) {}
	constexpr range(const Int &f_, const Int &l_):f(f_), l(l_), s(1) {}
	constexpr range(const Int &num):f(0), l(num), s(1) {}
	constexpr iter begin() const { return iter(f, s); }
	constexpr iter end() const { return iter(l, s); }
};

// * solve

constexpr int MAX_NUM_BLOCK = 1000;
constexpr int MAX_BLOCK_SIZE = 5;
constexpr int WIDTH = 5;
constexpr int HEIGHT = MAX_NUM_BLOCK * MAX_BLOCK_SIZE;

array<array<bool, WIDTH>, HEIGHT> field;

void drop_block() {
	static constexpr int dx[] = {0, 1, 0};
	static constexpr int dy[] = {0, 0, 1};

	int d, p, q;
	cin >> d >> p >> q;

	int x = q - 1;
	int y = 0;
	const int w = (d == 1 ? p : 1);

	for(int i : range(HEIGHT - 1, -1, -1)) {
		if(any_of(begin(field[i]) + x, begin(field[i]) + x + w, [](bool b) { return b; })) {
			y = i + 1;
			break;
		}
	}

	dump(x, y, w);

	for(int i : range(p)) {
		field[y][x] = true;

		if(all_of(begin(field[y]), end(field[y]), [](bool b) { return b; })) {
			field[y].fill(false);
			rotate(begin(field) + y, begin(field) + y + 1, end(field));
			--y;
		}

		x += dx[d];
		y += dy[d];
	}

	dump(field[2]);
	dump(field[1]);
	dump(field[0]);
}

int calc_score() {
	int res = 0;
	for(const auto &row : field) {
		res += count(begin(row), end(row), true);
	}
	return res;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	for(int n; cin >> n && n;) {
		fill_array(field, false);

		for(int i : range(n)) {
			drop_block();
		}

		cout << calc_score() << endl;
	}

	return EXIT_SUCCESS;
}

C++: #include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int x[10000][5], m[5], maxn, sum;
int n;
int a, b, c;
int main() {
	while (true) {
		sum = 0;
		maxn = 0;
		memset(x, 0, sizeof(x));
		memset(m, 0, sizeof(m));
		cin >> n;
		if (n == 0) { break; }
		for (int h = 0; h < n; h++) {
			cin >> a >> b >> c;
			c--;
			if (a == 1) {
				maxn = 0;
				for (int j = c; j < c + b; j++) {
					maxn = max(maxn, m[j]);
				}
				for (int j = c; j < c + b; j++) {
					x[maxn][j] = 1;
					m[j] = maxn + 1;
				}
			}
			else {
				for (int j = 0; j < b; j++) {
					x[m[c] + j][c] = 1;
				}
				m[c] += b;
			}
			for (int i = 0; i < 10000; i++) {
				if (x[i][0] + x[i][1] + x[i][2] + x[i][3] + x[i][4] == 5) {
					x[i][0] = 0; x[i][1] = 0; x[i][2] = 0; x[i][3] = 0; x[i][4] = 0;
					for (int j = i; j < 9999; j++) {
						for (int k = 0; k < 5; k++) {
							x[j][k] = x[j + 1][k];
						}
					}
					x[9999][0] = 0; x[9999][1] = 0; x[9999][2] = 0; x[9999][3] = 0; x[9999][4] = 0;
					i--;
					for (int j = 0; j < 5; j++) {
						for (int k = m[j]; k >= 0; k--) {
							if (x[k][j] == 1) {
								m[j] = k + 1; goto E;
							}
						}
						m[j] = 0;
					E:;
					}
				}
			}
		}
		for (int i = 0; i < 10000; i++) {
			for (int j = 0; j < 5; j++) {
				sum += x[i][j];
			}
		}
		cout << sum << endl;
	}
}

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


using namespace std;
#define rep(i,n) for(int i = 0 ; i < n ; ++i)



int solve(){
    int n;
    cin>>n;
    if(n==0)return 0;
    vector<int> res(5000);
    rep(i,n){
        int d,p,q;
        cin>>d>>p>>q;
        if(d==1){
            int bit = ((1<<p)-1)<<(q-1);
            int i = res.size();
            while(i>0&&(res[i-1]&bit)==0)--i;
            res[i]|=bit;
            if(res[i]==31){
                res.erase(res.begin()+i);
            }
        }
        else {
            int i = res.size();
            int bit = 1<<(q-1);
            while(i>0&&(res[i-1]&bit)==0)--i;
            rep(j,p)res[i+j]|=bit;
            for(int j=p-1;j>=0;--j){
                if(res[i+j]==31)res.erase(res.begin()+i+j);
            }
        }
    }
    int ans = 0;
    for(auto e : res){
        ans += __builtin_popcount(e);
    }
    cout<<ans<<endl;
    return 1;
}

int main(){
    while(solve());
}