Problem:
Problem C: Cut the Cake Today is the birthday of Mr. Bon Vivant, who is known as one of the greatest pâtissiers in the world.
Those who are invited to his birthday party are gourmets from around the world.
They are eager to see and eat his extremely creative cakes.
Now a large box-shaped cake is being carried into the party.
It is not beautifully decorated and looks rather simple, but it must be delicious beyond anyone's imagination.
Let us cut it into pieces with a knife and serve them to the guests attending the party. The cake looks rectangular, viewing from above (Figure C-1).
As exemplified in Figure C-2, the cake will iteratively be cut into pieces, where on each cut exactly a single piece is cut into two smaller pieces.
Each cut surface must be orthogonal to the bottom face and must be orthogonal or parallel to a side face.
So, every piece shall be rectangular looking from above and every side face vertical.   Figure C-1: The top view of the cake     Figure C-2: Cutting the cake into pieces  Piece sizes in Figure C-2 vary significantly and it may look unfair, but you don't have to worry.
Those guests who would like to eat as many sorts of cakes as possible often prefer smaller pieces.
Of course, some prefer larger ones. Your mission of this problem is to write a computer program that simulates the cutting process of the cake and reports the size of each piece. Input The input is a sequence of datasets, each of which is of the following format.  n  w  d  p 1  s 1 ...  p n  s n  The first line starts with an integer n that is between 0 and 100 inclusive.
It is the number of cuts to be performed.
The following w and d in the same line are integers between 1 and 100 inclusive.
They denote the width and depth of the cake, respectively.
Assume in the sequel that the cake is placed so that w and d are the lengths in the east-west and north-south directions, respectively. Each of the following n lines specifies a single cut, cutting one and only one piece into two. p i is an integer between 1 and i inclusive and is the identification number of the piece that is the target of the i -th cut.
Note that, just before the i -th cut, there exist exactly i pieces.
Each piece in this stage has a unique identification number that is one of 1, 2, ..., i and is defined as follows:  The earlier a piece was born, the smaller its identification number is. Of the two pieces born at a time by the same cut, the piece with the smaller area (looking from above) has the smaller identification number.
If their areas are the same, you may define as you like the order between them, since your choice in this case has no influence on the final answer. Note that identification numbers are adjusted after each cut.  s i is an integer between 1 and 1000 inclusive and specifies the starting point of the i -th cut.
From the northwest corner of the piece whose identification number is p i , you can reach the starting point by traveling s i in the clockwise direction around the piece.  
You may assume that the starting point determined in this way cannot be any one of the four corners of the piece.
The i -th cut surface is orthogonal to the side face on which the starting point exists.   The end of the input is indicated by a line with three zeros.   Output   For each dataset, print in a line the areas looking from above of all the pieces that exist upon completion of the n cuts specified in the dataset.
They should be in ascending order and separated by a space.
When multiple pieces have the same area, print it as many times as the number of the pieces.   Sample Input  3 5 6
1 18
2 19
1 2
3 4 1
1 1
2 1
3 1
0 2 5
0 0 0  Output for the Sample Input  4 4 6 16
1 1 1 1
10

Solution (Python):
ans_list = []
def make_pieces(w, d, s):
    if w == 0 and d == 0:
        print(w, d, s)
    s %= (2 * w + 2 * d)
    while True:
        if w > s:
            return [s, d], [w - s, d]
        s -= w
        if d > s:
            return [w, s], [w, d - s]
        s -= d
        if w > s:
            return [w - s, d], [s, d]
        s -= w
        if d > s:
            return [w, s], [w, d - s]
        s -= d


while True:
    n, w, d = map(int, input().split())
    P = [[w, d]]
    if n == 0 and w == 0 and d == 0:
        break
    for i in range(n):
        p, s = map(int, input().split())
        new_pieces = make_pieces(P[p - 1][0], P[p - 1][1], s)
        
        if new_pieces[0][0] * new_pieces[0][1] < new_pieces[1][0] * new_pieces[1][1]:
            P = P[:p - 1] + P[p:] + [new_pieces[0]] + [new_pieces[1]]
        else:
            P = P[:p - 1] + P[p:] + [new_pieces[1]] + [new_pieces[0]]
        

    S_list = []
    for i in P:
        S_list.append(i[0] * i[1])

    S_list.sort()
    ans_list.append(S_list)

for i in range(len(ans_list)):
    I = ans_list[i]
    for j in range(len(I)):
        J = I[j]
        if j == len(I) - 1:
            print(J, end = "")
        else:
            print(J, end=" ")
    print()

