Problem:
Problem Statement
You are now participating in the Summer Training Camp for Programming Contests with your friend Jiro, who is an enthusiast of the ramen chain SIRO.
Since every SIRO restaurant has its own tasteful ramen, he wants to try them at as many different restaurants as possible in the night.
He doesn't have plenty of time tonight, however, because he has to get up early in the morning tomorrow to join a training session.
So he asked you to find the maximum number of different restaurants to which he would be able to go to eat ramen in the limited time.
There are $n$ railway stations in the city, which are numbered $1$ through $n$. The station $s$ is the nearest to the camp venue.
$m$ pairs of stations are directly connected by the railway: you can move between the stations $a_i$ and $b_i$ in $c_i$ minutes in the both directions.
Among the stations, there are $l$ stations where a SIRO restaurant is located nearby. There is at most one SIRO restaurant around each of the stations, and there are no restaurants near the station $s$.
It takes $e_i$ minutes for Jiro to eat ramen at the restaurant near the station $j_i$.
It takes only a negligibly short time to go back and forth between a station and its nearby SIRO restaurant.
You can also assume that Jiro doesn't have to wait for the ramen to be served in the restaurants.
Jiro is now at the station $s$ and have to come back to the station in $t$ minutes. How many different SIRO's can he taste?
Input
The input is a sequence of datasets. The number of the datasets does not exceed $100$. Each dataset is formatted as follows:
$n$ $m$ $l$ $s$ $t$
$a_1$ $b_1$ $c_1$
:
:
$a_m$ $b_m$ $c_m$
$j_1$ $e_1$
:
:
$j_l$ $e_l$
The first line of each dataset contains five integers:
$n$ for the number of stations,
$m$ for the number of directly connected pairs of stations,
$l$ for the number of SIRO restaurants,
$s$ for the starting-point station, and
$t$ for the time limit for Jiro.
Each of the following $m$ lines contains three integers:
$a_i$ and $b_i$ for the connected stations, and
$c_i$ for the time it takes to move between the two stations.
Each of the following $l$ lines contains two integers:
$j_i$ for the station where a SIRO restaurant is located, and
$e_i$ for the time it takes for Jiro to eat at the restaurant.
The end of the input is indicated by a line with five zeros, which is not included in the datasets.
The datasets satisfy the following constraints:
$2 \le n \le 300$
$1 \le m \le 5{,}000$
$1 \le l \le 16$
$1 \le s \le n$
$1 \le t \le 100{,}000$
$1 \le a_i, b_i \le n$
$1 \le c_i \le 1{,}000$
$1 \le j_i \le n$
$1 \le e_i \le 15$
$s \ne j_i$
$j_i$'s are distinct.
$a_i \ne b_i$
$(a_i, b_i) \ne (a_j, b_j)$ and $(a_i, b_i) \ne (b_j, a_j)$ for any $i \ne j$
Note that there may be some stations not reachable from the starting point $s$.
Output
For each data set, output the maximum number of different restaurants where Jiro can go within the time limit.
Sample Input
2 1 1 1 10
1 2 3
2 4
2 1 1 1 9
1 2 3

...(truncated)

Submitted solutions:

code_snippet: #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <bitset>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define FI first
#define SE second
using namespace std;
typedef long long LL;
int G[305][305];
int D[20][20],siro[20],cost[20];
int dp[17][1<<16],bit[1<<16];
bool done[17][1<<16];
struct node
{
    int u,st,dis;
    inline node(int _u=0,int _st=0,int _dis=0)
    {
        u=_u; st=_st; dis=_dis;
    }
    inline bool operator <(const node &a)const
    {
        return dis>a.dis;
    }
};
priority_queue <node> Q;

inline void Dijkstra(int n,int t)
{
    memset(dp,0x3f,sizeof(dp));
    memset(done,0,sizeof(done));
    dp[0][0]=0;
    Q.push(node(0,0,0));
    node u;
    while(!Q.empty())
    {
        u=Q.top(); Q.pop();
        if(done[u.u][u.st]) continue;
        done[u.u][u.st]=1;
        for(int i=1;i<=n;++i) if(D[u.u][i]!=INF)
        {
            if(u.st&(1<<(i-1))) continue;
            int v=u.dis+D[u.u][i]+cost[i];
            if(v+D[0][i]>t) continue;
            int nst=u.st|(1<<(i-1));
            if(dp[i][nst]>v)
            {
                dp[i][nst]=v;
                Q.push(node(i,nst,v));
            }
        }
    }
    int res=0;
    for(int i=1;i<=n;++i)
        for(int j=(1<<n)-1;j>=0;--j)
            if(dp[i][j]+D[0][i]<=t) res=max(res,bit[j]);
    printf("%d\n",res);
}

inline int bit_count(int st)
{
    int res=0;
    for(;st;st^=st&-st) ++res;
    return res;
}

int main()
{
    for(int i=(1<<16)-1;i>=0;--i) bit[i]=bit_count(i);
    int n,m,l,s,t;
    while(scanf("%d%d%d%d%d",&n,&m,&l,&s,&t)&&n)
    {
        for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) G[i][j]=INF;
        while(m--)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            G[u][v]=G[v][u]=w;
        }
        for(int k=1;k<=n;++k)
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                {
                    if(k==i||k==j||i==j) continue;
                    G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
                }
        for(int i=1;i<=l;++i) scanf("%d%d",siro+i,cost+i);
        siro[0]=s;
        memset(D,0x3f,sizeof(D));
        for(int i=0;i<=l;++i)
            for(int j=i+1;j<=l;++j)
                D[i][j]=D[j][i]=G[siro[i]][siro[j]];
        Dijkstra(l,t);
    }
    return 0;
}
accuracy: 1
time_ms: 1400
memory_kb: 15736
final_rank: 11

code_snippet: #include <bits/stdc++.h>

struct node {
    int c, x, s;
    node(int _c, int _x, int _s): c(_c), x(_x), s(_s) {}
    bool operator < (const node &rhs) const {
        return c > rhs.c;
    }
};

std::vector<std::pair<int, int> > edges[310];

int floyd[310][310];
int dist[20][(1 << 16) + 10];
int eat[20];

int dij(int src, int limit) {
    std::priority_queue<node > q;
    memset(dist, 0x3f, sizeof dist);
    dist[src][0] = 0;
    q.emplace(0, src, 0);
    int ans = 0;
    while(!q.empty()) {
        auto now = q.top();
        q.pop();
        if(dist[now.x][now.s] < now.c) {
            continue;
        }
        for(auto next: edges[now.x]) {
            int new_d = dist[now.x][now.s] + next.second;
            int new_s = now.s;
            if(next.first < src && ((now.s >> next.first) & 1) == 0) {
                 new_d += eat[next.first];
                 new_s |= (1 << next.first);
            }
            if(dist[next.first][new_s] > new_d) {
                //printf("%d__%d__%d %d\n", next.first == src, new_s, new_d <= limit, dist[next.first][new_s]);
                if(next.first == src && new_d <= limit && __builtin_popcount(new_s) > ans) {
                    ans = __builtin_popcount(new_s);
                }
                dist[next.first][new_s] = new_d;
                q.emplace(new_d, next.first, new_s);
            }
        }
    }
    return ans;
}

