#include <bits/stdc++.h>
using namespace std;
const int MAXN = 4010;
const int INF = 0x7fffffff;
const double eps = 1e-8;
struct Edge {
  int from, to, flow, cap;
};
int deg[MAXN];
int ans[4000000], ts;
struct ISAP {
  int n, m, s, t;
  vector<Edge> edges;
  vector<int> G[MAXN];
  int p[MAXN];
  int num[MAXN];
  bool vis[MAXN];
  int d[MAXN];
  int cur[MAXN];
  void init(int _n, int _s, int _t) {
    n = _n, s = _s, t = _t;
    memset(p, 0, sizeof(p));
    memset(num, 0, sizeof(num));
    memset(vis, 0, sizeof(vis));
    memset(d, 0, sizeof(d));
    memset(cur, 0, sizeof(cur));
    edges.clear();
    for (int i = 0; i < MAXN; i++) G[i].clear();
  }
  void addedge(int from, int to, int cap) {
    edges.push_back((Edge){from, to, 0, cap});
    edges.push_back((Edge){to, from, 0, 0});
    m = edges.size();
    G[from].push_back(m - 2);
    G[to].push_back(m - 1);
  }
  bool BFS() {
    memset(vis, 0, sizeof(vis));
    queue<int> Q;
    Q.push(t);
    d[t] = 0;
    vis[t] = 1;
    while (!Q.empty()) {
      int x = Q.front();
      Q.pop();
      for (int i = 0; i < G[x].size(); i++) {
        Edge& e = edges[G[x][i] ^ 1];
        if (!vis[e.from] && e.cap > e.flow) {
          vis[e.from] = 1;
          d[e.from] = d[x] + 1;
          Q.push(e.from);
        }
      }
    }
    return vis[s];
  }
  int Augment() {
    int x = t;
    int a = INF;
    while (x != s) {
      Edge& e = edges[p[x]];
      a = min(a, e.cap - e.flow);
      x = edges[p[x]].from;
    }
    x = t;
    while (x != s) {
      edges[p[x]].flow += a;
      edges[p[x] ^ 1].flow -= a;
      x = edges[p[x]].from;
    }
    return a;
  }
  long long MaxFlow(int s, int t) {
    this->s = s;
    this->t = t;
    long long flow = 0;
    BFS();
    memset(num, 0, sizeof(num));
    for (int i = 1; i <= n; i++) num[d[i]]++;
    int x = s;
    memset(cur, 0, sizeof(cur));
    while (d[s] < n) {
      if (x == t) {
        flow += Augment();
        x = s;
      }
      int ok = 0;
      for (int i = cur[x]; i < G[x].size(); i++) {
        Edge& e = edges[G[x][i]];
        if (e.cap > e.flow && d[x] == d[e.to] + 1) {
          ok = 1;
          p[e.to] = G[x][i];
          cur[x] = i;
          x = e.to;
          break;
        }
      }
      if (!ok) {
        int m = n - 1;
        for (int i = 0; i < G[x].size(); i++) {
          Edge& e = edges[G[x][i]];
          if (e.cap > e.flow) m = min(m, d[e.to]);
        }
        if (--num[d[x]] == 0) break;
        num[d[x] = m + 1]++;
        cur[x] = 0;
        if (x != s) x = edges[p[x]].from;
      }
    }
    return flow;
  }
  void addflow() {
    for (int i = 0; i < G[s].size(); i++) {
      Edge& e = edges[G[s][i]];
      e.cap++;
    }
    for (int i = 0; i < G[t].size(); i++) {
      Edge& e = edges[G[t][i] ^ 1];
      e.cap++;
    }
  }
} NetFlow;
int main() {
  int i, j, k;
  int n1, n2, m;
  int u, v, s, t, nn;
  scanf("%d%d%d", &n1, &n2, &m);
  nn = n1 + n2 + 2;
  s = nn + 1;
  t = nn + 2;
  NetFlow.init(nn, s, t);
  for (i = 1; i <= m; i++) {
    scanf("%d%d", &u, &v);
    NetFlow.addedge(u, v + n1, 1);
    deg[u]++;
    deg[v + n1]++;
  }
  int mindeg = m;
  for (i = 1; i <= n1 + n2; i++) {
    mindeg = min(mindeg, deg[i]);
  }
  for (i = 1; i <= n1; i++) NetFlow.addedge(s, i, deg[i] - mindeg);
  for (i = 1; i <= n2; i++) NetFlow.addedge(i + n1, t, deg[i + n1] - mindeg);
  int flow = 0;
  for (i = mindeg; i >= 1; i--) {
    flow += NetFlow.MaxFlow(s, t);
    for (j = 1; j <= m; j++)
      if (NetFlow.edges[j * 2 - 2].flow == 0) ans[++ts] = j;
    ans[++ts] = m - flow;
    ans[++ts] = -1;
    NetFlow.addflow();
  }
  ans[++ts] = 0;
  for (i = ts; i >= 1; i--)
    if (ans[i] == -1)
      printf("\n");
    else
      printf("%d ", ans[i]);
  return 0;
}