Solution (Python):
while 1:
    n,w,d = map(int,raw_input().split())
    if w == 0: break
    cake = [[w,d]]
    for loop in xrange(n):
        p,s = map(int,raw_input().split())
        x,y = cake.pop(p-1)
        s %= (x+y)
        if s < x:
            x1,x2 = sorted([s,x-s])
            cake.append([x1,y])
            cake.append([x2,y])
        else:
            s -= x
            y1,y2 = sorted([s,y-s])
            cake.append([x,y1])
            cake.append([x,y2])
    print " ".join(map(str,sorted([x*y for x,y in cake])))

Solution (Python):
while 1:
    n,w,d = map(int,raw_input().split())
    if w == 0: break
    cake = [[w,d]]
    for loop in xrange(n):
        p,s = map(int,raw_input().split())
        x,y = cake.pop(p-1)
        s %= (x+y)
        if s < x:
            x1,x2 = sorted([s,x-s])
            cake += [[x1,y],[x2,y]]
        else:
            s -= x
            y1,y2 = sorted([s,y-s])
            cake += [[x,y1],[x,y2]]
    print " ".join(map(str,sorted([x*y for x,y in cake])))

Solution (Python):
def cut(loc,s,C):
    c1,c2=[],[]
    Cw,Cd=C[1:]
    if loc:
        a,b=max(s,Cw-s),min(s,Cw-s)
        c1=[a*Cd,a,Cd]
        c2=[b*Cd,b,Cd]
    else:
        a,b=max(s,Cd-s),min(s,Cd-s)
        c1=[a*Cw,Cw,a]
        c2=[b*Cw,Cw,b]    
    return c1,c2



while(1):
    [n,w,d]=[int(x) for x in raw_input().split()]
    if w==0:    break
    A=[[w*d,w,d]]
    for i in range(n):
        [j,s]=[int(x) for x in raw_input().split()]
        j-=1
        AA=A[:j]+A[j+1:]
        C=A.pop(j)
        loc=1
        while(1):
            if loc%2:
                if s>C[1]:
                    loc+=1
                    s-=C[1]
                else:
                    break
            else:
                if s>C[2]:
                    loc+=1
                    s-=C[2]
                else:
                    break
        loc%=2
        [c1,c2]=cut(loc,s,C)
        AA+=[c2,c1]
        A=AA[:]
    A.sort(key=lambda x:x[0])
    print ' '.join([str(x[0]) for x in A])

Solution (Python):
def cut(cake,s):
    ret_cake = [ (-1,-1),(-1,-1) ]
    w = cake[2]
    h = cake[1]

    s %= 2*(w+h)

    if w > s:
        ret_cake = [(h,s),(h,w-s)]
    elif w+h > s:
        ret_cake = [(s-w,w),(w+h-s,w)]
    elif 2*w+h > s:
        ret_cake = [(h,s-w-h),(h,2*w+h-s)]
    elif 2*w+2*h > s:
        ret_cake = [(s-2*w-h,w),(2*w+2*h-s,w)]

    ret_cake =  [ (c[0]*c[1],c[0],c[1]) for c in ret_cake]
    ret_cake.sort()
    return ret_cake

while True:
    n,w,d = map(int,input().split())
    if n == 0  and w == 0 and d == 0:
        break
    p = [0] * n
    s = [0] * n
    for i in range(n):
        p[i],s[i] = map(int,input().split())
    cake = [ (w*d,d,w) ]

    for i in range(n):
        cake = cake[:p[i]-1] + cake[p[i]:] + cut(cake[p[i]-1],s[i])
    cake.sort()
    print( " ".join(map(str,[c[0] for c in cake])))

Solution (Python):
class Cake:
  def __init__(self, w, d):
    self.w = w
    self.d = d
    self.next = None

  def getArea(self):
    return self.w*self.d

  def getCake(self, i):
    if i==1: return self
    else: return self.next.getCake(i-1)

  def devideCake(self, n):
    n = n % (self.w+self.d)
    if n < self.w:
      c1 = Cake(min(n, self.w-n), self.d)
      c2 = Cake(max(n, self.w-n), self.d)
    else:
      c1 = Cake(self.w, min(n-self.w, self.d-n+self.w))
      c2 = Cake(self.w, max(n-self.w, self.d-n+self.w))
    c1.next = c2
    return c1