void MAIN(int n, int m, int l, int s, int t) {
    memset(floyd, 0x3f, sizeof floyd);
    for(int i = 0; i < n; ++ i) {
        floyd[i][i] = 0;
    }
    for(int i = 0; i < m; ++ i) {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        -- u, -- v;
        floyd[u][v] = floyd[v][u] = c;
    }
    for(int k = 0; k < n; ++ k) {
        for(int i = 0; i < n; ++ i) {
            for(int j = 0; j < n; ++ j) {
                floyd[i][j] = std::min(floyd[i][j], floyd[i][k] + floyd[k][j]);
            }
        }
    }
    std::vector<int> special(l);
    for(int i = 0; i < l; ++ i) {
        scanf("%d", &special[i]);
        -- special[i];
        scanf("%d", &eat[i]);
    }
    for(int i = 0; i < n; ++ i) {
        edges[i].clear();
    }
    -- s;
    for(int i = 0; i < (int)special.size(); ++ i) {
        for(int j = 0; j < (int)special.size(); ++ j) {
            if(i == j) {
                continue;
            }
            edges[i].emplace_back(j, floyd[special[i]][special[j]]);
        }
        edges[special.size()].emplace_back(i, floyd[s][special[i]]);
        edges[i].emplace_back(special.size(), floyd[s][special[i]]);
    }
    printf("%d\n", dij(special.size(), t));
}

int main() {
    int n, m, l, s, t;
    while(scanf("%d%d%d%d%d", &n, &m, &l, &s, &t) == 5 && !(!n && !m && !l && !s && !t)) {
        MAIN(n, m, l, s, t);
    }
    return 0;
}
accuracy: 1
time_ms: 2840
memory_kb: 20972
final_rank: 20

code_snippet: #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <bitset>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define FI first
#define SE second
using namespace std;
typedef long long LL;
int G[305][305];
int D[20][20],siro[20],cost[20];
int dp[17][1<<16],bit[1<<16];
bool done[17][1<<16];
struct node
{
    int u,st,dis;
    inline node(int _u=0,int _st=0,int _dis=0)
    {
        u=_u; st=_st; dis=_dis;
    }
    inline bool operator <(const node &a)const
    {
        return dis>a.dis;
    }
};
priority_queue <node> Q;

inline void Dijkstra(int n,int t)
{
    memset(dp,0x3f,sizeof(dp));
    memset(done,0,sizeof(done));
    dp[0][0]=0;
    Q.push(node(0,0,0));
    node u;
    while(!Q.empty())
    {
        u=Q.top(); Q.pop();
        if(done[u.u][u.st]) continue;
        done[u.u][u.st]=1;
        for(int i=1;i<=n;++i) if(D[u.u][i]!=INF)
        {
            if(u.st&(1<<(i-1))) continue;
            int v=u.dis+D[u.u][i]+cost[i];
            if(v+D[0][i]>t) continue;
            int nst=u.st|(1<<(i-1));
            if(dp[i][nst]>v)
            {
                dp[i][nst]=v;
                Q.push(node(i,nst,v));
            }
        }
    }
    int res=0;
    for(int i=1;i<=n;++i)
        for(int j=(1<<n)-1;j>=0;--j)
            if(dp[i][j]+D[0][i]<=t) res=max(res,bit[j]);
    printf("%d\n",res);
}

inline int bit_count(int st)
{
    int res=0;
    for(;st;st^=st&-st) ++res;
    return res;
}

int main()
{
    for(int i=(1<<16)-1;i>=0;--i) bit[i]=bit_count(i);
    int n,m,l,s,t;
    while(scanf("%d%d%d%d%d",&n,&m,&l,&s,&t)&&n)
    {
        for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) G[i][j]=INF;
        while(m--)
        {
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            G[u][v]=G[v][u]=w;
        }
        for(int k=1;k<=n;++k)
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                {
                    if(k==i||k==j||i==j) continue;
                    G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
                }
        for(int i=1;i<=l;++i) scanf("%d%d",siro+i,cost+i);
        siro[0]=s;
        memset(D,0x3f,sizeof(D));
        for(int i=0;i<=l;++i)
            for(int j=i+1;j<=l;++j)
                D[i][j]=D[j][i]=G[siro[i]][siro[j]];
        Dijkstra(l,t);
    }
    return 0;
}
accuracy: 1
time_ms: 1400
memory_kb: 17080
final_rank: 14

