#include <bits/stdc++.h>
#define ft first
#define sd second
#define endl '\n'
#define pb push_back
#define md make_pair
#define gc() getchar()
#define pc(ch) putchar(ch)
#define umap unordered_map
#define pque priority_queue
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 bint;
typedef pair<int, int> pii;
typedef pair<pii, int> pi1;
typedef pair<pii, pii> pi2;
const ll INF = 0x3f3f3f3f;
const db Pi = acos(-1.0);
inline ll read()
{
ll res = 0, f = 1; char ch = gc();
while (ch < '0' || ch > '9') f = (ch == '-' ? -1 : f), ch = gc();
while (ch >= '0' && ch <= '9') res = (res << 1) + (res << 3) + (ch ^ 48), ch = gc();
return res * f;
}
inline void write(ll x)
{
if (x < 0) x = -x, pc('-');
if (x > 9) write(x / 10);
pc(x % 10 + '0');
}
inline void writech(ll x, char ch) { write(x), pc(ch); }
#define int long long
const int N = 1e4 + 20, M = 1e6 + 5, K = 15;
struct Edge {
int u, v, w;
} edge[M], e[M];
int c[K], a[K][N];
int fa[N];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
bool cmp(Edge x, Edge y) { return x.w < y.w; }
signed main()
{
int n = read(), m = read(), k = read();
for (int i = 1; i <= m; i++)
{
int u = read(), v = read(), w = read();
edge[i] = {u, v, w};
}
for (int i = 1; i <= k; i++)
{
c[i] = read();
for (int j = 1; j <= n; j++) a[i][j] = read();
}
sort(edge + 1, edge + m + 1, cmp);
if (k == 0)
{
for (int i = 1; i <= n; i++) fa[i] = i;
int ans = 0;
int cnt = 0;
for (int i = 1; i <= m; i++)
{
int u = edge[i].u, v = edge[i].v, w = edge[i].w;
int s = find(u), t = find(v);
if (s != t)
{
fa[s] = t;
ans += w;
cnt++;
}
if (cnt == n - 1) break;
}
write(ans);
return 0;
}
for (int i = 1; i <= n; i++) fa[i] = i;
int cnt = 0;
for (int i = 1; i <= m; i++)
{
int u = edge[i].u, v = edge[i].v, w = edge[i].w;
int s = find(u), t = find(v);
if (s != t)
{
fa[s] = t;
cnt++;
e[cnt] = {u, v, w};
}
if (cnt == n - 1) break;
}
int res = 2e18;
for (int S = 0; S < (1 << k); S++)
{
for (int i = 1; i <= n + k; i++) fa[i] = i;
for (int i = 1; i <= n - 1; i++) e[i] = edge[i];
int ans = 0;
int cur = n - 1;
for (int i = 1; i <= k; i++)
{
if (S & (1 << (i - 1)))
{
// cout << i << " ";
ans += c[i];
for (int j = 1; j <= n; j++) e[++cur] = {n + i, j, a[i][j]};
}
}
cout << endl;
sort(e + 1, e + cur + 1, cmp);
int bcnt = __builtin_popcount(S);
int cnt = 0;
for (int i = 1; i <= cur; i++)
{
int u = e[i].u, v = e[i].v, w = e[i].w;
int s = find(u), t = find(v);
if (s != t)
{
fa[s] = t;
cnt++;
ans += w;
// cout << u << " " << v << " " << w << endl;
}
if (cnt == bcnt + n - 1) break;
}
res = min(res, ans);
// cout << ans << endl;
}
write(res);
return 0;
}
/*
2
4
100 0 0
1
*/