#include #include #include #include using namespace std; using lint = long long; #define FOR(i, begin, end) for(int i=(begin),i##_end_=(end);i bool chmin(T &m, const T q) { return m > q ? (m = q, true) : false; } const std::vector> grid_dxs{{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {0, 0}}; int main() { cin.tie(nullptr), ios::sync_with_stdio(false); int N, M, K, T; cin >> N >> M >> K >> T; if (T >= (N - 1) + (M - 1)) { puts("0"); return 0; } vector C(N * M); vector D(N * M); const int B = N + M; const int W = B * 2 + 1; auto fij = [&](int i, int j) { return i * M + j; }; auto isin = [&](int i, int j, int t) { return 0 <= i and i < N and 0 <= j and j < M and - B <= t and t <= B; }; auto f = [&](int i, int j, int t) { assert(isin(i, j, t)); return (i * M + j) * W + (t + B); }; REP(k, K) { int a, b, c, d; cin >> a >> b >> c >> d; --a, --b; C.at(fij(a, b)) = c - 1; D.at(fij(a, b)) = d; // cerr << "k" << a << ' ' << b << ' ' << c << ' ' << d << '\n'; } const int sz = N * M * W; constexpr lint inf = 1LL << 60; vector dp(sz, inf); dp.at(f(0, 0, 0)) = 0; using S = tuple; priority_queue, greater> pq; pq.emplace(0, 0, 0, 0); while (!pq.empty()) { auto [dpnow, i, j, t] = pq.top(); // cerr << dpnow << ' ' << i << ' ' << j << ' ' << t << '\n'; pq.pop(); if (dpnow > dp.at(f(i, j, t))) continue; for (auto [di, dj] : grid_dxs) { const int ni = i + di, nj = j + dj, nt = t + 1; if (!isin(ni, nj, nt)) continue; if (chmin(dp.at(f(ni, nj, nt)), dpnow)) pq.emplace(dpnow, ni, nj, nt); } if (const int tnxt = max(t - C.at(fij(i, j)), -B); isin(i, j, tnxt)) { if (chmin(dp.at(f(i, j, tnxt)), dpnow + D.at(fij(i, j)))) { pq.emplace(dp.at(f(i, j, tnxt)), i, j, tnxt); } } } lint ret = dp.at(f(N - 1, M - 1, T)); cout << (ret < inf ? ret : -1) << '\n'; }