while True:
  n,w,d = map(int, raw_input().split())
  if n==w==d==0: break
  cakes = Cake(w, d)
  for i in xrange(n):
    p,s = map(int, raw_input().split())
    cake = cakes.getCake(p)
    if p == 1:
      cakes = cakes.next
    else:
      cakes.getCake(p-1).next = cake.next
    if i == 0:
      cakes = cake.devideCake(s)
    else:
      cakes.getCake(i).next = cake.devideCake(s)
  areas = []
  c = cakes
  while True:
    areas.append(c.getArea())
    if c.next == None: break
    c = c.next
  print " ".join(map(str, sorted(areas)))

Solution (Python):
def cut(d, w, s):
    s %= 2 * (d + w)
    sq = []
    if 0 < s < w:
        sq = [(d, s), (d, w - s)]
    elif w < s < w + d:
        s -= w
        sq = [(s, w), (d - s, w)]
    elif w + d < s < 2 * w + d:
        s -= w + d
        sq = [(d, s), (d, w - s)]
    elif 2 * w + d < s < 2 * (w + d):
        s -= 2 * w + d
        sq = [(s, w), (d - s, w)]
    else:
        assert(False)
    p1, p2 = sq
    if p1[0] * p1[1] > p2[0] * p2[1]:
        p1, p2 = p2, p1
    return [p1, p2]


while True:
    N, W, D = map(int, input().split())
    if not (N | W | D):
        break
    square = [(D, W)]
    for _ in range(N):
        p, s = map(int, input().split())
        d, w = square.pop(p - 1)
        square.extend(cut(d, w, s))
    print(*sorted(d * w for d, w in square))

Solution (Python):
def cut(d, w, s):
    s %= d + w
    sq = []
    if 0 < s < w:
        sq = [(d, s), (d, w - s)]
    elif w < s < w + d:
        s -= w
        sq = [(s, w), (d - s, w)]
    else:
        assert(False)
    p1, p2 = sq
    if p1[0] * p1[1] > p2[0] * p2[1]:
        p1, p2 = p2, p1
    return [p1, p2]


while True:
    N, W, D = map(int, input().split())
    if not (N | W | D):
        break
    square = [(D, W)]
    for _ in range(N):
        p, s = map(int, input().split())
        d, w = square.pop(p - 1)
        square.extend(cut(d, w, s))
    print(*sorted(d * w for d, w in square))

Solution (Python):
def cut(d, w, s):
    s %= d + w
    if 0 < s < w:
        p1, p2 = (d, s), (d, w - s)
    elif w < s < w + d:
        s -= w
        p1, p2 = (s, w), (d - s, w)
    else:
        assert(False)
    if p1[0] * p1[1] > p2[0] * p2[1]:
        p1, p2 = p2, p1
    return [p1, p2]


while True:
    N, W, D = map(int, input().split())
    if not (N | W | D):
        break
    square = [(D, W)]
    for _ in range(N):
        p, s = map(int, input().split())
        d, w = square.pop(p - 1)
        square.extend(cut(d, w, s))
    print(*sorted(d * w for d, w in square))

Solution (Python):
def cut(d, w, s):
    s %= d + w
    if 0 < s < w:
        p1, p2 = (d, s), (d, w - s)
    else:
        s -= w
        p1, p2 = (s, w), (d - s, w)
    if p1[0] * p1[1] > p2[0] * p2[1]:
        p1, p2 = p2, p1
    return [p1, p2]


while True:
    N, W, D = map(int, input().split())
    if not (N | W | D):
        break
    square = [(D, W)]
    for _ in range(N):
        p, s = map(int, input().split())
        d, w = square.pop(p - 1)
        square.extend(cut(d, w, s))
    print(*sorted(d * w for d, w in square))

