#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
struct Flow {
const static int MAX_EDGES = 100005;
const static int MAX_NODES = 1000;
const int INF = 1e9 + 50;
int S = MAX_NODES - 2, D = MAX_NODES - 1;
int G[MAX_NODES];
struct Edge {
int vec, flow, cap, cost, rev, nxt;
};
Edge E[MAX_EDGES];
int edges = 0;
int ParentNode[MAX_NODES], ParentEdge[MAX_NODES], Dist[MAX_NODES], DistOld[MAX_NODES], DistReal[MAX_NODES];
bool InQ[MAX_NODES];
queue<int> Q;
priority_queue<pair<int, int>> PQ;
Flow() {
Reset();
}
void setSource(int s) {
S = s;
}
void setSink(int d) {
D = d;
}
void _addEdge(int a, int b, int cap, int cost, int rev) {
++edges;
E[edges] = (Edge) {b, 0, cap, cost, rev, G[a]};
G[a] = edges;
}
void AddEdge(int a, int b, int cap, int cost) {
_addEdge(a, b, cap, cost, edges + 2);
_addEdge(b, a, 0, -cost, edges);
}
bool Bellman() {
memset(ParentNode, 0, sizeof(ParentNode));
DistOld[S] = 0;
Q.push(S);
while(!Q.empty()) {
int top = Q.front();
InQ[top] = 0;
Q.pop();
for(int i=G[top]; i; i=E[i].nxt) {
int vec = E[i].vec;
if(E[i].flow < E[i].cap && (ParentNode[vec] == 0 || DistOld[vec] > DistOld[top] + E[i].cost)) {
DistOld[vec] = DistOld[top] + E[i].cost;
ParentNode[vec] = top;
ParentEdge[vec] = i;
if(!InQ[vec]) {
Q.push(vec);
InQ[vec] = 1;
}
}
}
}
return ParentNode[D] != 0;
}
bool Dijkstra() {
memset(ParentNode, 0, sizeof(ParentNode));
Dist[S] = DistReal[S] = 0;
PQ.push({0, S});
while(!PQ.empty()) {
auto top = PQ.top();
PQ.pop();
int node = top.second;
if(-top.first > Dist[node])
continue;
for(int i = G[node]; i; i = E[i].nxt) {
int vec = E[i].vec;
if(E[i].flow < E[i].cap && (ParentNode[vec] == 0 || Dist[vec] > Dist[node] + DistOld[node] - DistOld[vec] + E[i].cost)) {
Dist[vec] = Dist[node] + DistOld[node] - DistOld[vec] + E[i].cost;
ParentNode[vec] = node;
ParentEdge[vec] = i;
DistReal[vec] = DistReal[node] + E[i].cost;
PQ.push({-Dist[vec], vec});
}
}
}
return ParentNode[D] != 0;
}
void Reset() {
edges = 0;
memset(G, 0, sizeof(G));
while(!Q.empty()) Q.pop();
while(!PQ.empty()) PQ.pop();
}
pair<int, int> MFMC() {
int cost = 0, flow = 0;
Bellman();
while(Dijkstra()) {
int M = INF;
for(int node = D; node != S; node = ParentNode[node]) {
int ei = ParentEdge[node];
M = min(M, E[ei].cap - E[ei].flow);
}
for(int node = D; node != S; node = ParentNode[node]) {
int ei = ParentEdge[node],
ri = E[ei].rev;
E[ei].flow += M;
E[ri].flow -= M;
cost += E[ei].cost * M;
}
flow += M;
memcpy(DistOld, DistReal, sizeof(DistReal));
}
return {flow, cost};
}
};
Flow F;
int Ind[200000];
int main() {
freopen("cmcm.in", "r", stdin);
freopen("cmcm.out", "w", stdout);
int n, m, e;
cin >> n >> m >> e;
#define Left(i) 2*i
#define Right(i) 2*i+1
for(int i=1; i<=n; i++)
F.AddEdge(F.S, Left(i), 1, 0);
for(int i=1; i<=m; i++)
F.AddEdge(Right(i), F.D, 1, 0);
int a, b, c;
for(int i=1; i<=e; i++) {
cin >> a >> b >> c;
Ind[F.edges+1] = Ind[F.edges+2] = i;
F.AddEdge(Left(a), Right(b), 1, c);
}
auto ret = F.MFMC();
cout << ret.first << " " << ret.second << '\n';
for(int i=1; i<=F.edges; i++) {
if(F.E[i].flow > 0 && Ind[i] > 0) {
cout << Ind[i] << " ";
}
}
return 0;
}