Title: Lightest Mobile

Problem:
Mobiles are widely appreciated as moving works of art. The IOI Japanese Committee has decided to create a mobile to promote JOI. The JOI promotional mobile is composed of three elements: a rod, a string, and a weight. The rod has one end painted blue and the other end painted red. The rod is suspended by a string at one point other than the ends. The length from the suspension point to the red end and from the suspension point to the blue end is a positive integer. The rod's ends are suspended with a weight or another rod using a string. The weight is suspended at one end of a rod using a string. The weight is a positive integer. One of the strings is tied to the suspension point of a rod to suspend another rod, and the other end is not tied to any other component. The weight of the rod and string is negligible, so they are considered to have a weight of 0. Each rod must be balanced. The program should find a way to attach the weights to minimize the total weight of the mobile while keeping each rod balanced. The program should output the total weight of the mobile. The program is given the following information about the mobile's composition:
- Number of rods, n
- Information for each rod (rod number from 1 to n)
  - Ratio of length from the suspension point to the red end and from the suspension point to the blue end
  - Number of the rod suspended at the red end (0 if a weight is suspended)
  - Number of the rod suspended at the blue end (0 if a weight is suspended)

Input:
The input consists of multiple datasets. Each dataset is given in the following format and ends with a line containing a single 0.
- The first line contains the number of rods, n.
- The next n lines (1 ≤ n ≤ 100) contain data for each rod. The i-th line (1 ≤ i ≤ n) contains four integers p, q, r, b separated by a space, representing the ratio of length from the suspension point to the red end and from the suspension point to the blue end for rod i, the number of the rod suspended at the red end, and the number of the rod suspended at the blue end, respectively. Rod number 0 represents a weight suspended. For all inputs, let w be the minimum weight of the mobile and L be the maximum value of a positive integer used to represent a ratio in the input. It holds that wL < 2^31.

Output:
For each dataset, output the weight of the mobile on a separate line.

Input/Output Example:
Input:
1
6 9 0 0
4
3 2 0 4
1 3 0 0
4 4 2 1
2 2 0 0
0

Output:
5
40

# Buggy version:
from math import gcd
while True:
  try:
    n = int(input())
    if not n: break
    lst = [[]]
    weight = [-1 for i in range(n + 1)]
    def setWeight(n):
      p,q,r,b = lst[n]
      if weight[n] != -1:pass
      elif r == 0 and b == 0:
        weight[n] = (p + q) // gcd(p,q)
      elif r == 0:
        setWeight(b)
        wb = weight[b]
        g = gcd(wb * q, p)
        lcm = wb * q * p // g
        weight[n] = lcm // q + lcm // p
        print("wr:",str(lcm//p),"wb:",str(wb),"g:",g,"p:",p,"lcm",lcm)
      elif b == 0:
        setWeight(r)
        wr = weight[r]
        g = gcd(wr * p, q)
        lcm = wr * p * q // g
        weight[n] = lcm // p + lcm // q
      else:
        if weight[r] == -1: setWeight(r)
        if weight[b] == -1: setWeight(b)
        wr = weight[r]
        wb = weight[b]
        g = gcd(wr * p, wb * q)
        lcm = wr * p * wb  * q // g
        weight[n] = lcm // p + lcm // q
    for i in range(n):
      lst.append(list(map(int,input().split())))
    for i in range(0,n):
      if weight[i + 1] == -1:
        setWeight(i+1)
    print(max(weight))
    print(weight)
  except EOFError:
    break




# Fixed version:
from math import gcd
while True:
  try:
    n = int(input())
    if not n: break
    lst = [[]]
    weight = [-1 for i in range(n + 1)]
    def setWeight(n):
      p,q,r,b = lst[n]
      if weight[n] != -1:pass
      elif r == 0 and b == 0:
        weight[n] = (p + q) // gcd(p,q)
      elif r == 0:
        setWeight(b)
        wb = weight[b]
        g = gcd(wb * q, p)
        lcm = wb * q * p // g
        weight[n] = lcm // q + lcm // p
#        print("wr:",str(lcm//p),"wb:",str(wb),"g:",g,"p:",p,"lcm",lcm)
      elif b == 0:
        setWeight(r)
        wr = weight[r]
        g = gcd(wr * p, q)
        lcm = wr * p * q // g
        weight[n] = lcm // p + lcm // q
      else:
        if weight[r] == -1: setWeight(r)
        if weight[b] == -1: setWeight(b)
        wr = weight[r]
        wb = weight[b]
        g = gcd(wr * p, wb * q)
        lcm = wr * p * wb  * q // g
        weight[n] = lcm // p + lcm // q
    for i in range(n):
      lst.append(list(map(int,input().split())))
    for i in range(0,n):
      if weight[i + 1] == -1:
        setWeight(i+1)
    print(max(weight))
#    print(weight)
  except EOFError:
    break