Problem:
Problem Statement You want to compete in ICPC (Internet Contest of Point Collection).
In this contest, we move around in $N$ websites, numbered $1$ through $N$, within a time limit and collect points as many as possible.
We can start and end on any website.  There are $M$ links between the websites, and we can move between websites using these links.
You can assume that it doesn't take time to move between websites.
These links are directed and websites may have links to themselves.  In each website $i$, there is an advertisement and we can get $p_i$ point(s) by watching this advertisement in $t_i$ seconds.
When we start on or move into a website, we can decide whether to watch the advertisement or not.
But we cannot watch the same advertisement more than once before using any link in the website, while we can watch it again if we have moved among websites and returned to the website using one or more links, including ones connecting a website to itself.
Also we cannot watch the advertisement in website $i$ more than $k_i$ times.  You want to win this contest by collecting as many points as you can.
So you decided to compute the maximum points that you can collect within $T$ seconds.  Input  The input consists of multiple datasets.
The number of dataset is no more than $60$.  Each dataset is formatted as follows.  $N$ $M$ $T$ $p_1$ $t_1$ $k_1$ : : $p_N$ $t_N$ $k_N$ $a_1$ $b_1$ : : $a_M$ $b_M$  The first line of each dataset contains three integers $N$ ($1 \le N \le 100$), $M$ ($0 \le M \le 1{,}000$) and $T$ ($1 \le T \le 10{,}000$), which denote the number of websites, the number of links, and the time limit, respectively.
All the time given in the input is expressed in seconds.  The following $N$ lines describe the information of advertisements.
The $i$-th of them contains three integers $p_i$ ($1 \le p_i \le 10{,}000$), $t_i$ ($1 \le t_i \le 10{,}000$) and $k_i$ ($1 \le k_i \le 10{,}000$), which denote the points of the advertisement, the time required to watch the advertisement, and the maximum number of times you can watch the advertisement in website $i$, respectively.  The following $M$ lines describe the information of links.
Each line contains two integers $a_i$ and $b_i$ ($1 \le a_i,b_i \le N$), which mean that we can move from website $a_i$ to website $b_i$ using a link.  The end of input is indicated by a line containing three zeros.  Output  For each dataset, output the maximum points that you can collect within $T$ seconds.  Sample Input  5 4 10
4 3 1
6 4 3
3 2 4
2 2 1
8 5 3
1 2
2 3
3 4
4 5
3 3 1000
1000 1 100
1 7 100
10 9 100
1 2
2 3
3 2
1 0 5
25 25 2
1 0 25
25 25 2
5 5 100
1 1 20
1 1 20
10 1 1
10 1 1
10 1 1
1 2
2 1
3 4
4 5
5 3
3 3 100
70 20 10
50 15 20
90 10 10
1 2
2 2
2 3
0 0 0  Output for the Sample Input  15
2014
0
25
40
390

Solution (Python):
from collections import deque
import sys
readline = sys.stdin.readline
write = sys.stdout.write

def scc(N, G, RG):
    order = []
    used = [0]*N
    group = [None]*N
    def dfs(s):
        used[s] = 1
        for t in G[s]:
            if not used[t]:
                dfs(t)
        order.append(s)
    def rdfs(s, col):
        group[s] = col
        used[s] = 1
        for t in RG[s]:
            if not used[t]:
                rdfs(t, col)
    for i in range(N):
        if not used[i]:
            dfs(i)
    used = [0]*N
    label = 0
    for s in reversed(order):
        if not used[s]:
            rdfs(s, label)
            label += 1
    return label, group

def construct(N, G, label, group):
    G0 = [set() for i in range(label)]
    RG0 = [set() for i in range(label)]
    GP = [[] for i in range(label)]
    for v in range(N):
        lbs = group[v]
        for w in G[v]:
            lbt = group[w]
            if lbs == lbt:
                continue
            G0[lbs].add(lbt)
            RG0[lbt].add(lbs)
        GP[lbs].append(v)
    return G0, RG0, GP

def solve():
    N, M, T = map(int, readline().split())
    if N == M == T == 0:
        return False
    V = [0]*N; W = [0]*N; C = [0]*N
    for i in range(N):
        V[i], W[i], C[i] = map(int, readline().split())
    G = [[] for i in range(N)]
    RG = [[] for i in range(N)]
    SL = [0]*N
    for i in range(M):
        a, b = map(int, readline().split())
        if a == b:
            SL[a-1] = 1
        else:
            G[a-1].append(b-1)
            RG[b-1].append(a-1)
    label, group = scc(N, G, RG)
    G0, RG0, GP = construct(N, G, label, group)

    INF = 10**18
    dp = [None]*label
    zeros = [0] + [-INF]*T

    que = deque()
    deg = [0]*label
    for i in range(label):
        if len(RG0[i]) == 0:
            que.append(i)
            dp[i] = zeros[:]
        deg[i] = len(RG0[i])

    ans = 0
    dp1 = [0]*(T+1)
    while que:
        v = que.popleft()
        dp0 = dp[v]
        if len(GP[v]) == 1 and not SL[GP[v][0]]:
            e, = GP[v]
            ve = V[e]; we = W[e]
            for i in range(T, we-1, -1):
                dp0[i] = max(dp0[i], dp0[i-we] + ve)
        else:
            deq = deque()
            push = deq.append
            popl = deq.popleft
            pop = deq.pop
            clear = deq.clear
            for e in GP[v]:
                ve = V[e]; we = W[e]; ce = C[e]
                if T < we:
                    continue
                if ce == 1:
                    for i in range(T, we-1, -1):
                        dp0[i] = max(dp0[i], dp0[i-we] + ve)
                elif T <= we*ce:
                    for i in range(we, T+1):
                        dp0[i] = max(dp0[i], dp0[i-we] + ve)
                else:
                    for k in range(we):
                        for i in range((T - k) // we + 1):
                            v0 = dp0[k] - i*ve
                            while deq and deq[-1][1] <= v0:
                                pop()
                            push((i, v0))

                            dp0[k] = deq[0][1] + i*ve

                            if deq[0][0] == i-ce:
                                popl()
                            k += we
                        clear()
        ans = max(ans, max(dp0))

        for w in G0[v]:
            deg[w] -= 1
            if deg[w] == 0:
                que.append(w)
            if dp[w] is None:
                dp[w] = dp0[:]
            else:
                dp[w][:] = (max(p, q) for p, q in zip(dp[w], dp0))
    write("%d\n" % ans)
    return True
while solve():
    ...