#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e8;
struct NetworkSimplex {
struct Edge { int a, b, c, k, f = 0; };
int n;
vector<int> pei, depth;
vector<ll> dual;
vector<Edge> E;
vector<set<int>> tree;
NetworkSimplex(int n) :
n(n), pei(n + 1, -1), depth(n + 1, 0),
dual(n + 1, 0), tree(n + 1) {}
int AddEdge(int a, int b, int c, int k) {
E.push_back({a, b, c, k});
E.push_back({b, a, 0, -k});
return E.size() - 2;
}
void upd(int ei) {
dual[E[ei].b] = dual[E[ei].a] + E[ei].k;
pei[E[ei].b] = (ei ^ 1);
depth[E[ei].b] = 1 + depth[E[ei].a];
dfs(E[ei].b);
}
void dfs(int node) {
for (auto ei : tree[node])
if (ei != pei[node])
upd(ei);
}
template<typename CB>
void walk(int a, int b, CB&& cb) {
if (a == b) return;
if (depth[a] > depth[b])
walk(E[pei[a]].b, b, cb), cb(pei[a]^1);
else
cb(pei[b]), walk(a, E[pei[b]].b, cb);
}
long long Compute() {
for (int i = 0; i < n; ++i) {
int ei = AddEdge(n, i, 0, 0);
tree[n].insert(ei);
tree[i].insert(ei^1);
}
dfs(n);
long long answer = 0;
ll flow, cost; int ein, eout, ptr = 0;
const int B = n / 3 + 1;
for (int z = 0; z < E.size() / B + 1; ++z) {
// Find negative cycle (round-robin).
cost = 0; ein = -1;
for (int t = 0; t < B; ++t, (++ptr) %= E.size()) {
auto& e = E[ptr];
ll now = dual[e.a] + e.k - dual[e.b];
if (e.f < e.c && now < cost)
cost = now, ein = ptr;
}
if (cost == 0) continue;
// Pivot around ein.
flow = E[ein].c - E[ein].f; eout = ein;
walk(E[ein].a, E[ein].b, [&](int ei) {
int res = E[ei].c - E[ei].f;
if (res < flow) flow = res, eout = ei;
});
if (flow) {
E[ein].f += flow, E[ein^1].f -= flow;
walk(E[ein].a, E[ein].b, [&](int ei) {
E[ei].f += flow, E[ei^1].f -= flow;
});
}
if (ein != eout) {
tree[E[ein].a].insert(ein);
tree[E[ein].b].insert(ein^1);
tree[E[eout].a].erase(eout);
tree[E[eout].b].erase(eout^1);
upd(pei[E[eout].a] == eout ? ein : ein^1);
}
answer += flow * cost;
z = -1;
}
return answer;
}
};
int main() {
ifstream cin("cmcm.in");
ofstream cout("cmcm.out");
int n, m, e; cin >> n >> m >> e;
NetworkSimplex NS(n + m + 2);
for (int i = 0; i < e; ++i) {
int a, b, c; cin >> a >> b >> c; --a; --b;
assert(2 * i == NS.AddEdge(a, b + n, 1, c));
}
for (int i = 0; i < n + m; ++i) {
if (i < n) NS.AddEdge(n + m, i, 1, 0);
else NS.AddEdge(i, n + m + 1, 1, 0);
}
int ed = NS.AddEdge(n + m + 1, n + m, n + m, -INF);
auto cost = NS.Compute();
int flow = NS.E[ed].f;
cost += 1LL * flow * INF;
cout << flow << " " << cost << '\n';
for (int i = 0; i < e; ++i)
if (NS.E[2 * i].f > 0)
cout << i + 1 << " ";
cout << endl;
return 0;
}