code_snippet: // AOJ #2567
// SIRO Challenge 2025.2.2

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const ll INF = 1e18;

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

    while (true) {
        int n, m, l, s, t;
        cin >> n >> m >> l >> s >> t;
        if (n == 0 && m == 0 && l == 0 && s == 0 && t == 0) break;

        vector<vector<ll>> dist(n + 1, vector<ll>(n + 1, INF));
        for (int i = 1; i <= n; ++i) {
            dist[i][i] = 0;
        }
        for (int i = 0; i < m; ++i) {
            int a, b, c;
            cin >> a >> b >> c;
            if (dist[a][b] > c) {
                dist[a][b] = c;
                dist[b][a] = c;
            }
        }

        // Floyd-Warshall algorithm to compute all-pairs shortest paths
        for (int k = 1; k <= n; ++k) {
            for (int i = 1; i <= n; ++i) {
                for (int j = 1; j <= n; ++j) {
                    if (dist[i][k] != INF && dist[k][j] != INF) {
                        if (dist[i][j] > dist[i][k] + dist[k][j]) {
                            dist[i][j] = dist[i][k] + dist[k][j];
                        }
                    }
                }
            }
        }

        vector<pair<int, int>> rest_list;
        for (int i = 0; i < l; ++i) {
            int j, e;
            cin >> j >> e;
            if (j != s && dist[s][j] < INF) {
                rest_list.emplace_back(j, e);
            }
        }
        l = rest_list.size();

        if (l == 0) {
            cout << 0 << endl;
            continue;
        }

        vector<vector<ll>> dp(1 << l, vector<ll>(l, INF));
        for (int i = 0; i < l; ++i) {
            int station = rest_list[i].first;
            int eat_time = rest_list[i].second;
            dp[1 << i][i] = dist[s][station] + eat_time;
        }

        vector<vector<int>> masks_by_bits(l + 1);
        for (int mask = 0; mask < (1 << l); ++mask) {
            int cnt = __builtin_popcount(mask);
            if (cnt >= 1 && cnt <= l) {
                masks_by_bits[cnt].push_back(mask);
            }
        }

        for (int cnt = 1; cnt <= l; ++cnt) {
            for (int mask : masks_by_bits[cnt]) {
                for (int u = 0; u < l; ++u) {
                    if (!(mask & (1 << u)) || dp[mask][u] == INF) {
                        continue;
                    }
                    for (int v = 0; v < l; ++v) {
                        if (mask & (1 << v)) {
                            continue;
                        }
                        int new_mask = mask | (1 << v);
                        ll travel = dist[rest_list[u].first][rest_list[v].first];
                        ll new_time = dp[mask][u] + travel + rest_list[v].second;
                        if (new_time < dp[new_mask][v]) {
                            dp[new_mask][v] = new_time;
                        }
                    }
                }
            }
        }

        int max_count = 0;
        for (int mask = 0; mask < (1 << l); ++mask) {
            if (mask == 0) continue;
            int cnt = __builtin_popcount(mask);
            if (cnt <= max_count) continue;

            ll min_total = INF;
            for (int u = 0; u < l; ++u) {
                if (mask & (1 << u)) {
                    ll back = dist[rest_list[u].first][s];
                    min_total = min(min_total, dp[mask][u] + back);
                }
            }

            if (min_total <= t) max_count = cnt;
        }
        cout << max_count << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 890
memory_kb: 15180
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

vector<int> MakeDist(vector<vector<pair<int,int>>>& G, int S) {
    int N = G.size();
    vector<int> Ret(N,inf);
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> PQ;
    Ret[S] = 0;
    PQ.push({0,S});
    while(!PQ.empty()) {
        auto [D,V] = PQ.top();
        PQ.pop();
        if (Ret[V] < D) continue;
        for (pair<int,int> P : G[V]) {
            auto [DD,NV] = P;
            int ND = D + DD;
            if (chmin(Ret[NV],ND)) {
                PQ.push({ND,NV});
            }
        }
    }
    return Ret;
}

int main() {
while(1) {
    int N, M, L, S, T;
    cin >> N >> M >> L >> S >> T;
    if (N == 0) return 0;
    S--;
    vector<vector<pair<int,int>>> G(N);
    rep(i,0,M) {
        int A, B, C;
        cin >> A >> B >> C;
        A--, B--;
        G[A].push_back({C,B});
        G[B].push_back({C,A});
    }
    vector<int> J(L), E(L);
    rep(i,0,L) cin >> J[i] >> E[i], J[i]--;
    vector<int> DS = MakeDist(G,S);
    vector<vector<int>> H(L,vector<int>(L));
    rep(i,0,L) {
        auto D = MakeDist(G,J[i]);
        rep(j,0,L) H[i][j] = D[J[j]];
    }
    vector<vector<int>> DP(1<<L,vector<int>(L,inf));
    rep(i,0,L) DP[1<<i][i] = DS[J[i]];
    rep(i,1,1<<L) {
        rep(j,0,L) {
            if (DP[i][j] == inf) continue;
            rep(k,0,L) {
                if (i & (1<<k)) continue;
                chmin(DP[i|(1<<k)][k],DP[i][j]+H[j][k]);
            }
        }
    }
    int ANS = 0;
    rep(i,1,1<<L) {
        rep(j,0,L) {
            if (i & (1<<j)) {
                ll D = DP[i][j]+DS[J[j]];
                rep(k,0,L) {
                    if (i & (1<<k)) D += E[k];
                }
                if (D<=T) {
                    chmax(ANS,popcnt(i));
                }
            }
        }
    }
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 860
memory_kb: 9684
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

void warshall_floyd(vector<vector<ll>> &d) {
	int n=d.size();
	for (int k = 0; k < n; k++) {  
		for (int i = 0; i < n; i++) {  
			for (int j = 0; j < n; j++) {
				d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
			}
		}
	}
}

ll N,M,L,S,T;
void solve(){
    S--;
    vector<vector<pair<ll,ll>>> G(N);
    vector<vector<ll>> dist(N,vector<ll>(N,1e18));
    for(int i=0;i<N;i++){dist[i][i]=0;}
    for(int i=0;i<M;i++){
        ll a,b,c;
        cin>>a>>b>>c;
        a--;b--;
        dist[a][b]=c;
        dist[b][a]=c;
    }
    warshall_floyd(dist);
    vector<ll> P(L+1,S),Q(L);
    for(int i=0;i<L;i++){
        cin>>P[i]>>Q[i];
        P[i]--;
    }

    vector<vector<ll>> DP(1<<(L+1),vector<ll>(L+1,1e18));
    DP[1<<L][L]=0;
    ll an=0;
    for(int bit=0;bit<(1<<(L+1));bit++){
        for(int n=0;n<=L;n++){
            if(DP[bit][n]>T)continue;
            if(DP[bit][n]+dist[P[n]][S]<=T){
                an=max(an,ll(__builtin_popcount(bit)));
            }
            for(int j=0;j<L;j++){
                if(bit&(1<<j))continue;
                ll nc=DP[bit][n]+dist[P[n]][P[j]]+Q[j];
                ll nb=bit+(1<<j);
                DP[nb][j]=min(DP[nb][j],nc);
            }
        }
    }
    cout<<an-1<<endl;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while(cin>>N>>M>>L>>S>>T,N+M!=0)solve();
    
}
accuracy: 1
time_ms: 620
memory_kb: 25452
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

void warshall_floyd(vector<vector<ll>> &d) {
	int n=d.size();
	for (int k = 0; k < n; k++) {  
		for (int i = 0; i < n; i++) {  
			for (int j = 0; j < n; j++) {
				d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
			}
		}
	}
}

ll N,M,L,S,T;
void solve(){
    S--;
    vector<vector<pair<ll,ll>>> G(N);
    vector<vector<ll>> dist(N,vector<ll>(N,1e18));
    for(int i=0;i<N;i++){dist[i][i]=0;}
    for(int i=0;i<M;i++){
        ll a,b,c;
        cin>>a>>b>>c;
        a--;b--;
        dist[a][b]=c;
        dist[b][a]=c;
    }
    warshall_floyd(dist);
    vector<ll> P(L+1,S),Q(L);
    for(int i=0;i<L;i++){
        cin>>P[i]>>Q[i];
        P[i]--;
    }

    vector<vector<ll>> DP(1<<(L+1),vector<ll>(L+1,1e18));
    DP[1<<L][L]=0;
    ll an=0;
    for(int bit=0;bit<(1<<(L+1));bit++){
        for(int n=0;n<=L;n++){
            if(DP[bit][n]>T)continue;
            if(DP[bit][n]+dist[P[n]][S]<=T){
                an=max(an,ll(__builtin_popcount(bit)));
            }
            for(int j=0;j<L;j++){
                if(bit&(1<<j))continue;
                ll nc=DP[bit][n]+dist[P[n]][P[j]]+Q[j];
                ll nb=bit+(1<<j);
                DP[nb][j]=min(DP[nb][j],nc);
            }
        }
    }
    cout<<an-1<<endl;
}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    while(cin>>N>>M>>L>>S>>T,N+M!=0)solve();
    
}
accuracy: 1
time_ms: 630
memory_kb: 25316
final_rank: 16

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

int solve(int n, int m, int l, int s, int t) {
    s--;
    const int INF = 1e9;
    vector D(n, vector(n, INF));
    for(int i : rep(n)) D[i][i] = 0;
    for(int i : rep(m)) {
        int a = in(), b = in(), c = in(); a--, b--;
        D[a][b] = D[b][a] = c;
    }

    for(int k : rep(n)) for(int i : rep(n)) for(int j : rep(n)) chmin(D[i][j], D[i][k] + D[k][j]);

    vector<int> j(l), e(l);
    for(int i : rep(l)) j[i] = in(), e[i] = in(), j[i]--;

    vector dp(1 << l, vector(l, INF));
    for(int v : rep(l)) dp[1 << v][v] = D[s][j[v]] + e[v];
    for(int S : rep(1 << l)) {
        for(int u : rep(l)) if(S & (1 << u)) {
            for(int v : rep(l)) if(!(S & (1 << v))) {
                chmin(dp[S | (1 << v)][v], dp[S][u] + D[j[u]][j[v]] + e[v]);
            }
        }
    }

    int ans = 0;
    for(int v : rep(l)) {
        for(int S : rep(1 << l)) if(S & (1 << v)) {
            if(dp[S][v] + D[j[v]][s] <= t) {
                chmax(ans, popcnt(S));
            }
        }
    }
    return ans;
}

int main() {
    while(true) {
        int n = in(), m = in(), l = in(), s = in(), t = in();
        if(make_tuple(n, m, l, s, t) == make_tuple(0, 0, 0, 0, 0)) return 0;
        print(solve(n, m, l, s, t));
    }
}
accuracy: 1
time_ms: 940
memory_kb: 10168
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
// clang-format off
struct Init { Init() { ios::sync_with_stdio(0); cin.tie(0); } }init;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<vector<int>> Graph;

#define rep(i, x, limit) for (int i = (int)x; i < (int)limit; i++)
#define REP(i, x, limit) for (int i = (int)x; i <= (int)limit; i++)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define el '\n'
#define spa " "
#define YES cout << "Yes" << el
#define NO cout << "No" << el
#define eps (1e-10)
#define Equals(a,b) (fabs((a) - (b)) < eps )

const double pi = 3.141592653589793238;
const int inf = 1073741823;
const ll infl = 1LL << 60;

//配列の要素を空白区切りで出力
template<class T> inline void print_vec(const vector<T>& v) {
    if(v.empty()){
        cout << "This vector is empty." << el;
        return;
    }
    for (int i = 0; i < v.size(); i++) {
        if(v[i]==inf || v[i]==infl) cout << 'x' << spa;
        else cout << v[i] << spa;
    }
    cout << el;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
// clang-format on

//--------------------------------------------------------
int main() {
    while(true){
        int n,m,l,s,t;
        cin >> n >> m >> l >> s >> t;
        if(n == 0) return 0;
        s--;

        vector<vector<ll>> g(n,vector<ll>(n,inf));
        rep(i,0,n) g[i][i] = 0;
        rep(i,0,m){
            int a,b,c;
            cin >> a >> b >> c;
            a--,b--;
            g[a][b] = c;
            g[b][a] = c;
        }

        rep(k,0,n){
            rep(i,0,n){
                rep(j,0,n){
                    chmin(g[i][j], g[i][k] + g[k][j]);
                }
            }
        }

        // first = near_station, second = time to eat
        vector<pii> rests(l);
        rep(i,0,l){
            int j,e;
            cin >> j >> e;
            j--;
            rests[i] = make_pair(j,e);
        }

        int L = (1<<l);
        vector<vector<ll>> dp(L,vector<ll>(l,inf));
        rep(i,0,l){
            int to = (1<<i);
            int to_pos = rests[i].first;
            dp[to][i] = g[s][to_pos]+g[to_pos][s];
        }
        rep(bit,0,L){
            rep(i,0,l){
                if(dp[bit][i] >= inf) continue;
                int now_pos = rests[i].first;
                rep(j,0,l){
                    int to = (1<<j);
                    int to_pos = rests[j].first;
                    if((bit&to) == 0){
                        chmin(dp[bit+to][j], dp[bit][i]+g[now_pos][to_pos]-g[now_pos][s]+g[to_pos][s]);
                    }
                }
            }
        }

        vector<ll> dists(L,inf);
        rep(bit,0,L){
            rep(i,0,l) chmin(dists[bit], dp[bit][i]);
        }
        
        int ans = 0;
        rep(bit,1,L){
            int cnt = __builtin_popcount(bit);
            ll eat_sum = 0;
            rep(i,0,l){
                if(bit&(1<<i)) eat_sum += rests[i].second;
            }
            if(dists[bit]+eat_sum <= t) chmax(ans,cnt);
        }
        cout << ans << el;
    }
}
accuracy: 1
time_ms: 860
memory_kb: 15100
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, deque<T> P)
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T> ostream& operator << (ostream &s, set<T> P)
{ for(auto it : P) { s << "<" << it << "> "; } return s; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)
{ for(auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s; }

using Edge = pair<int, long long>;
using Graph = vector<vector<Edge>>;
const long long INF = 1LL<<60;

// 頂点 s を始点としたグラフ探索
vector<long long> Dijkstra(const Graph &G, int s) {
    vector<long long> dist(G.size(), INF);
    dist[s] = 0;
    priority_queue<pair<long long,int>, vector<pair<long long,int>>, greater<pair<long long,int>>> que;
    que.push({0, s});
    while (!que.empty()) {
        auto [cur, v] = que.top();
        que.pop();
        if (dist[v] < cur) continue;
        for (const auto &e : G[v]) {
            if (chmin(dist[e.first], dist[v] + e.second)) {
                que.push({dist[e.first], e.first});
            }
        }
    }
    return dist;
}

int solve(int N, int M, int L, int S, int T) {
    --S;
    Graph G(N);
    for (int i = 0; i < M; ++i) {
        long long a, b, c;
        cin >> a >> b >> c;
        --a, --b;
        G[a].emplace_back(b, c);
        G[b].emplace_back(a, c);
    }
    
    // SIRO info
    vector<long long> J(L), E(L);
    for (int i = 0; i < L; ++i) {
        cin >> J[i] >> E[i];
        --J[i];
    }
    J.push_back(S), E.push_back(0);
    int s = L++;

    // make graph
    vector<vector<long long>> G2(L, vector<long long>(L, INF));
    for (int i = 0; i < L; ++i) {
        const auto &dist = Dijkstra(G, J[i]);
        for (int j = 0; j < L; ++j) G2[i][j] = dist[J[j]];
    }
    
    //COUT(J); COUT(E); COUT(G2);
    
    // bit DP: dp[S][v] := 頂点集合 S をすべて通って、最後にいる頂点が v であるときの、最小コスト
    vector<vector<long long>> dp(1<<L, vector<long long>(L, INF));
    dp[1<<s][s] = 0;
    for (int bit = 0; bit < (1<<L); ++bit) {
        for (int v = 0; v < L; ++v) {
            for (int v2 = 0; v2 < L; ++v2) {
                int nbit = bit | (1<<v2);
                dp[nbit][v2] = min(dp[nbit][v2], dp[bit][v] + G2[v][v2] + E[v2]);
            }
        }
    }
    
    // dp[bit][g] <= T となる bit について、最多お菓子数を求める
    int res = -1;
    for (int bit = 0; bit < (1<<L); ++bit) {
        for (int v = 0; v < L; ++v) {
            //cout << bitset<5>(bit) << ", " << v << ": " <<dp[bit][v] << endl;
            if (dp[bit][v] + G2[v][s] <= T) chmax(res, __builtin_popcount(bit) - 1);
        }
    }
    return res;
}

int main() {
    int N, M, L, S, T;
    while (cin >> N >> M >> L >> S >> T, N) {
        cout << solve(N, M, L, S, T) << endl;
    }
}
accuracy: 1
time_ms: 1200
memory_kb: 24760
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

#ifdef _RUTHEN
#include <debug.hpp>
#else
#define show(...) true
#endif

using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); i++)
template <class T> using V = vector<T>;

void solve(int N) {
    int M, L, S, T;
    cin >> M >> L >> S >> T;
    S--;

    const ll INF = 1LL << 60;
    V<V<ll>> dist(N, V<ll>(N, INF));

    rep(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        a--, b--;
        dist[a][b] = dist[b][a] = c;
    }
    rep(i, N) dist[i][i] = 0;

    rep(k, N) rep(i, N) rep(j, N) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);

    V<int> je(L + 1), jeb(L + 1);
    rep(i, L) {
        int j, e;
        cin >> j >> e;
        j--;
        je[i + 1] = j;
        jeb[i + 1] = e;
    }
    je[0] = S;
    jeb[0] = 0;

    L++;
    V<V<ll>> dp(1 << L, V<ll>(L, INF));
    dp[0][0] = 0;
    rep(b, 1 << L) {
        rep(v, L) {
            if (b >> v & 1) continue;
            rep(u, L) {
                if (v == u) continue;
                dp[b][v] = min(dp[b][v], dp[b][u] + dist[je[u]][je[v]]);
                dp[b | (1 << v)][v] = min(dp[b | (1 << v)][v], dp[b][u] + dist[je[u]][je[v]] + jeb[v]);
            }
        }
    }

    int ans = 0;
    rep(i, 1 << L) {
        if (dp[i][0] <= T) {
            ans = max(ans, __builtin_popcount(i) - 1);
        }
    }
    cout << ans << '\n';
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N;
    while (cin >> N, N != 0) solve(N);
    return 0;
}
accuracy: 1
time_ms: 1260
memory_kb: 25380
final_rank: 19

