#include <bits/stdc++.h>
using namespace std;
ifstream in("cmcm.in");
ofstream out("cmcm.out");
struct Graph
{
int l, r, n, s, d;
vector < vector <int> > a;
vector < vector <int> > cap, cost;
vector <int> dcost, flow, parent;
queue <int> Q;
priority_queue < pair <int, int> > Heap;
vector <bool> viz;
Graph(int _l, int _r): l(_l), r(_r), n(r + l + 2), s(0), d(n - 1), a(n),
cap(n, vector<int>(n)), cost(cap), dcost(n),
flow(n), parent(n), viz(n)
{
for (int i = 1; i <= l; ++i)
AddEdge(0, i, 1, 0);
for (int i = l + 1; i <= l + r; ++i)
AddEdge(i, d, 1, 0);
}
void AddEdge(int x, int y, int cp, int cst)
{
a[x].push_back(y);
a[y].push_back(x);
cap[x][y] += cp;
cost[x][y] += cst;
cost[y][x] -= cst;
}
void Bellman()
{
fill(dcost.begin(), dcost.end(), 1e9);
fill(viz.begin(), viz.end(), 0);
Q.push(s);
dcost[s] = 0;
viz[s] = 1;
while (not Q.empty())
{
int node = Q.front();
Q.pop();
viz[node] = 0;
int curr_cost = dcost[node];
for (int nei: a[node])
{
if (!cap[node][nei])
continue;
int new_dist = curr_cost + cost[node][nei];
if (new_dist < dcost[nei])
{
dcost[nei] = new_dist;
if (!viz[nei])
{
viz[nei] = 1;
Q.push(nei);
}
}
}
}
}
pair <int, int> Dijkstra()
{
fill(flow.begin(), flow.end(), 1e9);
vector <int> aux(n, 1e9);
Heap.push({0, s});
flow[s] = 0;
aux[s] = 0;
while (!Heap.empty())
{
int curr_cost = -Heap.top().first;
int node = Heap.top().second;
Heap.pop();
if (curr_cost != flow[node])
continue;
for (int nei: a[node])
{
if (!cap[node][nei])
continue;
int new_dist = curr_cost + cost[node][nei] + dcost[node] - dcost[nei];
if (new_dist < flow[nei])
{
flow[nei] = new_dist;
Heap.push({-flow[nei], nei});
parent[nei] = node;
aux[nei] = aux[node] + cost[node][nei];
}
}
}
if (flow[d] == 1e9)
return {0, 0};
int flow = 1e9;
for (int node = d; node != s; node = parent[node])
flow = min(flow, cap[parent[node]][node]);
for (int node = d; node != s; node = parent[node])
{
cap[parent[node]][node] -= flow;
cap[node][parent[node]] += flow;
}
dcost = aux;
return {flow, dcost[d] * flow};
}
pair <int, int> MinCostMaxFlow()
{
Bellman();
int maxFlow = 0, minCost = 0;
while(1)
{
auto lol = Dijkstra();
if (lol.first == 0)
break;
maxFlow += lol.first;
minCost += lol.second;
}
return {maxFlow, minCost};
}
vector <int> getUsedEdges(vector <pair <int, int> >& edges)
{
vector <int> ans;
for (int i = 0; i < (int) edges.size(); ++i)
{
int a = edges[i].first;
int b = edges[i].second;
if (!cap[a][b])
ans.push_back(i + 1);
}
return ans;
}
};
int main()
{
int l, r, m;
in >> l >> r >> m;
Graph G(l, r);
vector < pair <int, int> > edges;
for (int i = 1; i <= m; ++i)
{
int a, b, z;
in >> a >> b >> z;
G.AddEdge(a, l + b, 1, z);
edges.push_back({a, l + b});
}
auto ans = G.MinCostMaxFlow();
out << ans.first << ' ' << ans.second << '\n';
auto vec = G.getUsedEdges(edges);
for (int it : vec)
out << it << ' ';
return 0;
}