#pragma region GCC_CP_Directives
#ifndef ITS_PERSONAL
#define __FAST_GCC_DIRECTIVE_1 GCC optimize("Ofast")
#define __FAST_GCC_DIRECTIVE_2 GCC optimize ("unroll-loops")
#define __FAST_GCC_DIRECTIVE_3 GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma OPTIMIZE1
#pragma OPTIMIZE2
#pragma OPTIMIZE3
#undef __FAST_GCC_DIRECTIVE_1
#undef __FAST_GCC_DIRECTIVE_2
#undef __FAST_GCC_DIRECTIVE_3
#endif
#pragma endregion GCC_CP_Directives
#pragma comment(linker, "/STACK:256000000")
#include <bits/stdc++.h>
using namespace std;
/// MACROs
#define FOR(i,a,b) for(int i = (a); i <= (b); ++i)
// Meta constants
#define USE_FILES 1
#if USE_FILES == 1
ifstream fffin("cmcm.in");
ofstream fffout("cmcm.out");
#endif
// Meta constants
const bool MULTIPLE_CASES = 0;
const bool PRINT_CASE_MSG = 0;
const int DOUBLE_PRECISION = 6; // 0 - don't set fixed precision,
struct Flux_minCost
{
// CAREFUL!!
// does NOT support multi-edges between 2 nodes
static constexpr int NODES = 300 * 2 + 5;
static constexpr int INF = 1e9;
int n;
int cap[NODES + 2][NODES + 2];
int cost[NODES + 2][NODES + 2];
Flux_minCost(int nodes) : n(nodes)
{ }
void setEdge(int from, int to, int capacity, int price)
{
cap[from][to] += capacity;
cost[from][to] = price;
cost[to][from] = -price;
}
pair<int, int> maxflow_mincost(int source, int dest)
{
assert(1 <= source && source <= n);
assert(1 <= dest && dest <= n);
int father[NODES + 2];
fill(father, father + NODES + 2, 0);
auto bellman = [&]() -> bool
{
int dist[NODES + 2];
queue<int> q;
bool in_queue[NODES + 2];
fill(dist, dist + NODES + 1, INF);
dist[source] = 0;
q.push(source);
in_queue[source] = true;
while (!q.empty()) {
int nod = q.front();
in_queue[nod] = false;
q.pop();
for (int i = 1; i <= NODES; ++i) {
if (cap[nod][i] && dist[nod] + cost[nod][i] < dist[i]) {
dist[i] = dist[nod] + cost[nod][i];
father[i] = nod;
if (!in_queue[i]) {
in_queue[i] = true;
q.push(i);
}
}
}
}
return dist[dest] != INF;
};
int flowed = 0, ans = 0;
while (bellman()) {
int minim = INF;
int nod = dest;
while (father[nod]) {
minim = min(minim, cap[father[nod]][nod]);
nod = father[nod];
}
flowed += minim;
nod = dest;
while (father[nod]) {
cap[ father[nod] ][ nod ] -= minim;
cap[ nod ][ father[nod] ] += minim;
ans += minim * cost[ father[nod] ][ nod ];
nod = father[nod];
}
}
return {flowed, ans};
}
};
// type definitions
using i64 = long long;
using pii = pair<int, int>;
using Graph = vector<vector<int>>;
// Problem constants
const int INF = (1 << 30);
const int NMAX = 8e4 + 3;
void solve()
{
int N, M, E;
cin >> N >> M >> E;
vector<pii> edges;
Flux_minCost flux(N + M + 2);
FOR (i, 1, E) {
int x, y, c;
cin >> x >> y >> c;
edges.push_back({x, N + y});
flux.setEdge(x, N + y, 1, c);
}
FOR (i, 1, N)
flux.setEdge(N + M + 1, i, 1, 0);
FOR (i, N + 1, N + M)
flux.setEdge(i, N + M + 2, 1, 0);
auto leFlow = flux.maxflow_mincost(N + M + 1, N + M + 2);
cout << leFlow.first << ' ' << leFlow.second << '\n';
FOR (i, 1, E) {
int x = edges[i - 1].first, y = edges[i - 1].second;
if (flux.cap[x][y] == 0)
cout << i << ' ';
}
cout << '\n';
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#if USE_FILES == 1
cin.rdbuf(fffin.rdbuf());
cout.rdbuf(fffout.rdbuf());
#endif
#ifdef ITS_PERSONAL
auto _time_begin = std::chrono::high_resolution_clock::now();
#endif
if (DOUBLE_PRECISION > 0)
cout << setprecision(DOUBLE_PRECISION) << fixed;
auto testMessage = [](int id) {
return "Case #" + to_string(id) + ": ";
};
int T = 1;
if (MULTIPLE_CASES)
cin >> T;
for (int t = 1; t <= T; ++t) {
cout << (PRINT_CASE_MSG ? testMessage(t) : "");
solve();
}
#ifdef ITS_PERSONAL
auto _time_end = std::chrono::high_resolution_clock::now();
cerr << setprecision(4) << fixed;
cerr << "Execution time: " << std::chrono::duration_cast<std::chrono::duration<double>>(_time_end - _time_begin).count() << " seconds" << endl;
#endif
}