code_snippet: /**
 *    author:  otera
**/
#include<bits/stdc++.h>
using namespace std;

#define int long long

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using int128_t = __int128_t;
#define repa(i, n) for(int i = 0; i < n; ++ i)
#define repb(i, a, b) for(int i = a; i < b; ++ i)
#define repc(i, a, b, c) for(int i = a; i < b; i += c)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define rep(...) overload4(__VA_ARGS__, repc, repb, repa)(__VA_ARGS__)
#define rep1a(i, n) for(int i = 0; i <= n; ++ i)
#define rep1b(i, a, b) for(int i = a; i <= b; ++ i)
#define rep1c(i, a, b, c) for(int i = a; i <= b; i += c)
#define rep1(...) overload4(__VA_ARGS__, rep1c, rep1b, rep1a)(__VA_ARGS__)
#define rev_repa(i, n) for(int i=n-1;i>=0;i--)
#define rev_repb(i, a, b) assert(a > b);for(int i=a;i>b;i--)
#define rev_rep(...) overload3(__VA_ARGS__, rev_repb, rev_repa)(__VA_ARGS__)
#define rev_rep1a(i, n) for(int i=n;i>=1;i--)
#define rev_rep1b(i, a, b) assert(a >= b);for(int i=a;i>=b;i--)
#define rev_rep1(...) overload3(__VA_ARGS__, rev_rep1b, rev_rep1a)(__VA_ARGS__)
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define eb emplace_back
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
#define rall(c) c.rbegin(), c.rend()
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define Sort(a) sort(all(a))
#define Rev(a) reverse(all(a))
#define Uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define si(c) (int)(c).size()
inline ll popcnt(ull a){ return __builtin_popcountll(a); }
#define kth_bit(x, k) ((x>>k)&1)
#define unless(A) if(!(A))
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll intpow(ll a, ll b, ll m) {ll ans = 1; while(b){ if(b & 1) (ans *= a) %= m; (a *= a) %= m; b /= 2; } return ans; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__;in(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>>name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vc<T>>;
template <class T> using vvvc = vector<vvc<T>>;
template <class T> using vvvvc = vector<vvvc<T>>;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template <class T, class U> using umap = unordered_map<T, U>;
template<class T> void scan(T& a){ cin >> a; }
template<class T> void scan(vector<T>& a){ for(auto&& i : a) scan(i); }
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){ scan(head); in(tail...); }
void print(){ cout << ' '; }
template<class T> void print(const T& a){ cout << a; }
template<class T> void print(const vector<T>& a){ if(a.empty()) return; print(a[0]); for(auto i = a.begin(); ++i != a.end(); ){ cout << ' '; print(*i); } }
int out(){ cout << '\n'; return 0; }
template<class T> int out(const T& t){ print(t); cout << '\n'; return 0; }
template<class Head, class... Tail> int out(const Head& head, const Tail&... tail){ print(head); cout << ' '; out(tail...); return 0; }
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0,a1,a2,a3,a4,x,...) x
#define debug_1(x1) cout<<#x1<<": "<<x1<<endl
#define debug_2(x1,x2) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<endl
#define debug_3(x1,x2,x3) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<endl
#define debug_4(x1,x2,x3,x4) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<endl
#define debug_5(x1,x2,x3,x4,x5) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<", "#x5<<": "<<x5<<endl
#ifdef DEBUG
#define debug(...) CHOOSE((__VA_ARGS__,debug_5,debug_4,debug_3,debug_2,debug_1,~))(__VA_ARGS__)
#define dump(...) { print(#__VA_ARGS__); print(":"); out(__VA_ARGS__); }
#else
#define debug(...)
#define dump(...)
#endif

