#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <tuple>
#include <limits>
#include <functional>
#include <complex>
#include <bitset>
#include <list>
//#include <atomic>
//#include <condition_variable>
//#include <future>
//#include <mutex>
//#include <thread>
using namespace std;
#define debug(x) cerr << #x << " = " << x << "\n"
const int INF = 0x3f3f3f3f;
const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
struct MinCostFlow
{
typedef long long Flow; typedef long long Cost; typedef int Index;
static const Flow InfCapacity = 0x3f3f3f3f / 2;
static const Cost InfCost = 0x3f3f3f3f / 2;
int index;
struct Edge
{
Index to, rev;
Flow capacity;
Cost cost;
Index id;
};
vector< vector<Edge> > g;
void init(int n) { index = 0; g.assign(n, vector<Edge>()); }
void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost())
{
Edge e, f;
e.id = ++index;
e.to = j, f.to = i;
e.capacity = capacity, f.capacity = 0;
e.cost = cost, f.cost = -cost;
g[i].push_back(e), g[j].push_back(f);
g[i].back().rev = (int) g[j].size() - 1;
g[j].back().rev = (int) g[i].size() - 1;
}
void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost())
{
add(i, j, capacity, cost);
add(j, i, capacity, cost);
}
pair<Cost, Flow> min_cost_flow(Index s, Index t, Flow f = InfCapacity, bool useSPFA = false)
{
Index n = (Index) g.size();
vector<Cost> dist(n);
vector<Cost> potential(n);
vector<Index> prev(n);
vector<Index> prev_edge(n);
pair<Cost, Flow> total = {0, 0};
while (f > 0)
{
fill(dist.begin(), dist.end(), InfCost);
if (useSPFA || total.second == 0)
{
vector<bool> in_queue(n);
deque<Index> q;
q.push_back(s);
dist[s] = 0;
in_queue[s] = true;
while (!q.empty())
{
Index i = q.front();
q.pop_front();
in_queue[i] = false;
for (Index ei = 0; ei < (Index) g[i].size(); ei++)
{
const Edge& e = g[i][ei];
Index j = e.to;
Cost d = dist[i] + e.cost;
if (e.capacity > 0 && d < dist[j])
{
if (!in_queue[j])
{
in_queue[j] = true;
q.push_back(j);
}
dist[j] = d;
prev[j] = i;
prev_edge[j] = ei;
}
}
}
}
else
{
vector<bool> visited(n, false);
priority_queue< pair<Cost, Index>, vector< pair<Cost, Index> >, std::greater< pair<Cost, Index> > > q;
q.push({0, s});
dist[s] = 0;
while (!q.empty())
{
Index i = q.top().second;
q.pop();
if (visited[i]) continue;
visited[i] = true;
for (Index ei = 0; ei < (Index) g[i].size(); ei++)
{
const Edge& e = g[i][ei];
if (e.capacity <= 0) continue;
Index j = e.to;
Cost d = dist[i] + (e.cost + potential[i] - potential[j]);
if (d < dist[j])
{
dist[j] = d;
prev[j] = i;
prev_edge[j] = ei;
q.push({d, j});
}
}
}
}
if (dist[t] == InfCost) break;
if (!useSPFA) for (Index i = 0; i < n; i++) potential[i] += dist[i];
Flow d = f;
Cost dist_t = 0;
for (Index v = t; v != s; )
{
Index u = prev[v];
const Edge& e = g[u][prev_edge[v]];
d = min(d, e.capacity);
dist_t += e.cost;
v = u;
}
f -= d;
total.first += d * dist_t;
total.second += d;
for (Index v = t; v != s; )
{
Index u = prev[v];
Edge& e = g[u][prev_edge[v]];
e.capacity -= d;
g[e.to][e.rev].capacity += d;
v = u;
}
}
return total;
}
};
const long long MinCostFlow::InfCost;
const long long MinCostFlow::InfCapacity;
int main(int argc, char* argv[])
{
freopen("cmcm.in", "r", stdin);
freopen("cmcm.out", "w", stdout);
cin.sync_with_stdio(false);
int N, M, E;
cin >> N >> M >> E;
MinCostFlow mf;
mf.init(N + M + 2);
int s = 0, t = N + M + 1;
for (int i = 0; i < E; i++)
{
int x, y, c;
cin >> x >> y >> c;
mf.add(x, y + N, 1, c);
}
for (int i = 1; i <= N; i++) mf.add(s, i, 1, 0);
for (int i = N + 1; i <= N + M; i++) mf.add(i, t, 1, 0);
auto ans = mf.min_cost_flow(s, t);
auto& g = mf.g;
cout << ans.second << " " << ans.first << "\n";
for (int i = 1; i <= N; i++)
{
for (auto& e : g[i])
{
if (e.capacity == 0)
{
cout << e.id << " ";
break;
}
}
}
cout << endl;
return 0;
}