#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;


const int T = 5001, N = 101;
int maxMoney, startNode, nodes, edges, avTime, win[N], mat[T][N][N];
vector<vector<pair<int, int> > > adjacent;


void parse_input()
{
    cin >> nodes >> edges >> startNode >> avTime;
    for (int i = 1; i <= nodes; ++i) cin >> win[i]; // money gain for node i
    adjacent.resize(nodes + 1);
    for (int i = 0; i < edges; ++i) {
        int t, x, y;
        cin >> t >> x >> y; // t time between x and y
        adjacent[x].push_back(make_pair(y, t));
        adjacent[y].push_back(make_pair(x, t));
    }
}


void solve()
{
    /** O(TN^2) */
    maxMoney = win[startNode]; // atribuim maximului castigul de start
    mat[0][startNode][0] = maxMoney; // la momentul de timp t=0 initializam nodul de start
    mat[0][startNode][startNode] = 1; // marcam ca este vizitat in lantul curent
    for (int i = 0; i < avTime; ++i) { // pentru fiecare moment de timp
        for (int j = 1; j <= nodes; ++j) { // luam fiecare nod
            if (mat[i][j][0]) { // si daca s-a putut ajunge in el (avand suma strict pozitiva)
                for (int k = 0; k < adjacent[j].size(); ++k) { // luam fiecare vecin al lui
                    int tmpTime = i + adjacent[j][k].second; // aflam noul timp pentru vizita vecinului
                    int tmpMoney = mat[i][j][0]; // clonam suma de la care pornim vizita
                    if (!mat[i][j][adjacent[j][k].first]) { // daca nu a mai fost vizitat acel vecin
                        tmpMoney += win[adjacent[j][k].first]; // actualizam suma
                    } // apoi daca vizita intra in timp si obtinem o suma mai buna de bani
                    if (tmpTime <= avTime && tmpMoney > mat[tmpTime][adjacent[j][k].first][0]) {
                        if (tmpMoney > maxMoney) maxMoney = tmpMoney; // actualizam maximul
                        mat[tmpTime][adjacent[j][k].first][0] = tmpMoney; // evenimentul in matrice
                        for (int l = 1; l <= nodes; ++l) { // dar si lantul de noduri vizitate
                            mat[tmpTime][adjacent[j][k].first][l] = mat[i][j][l];
                            mat[tmpTime][adjacent[j][k].first][adjacent[j][k].first] = 1;
                        }
                    }
                }
            }
        }
    }
}


int main()
{
    //freopen("dp_graf.in", "rt", stdin); // switch input source
    parse_input();
    solve();
    cout << maxMoney;
    return 0;
}