struct io_setup {
    io_setup(int precision = 20) {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout << fixed << setprecision(precision);
    }
} io_setup_ {};

const int inf = 1e9 + 7;

typedef pair<ll, P> P2;

void solve() {
    int n, m, l, s, t;
    while(cin >> n >> m >> l >> s >> t) {
        if(n == 0) break;
        -- s;
        // vvc<P> g(n);
        vvc<int> d(n, vc<int>(n, inf));
        rep(i, m) {
            INT(a, b, c); -- a, -- b;
            // g[a].eb(b, c);
            // g[b].eb(a, c);
            chmin(d[a][b], c);
            chmin(d[b][a], c);
        }
        rep(k, n) {
            rep(i, n) {
                rep(j, n) {
                    chmin(d[i][j], d[i][k] + d[k][j]);
                }
            }
        }
        vc<int> check(l, inf);
        // vc<int> id(n, -1);
        vc<int> jiros;
        rep(i, l) {
            INT(j, e); -- j;
            // id[j] = i;
            check[i] = e;
            jiros.eb(j);
        }
        vvc<int> dp(l, vc<int>((1<<l), inf));
        // pqg<P2> pque;
        // dp[s][0] = 0;
        // pque.push(P2{0, P{s, 0}});
        // while(pque.size()) {
        //     auto [di, p] = pque.top(); pque.pop();
        //     auto [v, bit] = p;
        //     if(di > dp[v][bit]) continue;
        //     if(check[v] != inf && !(bit & (1<<id[v]))) {
        //         int nbit = bit | (1<<id[v]);
        //         if(chmin(dp[v][nbit], di + check[v])) {
        //             pque.push(P2{dp[v][nbit], P{v, nbit}});
        //         }
        //     }
        //     for(auto [nv, c]: g[v]) {
        //         if(chmin(dp[nv][bit], di + c)) {
        //             pque.push(P2{dp[nv][bit], P{nv, bit}});
        //         }
        //     }
        // }
        rep(i, l) {
            chmin(dp[i][(1<<i)], d[s][jiros[i]] + check[i]);
        } 
        rep(bit, (1<<l)) {
            rep(i, l) {
                unless(bit & (1<<i)) continue;
                rep(j, l) {
                    if(bit & (1<<j)) continue;
                    chmin(dp[j][bit | (1<<j)], dp[i][bit] + d[jiros[i]][jiros[j]] + check[j]);
                }
            }
        }
        debug(t);
        int ans = 0;
        rep(bit, (1<<l)) {
            rep(i, l) {
                if(dp[i][bit] + d[jiros[i]][s] <= t) {
                    chmax(ans, popcnt(bit));
                }
            }
        }
        out(ans);
    }
}

