#include using namespace std; typedef long long ll; using coord = ll; // type of data const int MAXN = 5010; const coord INF = 0; //for maximum set INF to 0, and negate costs int N, matchl[MAXN], matchr[MAXN]; coord cst[MAXN][MAXN]; void add(int x, int y, coord c){ cst[x][y] = c; } coord hungarian(){ int mat = 0, dad[MAXN], vis[MAXN]; coord ds[MAXN], y[MAXN], z[MAXN]; for (int i = 0; i < N; i++) y[i] = *min_element(cst[i], cst[i] + N); for (int j = 0; j < N; j++){ z[j] = cst[0][j] - y[0]; for (int i = 1; i < N; i++) z[j] = min(z[j], cst[i][j] - y[i]); } memset(matchl, -1, sizeof matchl); memset(matchr, -1, sizeof matchr); for (int i = 0; i < N; i++) // speedup for (int j = 0; j < N; j++) if (matchr[j] == -1 && !(cst[i][j] - y[i] - z[j])) { matchl[i] = j; matchr[j] = i; mat++; break; } while (mat < N){ int s = 0, j = 0, i; while (matchl[s] != -1) s++; memset(dad, -1, sizeof dad); memset(vis, 0, sizeof vis); for (int k = 0; k < N; k++) ds[k] = cst[s][k] - y[s] - z[k]; while (true){ j = -1; for (int k = 0; k < N; k++) if (!vis[k] && (j == -1 || ds[k] < ds[j])) j = k; vis[j] = 1; i = matchr[j]; if (i == -1) break; for (int k = 0; k < N; k++) if (!vis[k]){ auto new_ds = ds[j] + cst[i][k] - y[i] - z[k]; if(ds[k] > new_ds){ ds[k] = new_ds; dad[k] = j; } } } for (int k = 0; k < N; k++) if (k != j && vis[k]){ auto w = ds[k] - ds[j]; z[k] += w; y[matchr[k]] -= w; } y[s] += ds[j]; while (dad[j] >= 0){ int d = dad[j]; matchr[j] = matchr[d]; matchl[matchr[j]] = j; j = d; } matchr[j] = s; matchl[s] = j; mat++; } coord value = 0; for (int i = 0; i < N; i++) value += cst[i][matchl[i]]; return value; } constexpr int kM = int(1E5 + 10); int x[kM], y[kM], z[kM]; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, m, k, l; cin >> n >> m >> k >> l; for (int i = 1; i <= l; i++) cin >> x[i] >> y[i] >> z[i]; N = max(n, m); for (int i = 1; i <= l; i++) add(x[i] - 1, y[i] - 1, -(1LL << z[i])); cout << -hungarian() << endl; }