Solution (Python):
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 998244353
dd = [(0,-1),(1,0),(0,1),(-1,0)]
ddn = [(0,-1),(1,-1),(1,0),(1,1),(0,1),(-1,-1),(-1,0),(-1,1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)


def main():
    rr = []

    while True:
        n,w,d = LI()
        if n == 0 and w == 0 and d == 0:
            break
        a = [LI() for _ in range(n)]
        r = [(w,d)]
        for p,s in a:
            ww, dd = r.pop(p-1)
            u = ww + dd
            s %= u
            tr = []
            if s < ww:
                tr.append((s,dd))
                tr.append((ww-s,dd))
            else:
                s -= ww
                tr.append((ww,s))
                tr.append((ww,dd-s))
            r.extend(sorted(tr,key=lambda x: x[0]*x[1]))

        rr.append(' '.join(map(lambda x: str(x[0]*x[1]), sorted(r,key=lambda x: x[0]*x[1]))))
    return '\n'.join(map(str,rr))


print(main())

Solution (Python):

from sys import setrecursionlimit
setrecursionlimit(100000)

class Cake():

    def __init__(self, N, W, D):
        self.P = [-1]*2*(N+1)
        self.L = [-1]*2*(N+1)
        self.R = [-1]*2*(N+1)
        self.W = [0]*2*(N+1)
        self.W[1] = W
        self.D = [0]*2*(N+1)
        self.D[1] = D

    def find(self, target):
        count = 0
        for i in range(1, 2*N+2):
            count += (self.L[i] == -1)
            if count == target:
                return i

    def cut(self, target, s, l):
        w = self.W[target]
        d = self.D[target]
        L = w+d
        s %= L
        if s <= w:
            nw, nW = s, w-s
            if nw > nW:
                nw, nW = nW, nw
            nd, nD = d, d
        else:
            s -= w
            nd, nD = s, d-s
            if nd > nD:
                nd, nD = nD, nd
            nw, nW = w, w
        assert 0 < nw
        assert 0 < nd
        r = l + 1
        self.L[target], self.R[target] = l, r
        self.P[l], self.P[r] = target, target
        self.W[l], self.W[r] = nw, nW
        self.D[l], self.D[r] = nd, nD

    def show(self):
        tmp = []
        for i in range(1, len(self.L)):
            if self.L[i] == -1:
                tmp.append(self.W[i] * self.D[i] )
        print(" ".join(map(str, sorted(tmp))))

N, W, D = map(int, input().split())
while W:
    cake = Cake(N, W, D)
    for i in range(N):
        p, s = map(int, input().split())
        target = cake.find(p)
        cake.cut(target, s, 2*(i+1))
    cake.show()
    N, W, D = map(int, input().split())

Solution (Python):

from sys import setrecursionlimit
setrecursionlimit(100000)
 
class Cake():
 
    def __init__(self, N, W, D):
        self.P = [-1]*2*(N+1)
        self.L = [-1]*2*(N+1)
        self.R = [-1]*2*(N+1)
        self.W = [0]*2*(N+1)
        self.W[1] = W
        self.D = [0]*2*(N+1)
        self.D[1] = D
 
    def find(self, target):
        count = 0
        for i in range(1, 2*N+2):
            count += (self.L[i] == -1)
            if count == target:
                return i
 
    def cut(self, target, s, l):
        w = self.W[target]
        d = self.D[target]
        L = w+d
        s %= L
        if s <= w:
            nw, nW = s, w-s
            if nw > nW:
                nw, nW = nW, nw
            nd, nD = d, d
        else:
            s -= w
            nd, nD = s, d-s
            if nd > nD:
                nd, nD = nD, nd
            nw, nW = w, w
        assert 0 < nw
        assert 0 < nd
        r = l + 1
        self.L[target], self.R[target] = l, r
        self.P[l], self.P[r] = target, target
        self.W[l], self.W[r] = nw, nW
        self.D[l], self.D[r] = nd, nD
 
    def show(self):
        tmp = []
        for i in range(1, len(self.L)):
            if self.L[i] == -1:
                tmp.append(self.W[i] * self.D[i] )
        print(" ".join(map(str, sorted(tmp))))
 
N, W, D = map(int, input().split())
while W:
    cake = Cake(N, W, D)
    for i in range(N):
        p, s = map(int, input().split())
        target = cake.find(p)
        cake.cut(target, s, 2*(i+1))
    cake.show()
    N, W, D = map(int, input().split())

Solution (Python):
while True:
	dic = {}
	n,w,d = map(int,input().split(" "))
	if n == 0 and w == 0 and d == 0:
		break
	dic[1] = (w,d)
	for i in range(n):
		p,s = map(int,input().split(" "))
		W,H = dic[p]
		for j in range(p,i+1):
			dic[j] = dic[j+1]
		cycle = 2*(H+W)
		s %= cycle
		if s < W or ((H+W) < s and s < (W+H+W)):
			if W < s:
				s -= (H+W)
			dic[i+1] = (min(s,W-s),H)
			dic[i+2] = (max(s,W-s),H)

		elif (W < s and s < (H+W)) or ((W+H+W) < s):
			if s > (H+W):
				s -= (W+H+W)
			else:
				s -= W
			dic[i+1] = (W,min(s,H-s))
			dic[i+2] = (W,max(s,H-s))

	sq = list(dic.values())
	sq.sort(key=lambda x:x[0]*x[1])
	for i in range(len(sq)-1):
		print(sq[i][0]*sq[i][1],end=" ")
	print(sq[len(sq)-1][0]*sq[len(sq)-1][1])

Solution (Python):
while True:
  n, w, h = map(int, input().split())
  if w == 0:
    break
  lst = [(w, h)]
  for _ in range(n):
    p, s = map(int, input().split())
    wi, hi = lst.pop(p - 1)
    pos = s % (wi + hi)
    if pos < wi:
      w1, w2 = min(pos, wi - pos), max(pos, wi - pos)
      lst.append((w1, hi))
      lst.append((w2, hi))
    else:
      h1, h2 = min(pos - wi, hi - (pos - wi)), max(pos - wi, hi - (pos - wi))
      lst.append((wi, h1))
      lst.append((wi, h2))
  ans = sorted([wi * hi for wi, hi in lst])
  print(*ans)

Solution (Python):
while True:
    n,w,d=map(int,raw_input().split())
    if n==w==d==0:break
    D=[(w,d)]
    for i in range(n):
        p,s=map(int,raw_input().split())
        p-=1
        s%=D[p][0]+D[p][1]
        if s>D[p][0]:
            s-=D[p][0]
            D.append((D[p][0],s))
            D.append((D[p][0],D[p][1]-s))
        else:
            D.append((D[p][0]-s,D[p][1]))
            D.append((s,D[p][1]))
        del D[p]
        p=len(D)-1
        if D[p][0]*D[p][1]<D[p-1][0]*D[p-1][1]:
            D[p],D[p-1]=D[p-1],D[p]

    D=[i*j for i,j in D]
    D.sort()
    print " ".join(map(str,D))

Solution (Python):



class Cake:
    def __init__(self, w, d):
        self.w = w
        self.d = d

    def area(self):
        return self.w * self.d

    def cut(self, s):
        perimeter = self.w * 2 + self.d * 2
        s %= perimeter
        if s < self.w:
            return [Cake(s, self.d), Cake(self.w - s, self.d)]
        elif s < self.w + self.d:
            l = s - self.w
            return [Cake(self.w, l), Cake(self.w, self.d - l)]
        elif s < self.w + self.d + self.w:
            l = s - (self.w + self.d)
            return [Cake(self.w - l, self.d), Cake(l, self.d)]
        else:
            l = s - (self.w + self.d + self.w)
            return [Cake(self.w, self.d - l), Cake(self.w, l)]

    def __repr__(self):
        return '(w {}, d {})'.format(self.w, self.d)


def solve(Q, n, w, d):
    cakes = [Cake(w, d)]
    for p, s in Q:
        
        cut_cake = cakes.pop(p)
        cake1, cake2 = cut_cake.cut(s)
        if cake1.area() > cake2.area():
            cake2, cake1 = cake1, cake2
        cakes.append(cake1)
        cakes.append(cake2)

    
    cakes.sort(key=lambda cake: cake.area())
    areas_str = []
    for cake in cakes:
        area_str = str(cake.area())
        areas_str.append(area_str)
    print(' '.join(areas_str))


if __name__ == "__main__":
    while True:
        n, w, d = list(map(int, input().split()))
        if n == 0 and w == 0 and d == 0:
            break
        Q = []
        for _ in range(n):
            p, s = list(map(int, input().split()))
            Q.append((p-1, s))
        solve(Q, n, w, d)

Solution (Python):
WIDTH = 0
DEPTH = 1

while True:
    N, W, D = [int(x) for x in input().split()]
    if N == W == D == 0:    break
    if N == 0:
        print(W * D)
        continue

    p, s = zip(*[[int(x) for x in input().split()] for _ in range(N)])

    
    
    cake = [[0, 0], [W, D]] + [None] * N

    for i in range(N):
        id = p[i]   
        w, d = cake[id] 
        l = s[i]    

        
        for j in range(id, i + 1):
            cake[j] = cake[j + 1][:]
        cake[i + 1] = None

        
        l = l % (w + d)
        if l < w:  
            w_min = min(l, w - l)  
            cake[i + 1] = [w_min, d]
            cake[i + 2] = [w - w_min, d]
        else:  
            l -= w
            d_min = min(l, d - l)
            cake[i + 1] = [w, d_min]
            cake[i + 2] = [w, d - d_min]

    area = [w * d for (w, d) in cake]
    area.sort()
    print(" ".join(map(str, area[1:])))

Solution (Python):
def cut(cake,s):
    w=cake[0]
    h=cake[1]
    s=s%(w+h)
    if s<w:
        if s<(w-s):
            return [(s,h),(w-s,h)]
        else:
            return [(w-s,h),(s,h)]
    else:
        if (s-w)<(w+h-s):
            return [(w,s-w),(w,w+h-s)]
        else:
            return [(w,w+h-s),(w,s-w)]
        
n,w,d=map(int,input().split())
while n!=0 or w!=0 or d!=0:
    cakes=[(w,d)]
    for i in range(n):
        p,s=map(int,input().split())
        p=p-1
        cut_cakes=cut(cakes[p],s)
        cakes=cakes[:p]+cakes[p+1:]+cut_cakes
    ans=[0]*len(cakes)
    for i in range(len(cakes)):
        ans[i]=cakes[i][0]*cakes[i][1]
    ans.sort()
    print(ans[0],end="")
    for i in range(1,len(cakes)):
        print(" "+str(ans[i]),end="")
    print()
    n,w,d=map(int,input().split())

Solution (Python):
def cut(w, d, s):
    mod = s % (w + d)
    s = []
    if mod > w:
        tate = mod - w
        yoko = w
        tate_2 = d - (mod - w)
        area = tate * yoko
        area_2 = tate_2 * yoko
        s.append([area, [yoko, tate]])
        s.append([area_2, [yoko, tate_2]])
    else:
        yoko = mod
        tate = d
        yoko_2 = w - mod
        area = tate * yoko
        area_2 = tate * yoko_2
        s.append([area , [yoko, tate]])
        s.append([area_2, [yoko_2, tate]])
    return sorted(s)


while True:
    n, w, d = map(int, input().split())
    if n == 0 and w == 0 and d == 0:
        break
    cuts = [list(map(int, input().split())) for _ in range(n)]
    areas = [(w * d, [w, d])]
    for key, s in cuts:
        area = areas.pop(key - 1)
        areas += cut(*area[1], s)
    ans = []
    for k in areas:
        ans.append(k[0])
    ans.sort()
    print(*ans)

Solution (Python):
def main():
    import sys
    input = sys.stdin.readline
    while True:
        N, W, D = map(int, input().split())
        if N == W == D == 0:
            break

        piece = [(W, D)]
        for _ in [0]*N:
            p, s = map(int, input().split())
            w, d = piece.pop(p-1)
            s %= w+d
            if s < w:
                w1 = min(s, w-s)
                w2 = w-w1
                piece.append((w1, d))
                piece.append((w2, d))
            else:
                s -= w
                d1 = min(s, d-s)
                d2 = d-d1
                piece.append((w, d1))
                piece.append((w, d2))

        piece.sort(key=lambda x: x[0]*x[1])
        print(*map(lambda x: x[0]*x[1], piece))


if __name__ == '__main__':
    main()

Solution (Python):
import bisect
while True:
  n,w,d=map(int,input().split())
  if n==w==d==0:break
  A=[w*d]
  B=[[0,w,w+d,2*w+d,2*w+2*d]]
  for _ in range(n):
    p,s=map(int,input().split())
    b=B.pop(p-1)
    S=A.pop(p-1)
    s%=b[-1]
    w=b[1]
    d=b[2]-w
    if bisect.bisect_left(b,s)%2:
      w1=s-b[bisect.bisect_left(b,s)-1]
      w2=w-w1
      d1,d2=d,d
    else:
      d1=s-b[bisect.bisect_left(b,s)-1]
      d2=d-d1
      w1,w2=w,w
    if w1*d1>w2*d2:
      A.append(w2*d2)
      A.append(w1*d1)
      B.append([0,w2,w2+d2,2*w2+d2,2*w2+2*d2])
      B.append([0,w1,w1+d1,2*w1+d1,2*w1+2*d1])
    else:
      A.append(w1*d1)
      A.append(w2*d2)
      B.append([0,w1,w1+d1,2*w1+d1,2*w1+2*d1])
      B.append([0,w2,w2+d2,2*w2+d2,2*w2+2*d2])
  print(*sorted(A))

Solution (Python):
while True:
    n,w,h = map(int,input().split())
    if w == 0:
        break
    ls = [[w,h]]
    for i in range(n):
        p,s = map(int,input().split())
        p -= 1
        pw,ph = ls[p]
        if s%(pw+ph) < pw:
            s %= pw+ph
            ls.extend([[min(s,pw-s),ph],[max(s,pw-s),ph]])
        else:
            s = (s-pw)%(ph+pw)
            ls.extend([[pw,min(s,ph-s)],[pw,max(s,ph-s)]])
        ls.pop(p)
    ans = [hi*wi for wi,hi in ls]
    ans.sort()
    print(' '.join(map(str,ans)))

Solution (Python):
while True:
    n,w,d = list(map(int,input().split()))
    if n == 0 and w == 0 and d == 0:
        exit()
    SP = [list(map(int,input().split())) for _ in range(n)]
    
    C = {}
    C[1] = {'height': d, 'width': w}
    
    for sp in SP:
        cake = C.pop(sp[0])
        p = sp[1]%(2*cake['width']+2*cake['height'])
        max_index = max(list(C.keys())+[0])
        if 0 < p < cake['width']:
            C[max_index+1] = {'height': cake['height'], 'width': min(p,cake['width']-p)}
            C[max_index+2] = {'height': cake['height'], 'width': max(p,cake['width']-p)}
        elif cake['width'] < p < cake['width']+cake['height']:
            C[max_index+1] = {'height': min(p-cake['width'],cake['width']+cake['height']-p), 'width': cake['width']}
            C[max_index+2] = {'height': max(p-cake['width'],cake['width']+cake['height']-p), 'width': cake['width']}
        elif cake['width']+cake['height'] < p < 2*cake['width']+cake['height']:
            C[max_index+1] = {'height': cake['height'], 'width': min(p-cake['width']-cake['height'],2*cake['width']+cake['height']-p)}
            C[max_index+2] = {'height': cake['height'], 'width': max(p-cake['width']-cake['height'],2*cake['width']+cake['height']-p)}
        else:
            C[max_index+1] = {'height': min(p-2*cake['width']-cake['height'],2*cake['width']+2*cake['height']-p), 'width': cake['width']}
            C[max_index+2] = {'height': max(p-2*cake['width']-cake['height'],2*cake['width']+2*cake['height']-p), 'width': cake['width']}
        
        new_C = {}
        for i,key in enumerate(sorted(C.keys())):
            new_C[i+1] = C[key]
        C = new_C
    
    ans = []
    for c in C.values():
        ans.append(c['height']*c['width'])
    print(*sorted(ans))

Solution (Python):
import sys
import itertools

import time
import math
import heapq
from collections import defaultdict
sys.setrecursionlimit(10 ** 7)
 
INF = 10 ** 9 + 7
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines



while True:
    N, W, D = map(int, input().split())
    if N == 0 and W == 0 and D == 0:
        break    
    cakes = [(W * D, W, D)]
    for i in range(N):
        p, s = map(int, input().split())
        _, w, d = cakes.pop(p - 1)
        s %= (2 * w + 2 * d)
        A = 0
        B = 0
        if s <= w:
            A = (s * d, s, d)
            B = ((w - s) * d, w - s, d)
        elif s <= w + d:
            y = s - w
            A = (w * y, w, y)
            B = (w * (d - y), w, (d - y))
        elif s <= 2 * w + d:
            x = 2 * w + d - s
            A = (x * d, x, d)
            B = ((w - x) * d, w - x, d)
        else:
            y = (2 * w + 2 * d) - s
            A = (w * y, w, y)
            B = (w * (d - y), w, (d - y))
        
        if A[0] > B[0]:
            A, B = B, A
        cakes.append(A)
        cakes.append(B)
    print(" ".join(map(lambda cake: str(cake[0]), sorted(cakes))))

Solution (Python):
N,W,D = map(int,input().split())

while W:
  cp = [[0,0,0,0] for _ in range(2*N+1)]	
  cp[0] = [0,0,W,D]
  
  for time in range(N):
    P,S = map(int,input().split())
    P -= 1
    ta = cp[P]
    S %= (ta[2]+ta[3])*2
    
    
    
    
    
    if 0 <= S < ta[2]:
      if S < ta[2]/2:
        cp[time+1] = [ta[0],ta[1],S,ta[3]]
        cp[time+2] = [ta[0]+S,ta[1],ta[2]-S,ta[3]]
      else:
        cp[time+1] = [ta[0]+S,ta[1],ta[2]-S,ta[3]]
        cp[time+2] = [ta[0],ta[1],S,ta[3]]
        
    
    elif S < ta[2]+ta[3]:
      S -= ta[2]
      if S < ta[3]/2:
        cp[time+1] = [ta[0],ta[1],ta[2],S]
        cp[time+2] = [ta[0],ta[1]+S,ta[2],ta[3]-S]
      else:
        cp[time+1] = [ta[0],ta[1]+S,ta[2],ta[3]-S]
        cp[time+2] = [ta[0],ta[1],ta[2],S]
        
    
    elif S < ta[2]*2+ta[3]:
      S = ta[2]-(S-ta[2]-ta[3])
      if S < ta[2]/2:
        cp[time+1] = [ta[0],ta[1],S,ta[3]]
        cp[time+2] = [ta[0]+S,ta[1],ta[2]-S,ta[3]]
      else:
        cp[time+1] = [ta[0]+S,ta[1],ta[2]-S,ta[3]]
        cp[time+2] = [ta[0],ta[1],S,ta[3]]
        
    
    else:
      S = ta[3]-(S-ta[2]*2-ta[3])
      if S < ta[3]/2:
        cp[time+1] = [ta[0],ta[1],ta[2],S]
        cp[time+2] = [ta[0],ta[1]+S,ta[2],ta[3]-S]
      else:
        cp[time+1] = [ta[0],ta[1]+S,ta[2],ta[3]-S]
        cp[time+2] = [ta[0],ta[1],ta[2],S]
        
    
    del cp[P]
    
    
  
  ansli = []
  for el in cp:
    ansli.append(el[2]*el[3])
  ansli.sort()
  print(*ansli)
  
  N,W,D = map(int,input().split())

Solution (Python):
while True:
    n, w, h = map(int, input().split())
    if w == 0:
        break
    ls = [[w, h]]
    for i in range(n):
        p, s = map(int, input().split())
        p -= 1
        pw, ph = ls[p]
        if s % (pw + ph) < pw:
            s %= pw + ph
            ls.extend([[min(s, pw - s), ph], [max(s, pw - s), ph]])
        else:
            s = (s - pw) % (ph + pw)
            ls.extend([[pw, min(s, ph - s)], [pw, max(s, ph - s)]])
        ls.pop(p)
    
    ans = sorted([hi * wi for wi, hi in ls])
    print(' '.join(map(str, ans)))

Solution (Python):
def cake(n, w, d):
  piece = [0] * (n + 1)
  piece[0] = [w, d, w * d]
  ps = [0] * n
  for i in range(n):
    
    p, s = map(int, input().split())
    now = piece[p - 1]
    nw, nd = now[0], now[1]
    s = s % (nw + nd)
    if p != i + 1:
      for j in range(p, i + 2):
        piece[j - 1] = piece[j]
    if s < nw:
      a, b = s, nw - s
      if a > b:
        piece[i + 1] = [a, nd, a * nd]
        piece[i] = [b, nd, b * nd]
      else:
        piece[i] = [a, nd, a * nd]
        piece[i + 1] = [b, nd, b * nd]   
        
    elif s < nw + nd:
      a, b = s - nw, nw + nd - s
      if a > b:
        piece[i] = [nw, b, b * nw]
        piece[i + 1] = [nw, a, a * nw]
      else:
        piece[i + 1] = [nw, b, b * nw]
        piece[i] = [nw, a, a * nw]
        
    elif s < 2 * nw + nd:
      a, b = s - nw - nd, 2 * nw + nd - s
      if a > b:
        piece[i + 1] = [a, nd, a * nd]
        piece[i] = [b, nd, b * nd]
      else:
        piece[i] = [a, nd, a * nd]
        piece[i + 1] = [b, nd, b * nd]   
        
    else:
      a, b = s - nw, nw + nd - s
      if a > b:
        piece[i] = [nw, b, b * nw]
        piece[i + 1] = [nw, a, a * nw]
      else:
        piece[i + 1] = [nw, b, b * nw]
        piece[i] = [nw, a, a * nw]
  return piece

p = True
while p:
  n, w, d = map(int, input().split())
  if (n, w, d) == (0, 0, 0):
    p = False
    quit()
  else:
    ans = cake(n, w, d)
    ans = sorted(ans, key = lambda x:x[2])
    for i in range(n + 1):
      if i!= n:
        print(ans[i][2], end = " ")
      else:
        print(ans[i][2])

Solution (Python):
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return map(int, input().split())
sys.setrecursionlimit(10**9)
while 1:
    N, W, D = mapint()
    if N==0 and W==0 and D==0:
        break
    cakes = [(W, D)]
    for i in range(N):
        p, s = mapint()
        w, h = cakes.pop(p-1)
        s = s%(w+h)
        if s<w:
            piece1, piece2 = (s, h), (w-s, h)
            if s>=w-s: piece1, piece2 = piece2, piece1
            cakes.append(piece1)
            cakes.append(piece2)
        else:
            s -= w
            piece1, piece2 = (w, s), (w, h-s)
            if s>=h-s: piece1, piece2 = piece2, piece1
            cakes.append(piece1)
            cakes.append(piece2)
    cakes = sorted(list(map(lambda x: x[0]*x[1], cakes)))
    cakes = list(map(str, cakes))
    print(' '.join(cakes))