signed main() {
    int testcase = 1;
    // in(testcase);
    while(testcase--) solve();
    return 0;
}
accuracy: 1
time_ms: 1000
memory_kb: 12428
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int inf = 1 << 29;
int n, m, l, s, t;

int popcount(int bit){
    int ret = 0;
    while(bit){
        if(bit & 1) ret++;
        bit >>= 1;
    }
    return ret;
}

void solve(){
    s--;
    vector<vector<int>> dist(n, vector<int>(n, inf));
    int a, b, c;
    for(int i = 0; i < m; i++){
        cin >> a >> b >> c;
        a--; b--;
        dist[a][b] = c;
        dist[b][a] = c;
    }
    for(int k = 0; k < n; k++) for(int i = 0; i < n; i++){
        for(int j = 0; j < n; j++) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
    }
    vector<int> pos;
    vector<int> siro;
    vector<vector<int>> dp(1 << l, vector<int>(l, inf));
    int ans = 0;
    int j, e;
    for(int i = 0; i < l; i++){
        cin >> j >> e;
        j--;
        pos.push_back(j);
        siro.push_back(e);
        dp[1 << i][i] = dist[s][j] + e;
        if(2 * dist[s][j] + e <= t) ans = 1;
    }
    if(ans == 0){
        cout << "0\n";
        return;
    }
    for(int bit = 1; bit < (1 << l); bit++){
        for(int i = 0; i < l; i++){
            if((bit >> i) & 1){
                for(int j = 0; j < l; j++){
                    if(i != j && (bit >> j) & 1){
                        int tmp = dp[bit ^ (1 << i)][j] + dist[pos[j]][pos[i]] + siro[i];
                        dp[bit][i] = min(dp[bit][i], tmp);
                    }
                }
                if(dp[bit][i] + dist[pos[i]][s] <= t){
                    ans = max(ans, popcount(bit));
                }
            }
        }
    }
    cout << ans << "\n";
}

int main(void){
    while(1){
        cin >> n >> m >> l >> s >> t;
        if(n == 0) break;
        solve();
    }
    
}
accuracy: 1
time_ms: 720
memory_kb: 10148
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
static const ll INF = 1e18;

// ワ―シャルフロイド法 O(V^3)
void warshall_floyd(vector<vector<ll>> &M) {
  int n = M.size();
  for (int j = 0; j < n; j++) { // 経由
    for (int i = 0; i < n; i++) { // 始点
      for (int k = 0; k < n; k++) { // 終点
        if (M[i][j] == INF || M[j][k] == INF) continue;
        M[i][k] = min(M[i][k], M[i][j] + M[j][k]);
      }
    }
  }
  return;
}

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

  while (true) {
    int n, m, l, s, t;
    cin >> n >> m >> l >> s >> t;
    if (n == 0) return 0;
    s--;

    vector<vector<ll>> M(n, vector<ll>(n, INF));
    for (int i = 0; i < n; i++) M[i][i] = 0;
    for (int i = 0; i < m; i++) {
      int a, b;
      ll c;
      cin >> a >> b >> c;
      a--;
      b--;
      M[a][b] = M[b][a] = c;
    }

    vector<ll> j(l), e(l);
    for (int i = 0; i < l; i++) {
      cin >> j.at(i) >> e.at(i);
      j.at(i)--;
    }

    warshall_floyd(M);

    vector<vector<ll>> dp(l, vector<ll>((1 << l), INF));
    for (int i = 0; i < l; i++) {
      dp[i][(1 << i)] = min(dp[i][(1 << i)], M[s][j.at(i)] + e.at(i));
    }
    for (int bit = 1; bit < (1 << l); bit++) {
      for (int i = 0; i < l; i++) {
        if (dp[i][bit] == INF) continue;
        for (int j2 = 0; j2 < l; j2++) {
          if (bit & (1 << j2)) continue;
          dp[j2][bit | (1 << j2)] = min(dp[j2][bit | (1 << j2)], dp[i][bit] + M[j.at(i)][j.at(j2)] + e.at(j2));
        }
      }
    }

    int ans = 0;
    for (int bit = 1; bit < (1 << l); bit++) {
      for (int i = 0; i < l; i++) {
        if (dp[i][bit] == INF) continue;
        if (dp[i][bit] + M[j.at(i)][s] <= t) ans = max<int>(ans, __builtin_popcount(bit));
      }
    }

    cout << ans << '\n';
  }
}
accuracy: 1
time_ms: 850
memory_kb: 12532
final_rank: 5

code_snippet: // #include "atcoder/all"
#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <cstdio> // printf
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#include <unordered_map> // unordered_map
#include <unordered_set> // unordered_set
#include <bitset> // bitset
#include <cctype> // isupper, islower, isdigit, toupper, tolower
#include <iomanip> // setprecision
#include <complex> // complex
#include <math.h>
#include <functional>
#include <cassert>
using namespace std;
// using namespace atcoder;
using ll = long long;
using P = pair<ll,int>;
constexpr ll INF = 1e15;
constexpr ll LLMAX = 9223372036854775807;
constexpr int inf = 1e9;
// constexpr ll mod = 1000000007;
constexpr ll mod = 998244353;
// 右下左上
const int dx[8] = {1, 0, -1, 0,1,1,-1,-1};
const int dy[8] = {0, 1, 0, -1,1,-1,1,-1};
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
#define eol "\n"
// ---------------------------------------------------------------------------

bool solve(){
    ll N,M,L,S,T;
    cin >> N >> M >> L >> S >> T;
    S--;
    if(N == 0) return false;
    vector<vector<P>> G(N);
    for(int i=0; i<M; i++){
        int a,b,c;
        cin >> a >> b >> c;
        a--;b--;
        G[a].emplace_back(b,c);
        G[b].emplace_back(a,c);
    }
    vector<vector<ll>> dist(N,vector<ll>(N,INF));
    for(int s=0; s<N; s++){
        dist[s][s] = 0;
        priority_queue<P,vector<P>,greater<>> que;
        que.emplace(0,s);
        while(que.size()){
            ll cost,v;
            tie(cost, v) = que.top();
            que.pop();
            if(dist[s][v] < cost) continue;
            for(auto hoge: G[v]){
                ll nv,nc;
                tie(nv,nc) = hoge;
                if(chmin(dist[s][nv],cost+nc)){
                    que.emplace(dist[s][nv],nv);
                }
            }
        }
    }
    vector<ll> ID(L+1);
    vector<ll> E(L+1);
    ID[0] = S;
    for(int i=1; i<=L; i++){
        cin >> ID[i] >> E[i];
        ID[i]--;
    }
    vector<vector<ll>> D(L+1,vector<ll>(L+1));
    // for(int i=0; i<N; i++){
    //     for(int j=0; j<N; j++){
    //         cout << dist[i][j] << " \n"[j+1==N];
    //     }
    // }
    for(int i=0; i<=L; i++){
        for(int j=0; j<=L; j++){
            D[i][j] = dist[ID[i]][ID[j]];
            // cout << D[i][j] << " \n"[j==L];
        }
    }

    vector<vector<ll>> dp(L+1,vector<ll>(1LL<<L,INF));
    dp[0][0] = 0;
    for(int bit=0; bit<(1LL<<L); bit++){
        for(int i=0; i<=L; i++){
            if((i && (!(bit & (1LL<<(i-1)))))) continue;
            for(int j=0; j<=L; j++){
                if(j && (bit & (1LL<<(j-1)))) continue;
                // cout << i << " " << bit << endl;
                // cout << dp[i][bit] << endl;
                if(j){
                    chmin(dp[j][bit + (1LL<<(j-1))],dp[i][bit]+D[i][j] + E[j]);
                }else{
                    chmin(dp[0][bit],dp[i][bit]+D[i][0]);
                }
            }
        }
    }
    ll ans = 0;
    for(int i=0; i<(1LL<<L); i++){
        ll num = __builtin_popcount(i);
        if(dp[0][i] <= T) chmax(ans,num);
    }
    cout << ans << endl;
    // cout << endl;
    return true;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while(solve());
    return 0;
}
accuracy: 1
time_ms: 1040
memory_kb: 13368
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

int n, m, l, s, t;
vector<int> v, e;
vector<vector<int>> d;

int solve();

int main() {
  while (1) {
    cin >> n >> m >> l >> s >> t, --s;
    if (!n) break;
    d.assign(n, vector<int>(n, 1e8));
    for (int i = 0; i < m; ++i) {
      int a, b, c;
      cin >> a >> b >> c, --a, --b;
      d[a][b] = min(d[a][b], c);
      d[b][a] = min(d[b][a], c);
    }
    v.assign(l + 1, s), e.assign(l + 1, 0);
    for (int i = 1; i <= l; ++i) cin >> v[i] >> e[i], --v[i];
    cout << solve() << endl;
  }
  return 0;
}

int solve() {
  for (int k = 0; k < n; ++k)
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
  ++l;
  vector<vector<int>> dp(1 << l, vector<int>(l, 1e8));
  dp[0][0] = 0;
  for (int i = 0; i < (1 << l); ++i)
    for (int j = 0; j < l; ++j)
      for (int k = 0; k < l; ++k)
        if (!(i >> k & 1)) {
          dp[i | (1 << k)][k] =
              min(dp[i | (1 << k)][k], dp[i][j] + d[v[j]][v[k]] + e[k]);
        }
  int res = 0;
  for (int i = 0; i < (1 << l); ++i)
    if (dp[i][0] <= t) res = max(res, (int)__builtin_popcount(i) - 1);
  return res;
}
accuracy: 1
time_ms: 1370
memory_kb: 16804
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
using P = pair<int,int>;
int dp[(1<<17)][17];

void init(){
  for(int i=0; i<(1<<17); i++){
    for(int j=0; j<17; j++){
      dp[i][j] = 1e9;
    }
  }
  dp[1][0] = 0;
}

void solve(int N){
  int M, L, S, T;
  cin >> M >> L >> S >> T;
  S--;
  vector<vector<int>> dist(N,vector<int>(N,1e9));
  for(int i=0; i<M; i++){
    int a, b, c;
    cin >> a >> b >> c;
    a--; b--;
    dist[a][b] = min(dist[a][b],c);
    dist[b][a] = min(dist[b][a],c);
  }
  vector<P> vec(L+1, P(S,0));
  for(int i=1; i<=L; i++){
    int x, y;
    cin >> x >> y;
    x--;
    vec[i] = P(x,y);
  }
  
  for(int k=0; k<N; k++){
    for(int i=0; i<N; i++){
      for(int j=0; j<N; j++){
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
      }
    }
  }
  
  init();
  
  for(int i=0; i<(1<<(L+1)); i++){
    for(int j=0; j<=L; j++){
      for(int k=0; k<=L; k++){
        dp[i|(1<<k)][k] = min(dp[i|(1<<k)][k], dp[i][j] + 
                              dist[vec[j].first][vec[k].first] + vec[k].second);
      }
    }
  }
  
  int ans = 0;
  for(int i=0; i<(1<<(L+1)); i++){
    if(dp[i][0] <= T){
      int cnt = 0;
      for(int k=0; k<=L; k++){
        if(i & (1<<k)){
          cnt++;
        }
      }
      ans = max(ans,cnt-1);
    }
  }
  cout << ans << endl;
}

int main(){
  while(true){
    int N;
    cin >> N;
    if(N == 0){
      break;
    }
    solve(N);
    //break;
  }
}
accuracy: 1
time_ms: 1210
memory_kb: 12228
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll = long long;
const int INF = 1e9 + 7;
const ll inf = 1LL<<60;
template<typename T>
bool chmin(T& x, const T& y){
  if(x <= y) return false;
  x = y;
  return true;
}
template<typename T>
bool chmax(T& x, const T& y){
  if(x >= y) return false;
  x = y;
  return true;
}


bool solve() {
  int n, m, l, s, t; cin >> n >> m >> l >> s >> t;
  s--;
  if (n == 0) return false;
  vector<vector<int>> wf(n, vector<int>(n, INF));
  for (int i=0; i<m; i++) {
    int a, b, c; cin >> a >> b >> c;
    a--; b--;
    wf[a][b] = wf[b][a] = c;
  }
  vector<int> jiro(l+1), id(l+1);
  for (int i=0; i<l; i++) {
    int j, e; cin >> j >> e;
    jiro[i] = e;
    id[i] = j-1;
  }
  jiro[l] = 0;
  id[l] = s;
  for (int k=0; k<n; k++) for (int i=0; i<n; i++) for (int j=0; j<n; j++) {
    chmin(wf[i][j], wf[i][k] + wf[k][j]);
  }
  vector<vector<int>> dp(1<<(l+1), vector<int>(l+1, INF));
  dp[0][l] = 0;
  for (int i=0; i<l; i++) dp[1<<i][i] = wf[s][id[i]] + jiro[i];
  for (int bit=1; bit<(1<<(l+1)); bit++) for (int i=0; i<l+1; i++) if (bit & (1<<i)) {
    for (int j=0; j<l+1; j++) if (!(bit & (1<<j))) {
      int nbit = bit | (1<<j);
      chmin(dp[nbit][j], dp[bit][i] + wf[id[i]][id[j]] + jiro[j]);
    }
  }
  int ans = 0;
  for (int S=0; S<(1<<(l+1)); S++) if (dp[S][l] <= t) {
    chmax(ans, (int)__builtin_popcount(S) - 1);
  }
  cout << ans << endl;
  return true;
}
int main() {
  while (solve());
}
accuracy: 1
time_ms: 1640
memory_kb: 16916
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll = long long;
const int INF = 1e9 + 7;
const ll inf = 1LL<<60;
template<typename T>
bool chmin(T& x, const T& y){
  if(x <= y) return false;
  x = y;
  return true;
}
template<typename T>
bool chmax(T& x, const T& y){
  if(x >= y) return false;
  x = y;
  return true;
}


bool solve() {
  int n, m, l, s, t; cin >> n >> m >> l >> s >> t;
  s--;
  if (n == 0) return false;
  vector<vector<int>> wf(n, vector<int>(n, INF));
  for (int i=0; i<m; i++) {
    int a, b, c; cin >> a >> b >> c;
    a--; b--;
    wf[a][b] = wf[b][a] = c;
  }
  vector<int> jiro(l+1), id(l+1);
  for (int i=0; i<l; i++) {
    int j, e; cin >> j >> e;
    jiro[i] = e;
    id[i] = j-1;
  }
  jiro[l] = 0;
  id[l] = s;
  for (int k=0; k<n; k++) for (int i=0; i<n; i++) for (int j=0; j<n; j++) {
    chmin(wf[i][j], wf[i][k] + wf[k][j]);
  }
  vector<vector<int>> dp(1<<(l+1), vector<int>(l+1, INF));
  dp[0][l] = 0;
  for (int i=0; i<l; i++) dp[1<<i][i] = wf[s][id[i]] + jiro[i];
  for (int S=1; S<(1<<(l+1)); S++) for (int v=0; v<l+1; v++) if (!((S >> v) & 1)) {
    for (int u=0; u<l+1; u++) if ((S >> u) & 1) {
      chmin(dp[S|(1<<v)][v], dp[S][u] + wf[id[u]][id[v]] + jiro[v]);
    }
  }
  int ans = 0;
  for (int S=0; S<(1<<(l+1)); S++) if (dp[S][l] <= t) {
    chmax(ans, (int)__builtin_popcount(S) - 1);
  }
  cout << ans << endl;
  return true;
}
int main() {
  while (solve());
}
accuracy: 1
time_ms: 1410
memory_kb: 16740
final_rank: 13

code_snippet: #pragma region Macros
#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define FOR(i, a, b) for(int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;

void Case(int i) { cout << "Case #" << i << ": "; }
int popcount(int x) { return __builtin_popcount(x); }
ll popcount(ll x) { return __builtin_popcountll(x); }
#pragma endregion Macros

bool solve() {
    int N, M, L, s, T;
    cin >> N >> M >> L >> s >> T;
    if(N == 0) return false;
    s--;
    vector dist(N, vector<int>(N, INF));
    REP(i, N) dist[i][i] = 0;
    REP(i, M) {
        int a, b, c;
        cin >> a >> b >> c;
        a--; b--;
        dist[a][b] = dist[b][a] = c;
    }
    vector<int> vs(L), es(L);
    REP(i, L) {
        cin >> vs[i] >> es[i];
        vs[i]--;
    }
    REP(k, N) REP(i, N) REP(j, N) {
        if(dist[i][k] == INF or dist[k][j] == INF) continue;
        chmin(dist[i][j], dist[i][k] + dist[k][j]);
    }

    vector dp(1 << L, vector<int>(L, INF));
    REP(i, L) {
        dp[1 << i][i] = dist[s][vs[i]] + es[i];
    }
    REP(mask, 1 << L) {
        REP(i, L) {
            if(dp[mask][i] >= INF) continue;
            assert(mask >> i & 1);
            REP(j, L) {
                if(mask >> j & 1) continue;
                chmin(dp[mask | (1 << j)][j], dp[mask][i] + dist[vs[i]][vs[j]] + es[j]);
            }
        }
    }
    int ans = 0;
    REP(mask, 1 << L) {
        int pcnt = popcount(mask);
        REP(i, L) {
            if(dp[mask][i] >= INF) continue;
            if(dp[mask][i] + dist[vs[i]][s] <= T) {
                chmax(ans, pcnt);
            }
        }
    }
    cout << ans << "\n";
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 890
memory_kb: 10124
final_rank: 3