#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 20000;
const int MAXM = MAXN - 1;
const int MAXQ = 10000;
const int MAXLGN = 14;
const int MAXID = MAXN * (MAXLGN + 1) + MAXQ + 2;
const int MAXE = MAXQ + MAXN - 1 + 2 * MAXN * MAXLGN + 2 * MAXLGN * MAXQ;
int n, nq, nid;
int ghead[MAXN], gnxt[2 * MAXM], gto[2 * MAXM];
int d[MAXN];
int sid, tid, qid[MAXQ];
int up[MAXN][MAXLGN + 1];
int upid[MAXN][MAXLGN + 1];
void dfs(int at, int par) {
  up[at][0] = par;
  d[at] = par == -1 ? 0 : d[par] + 1;
  for (int k = 1; (1 << k) <= d[at]; ++k)
    up[at][k] = up[up[at][k - 1]][k - 1], upid[at][k] = nid++;
  for (int x = ghead[at]; x != -1; x = gnxt[x]) {
    int to = gto[x];
    if (to == par) continue;
    dfs(to, at);
  }
}
vector<int> getpath(int a, int b) {
  vector<int> ret;
  if (d[a] < d[b]) swap(a, b);
  {
    int k = 0;
    while (d[a] - (1 << k) >= d[b]) ++k;
    for (--k; k >= 0; --k)
      if (d[a] - (1 << k) >= d[b]) ret.push_back(upid[a][k]), a = up[a][k];
  }
  {
    int k = 0;
    while ((1 << k) <= d[a]) ++k;
    for (--k; k >= 0; --k)
      if (up[a][k] != up[b][k])
        ret.push_back(upid[a][k]), ret.push_back(upid[b][k]), a = up[a][k],
                                                              b = up[b][k];
  }
  if (a != b) {
    assert(d[a] >= 1 && up[a][0] == up[b][0]);
    ret.push_back(upid[a][0]), ret.push_back(upid[b][0]);
  }
  return ret;
}
typedef struct MF {
  int n, m;
  int ghead[MAXID], gnxt[2 * MAXE], gto[2 * MAXE], gcap[2 * MAXE];
  void init(int _n) {
    n = _n, m = 0;
    for (int i = (0); i < (n); ++i) ghead[i] = -1;
  }
  void addedge(int a, int b, int c) {
    gnxt[2 * m + 0] = ghead[a], ghead[a] = 2 * m + 0, gto[2 * m + 0] = b,
                 gcap[2 * m + 0] = c;
    gnxt[2 * m + 1] = ghead[b], ghead[b] = 2 * m + 1, gto[2 * m + 1] = a,
                 gcap[2 * m + 1] = 0;
    ++m;
  }
  int d[MAXID];
  int q[MAXID], qhead, qtail;
  int cur[MAXID];
  int solve(int s, int t) {
    int ret = 0;
    while (true) {
      for (int i = (0); i < (n); ++i) d[i] = INT_MAX;
      qhead = qtail = 0;
      d[s] = 0, q[qhead++] = s;
      while (qtail < qhead) {
        int at = q[qtail++];
        for (int x = ghead[at]; x != -1; x = gnxt[x]) {
          int to = gto[x];
          if (gcap[x] == 0 || d[to] != INT_MAX) continue;
          d[to] = d[at] + 1;
          q[qhead++] = to;
        }
      }
      if (d[t] == INT_MAX) return ret;
      for (int i = (0); i < (n); ++i) cur[i] = ghead[i];
      ret += dfs(s, t, INT_MAX);
    }
  }
  int dfs(int at, int t, int rem) {
    int ret = 0;
    if (at == t) return rem;
    if (d[at] >= d[t]) return 0;
    for (; cur[at] != -1; cur[at] = gnxt[cur[at]]) {
      int to = gto[cur[at]], cap = gcap[cur[at]];
      if (d[to] != d[at] + 1 || cap == 0) continue;
      int now = dfs(to, t, min(cap, rem));
      rem -= now;
      ret += now;
      gcap[cur[at]] -= now;
      gcap[cur[at] ^ 1] += now;
      if (rem == 0) return ret;
    }
    return ret;
  }
  void print() {
    for (int i = (0); i < (m); ++i)
      if (gcap[2 * i + 0] == 0)
        printf("used %d->%d\n", gto[2 * i + 1], gto[2 * i + 0]);
  }
} MF;
MF mf;
void run() {
  scanf("%d%d", &n, &nq);
  nid = 0;
  for (int i = (0); i < (n); ++i) ghead[i] = -1;
  for (int i = (0); i < (n - 1); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    gnxt[2 * i + 0] = ghead[a];
    ghead[a] = 2 * i + 0;
    gto[2 * i + 0] = b;
    gnxt[2 * i + 1] = ghead[b];
    ghead[b] = 2 * i + 1;
    gto[2 * i + 1] = a;
  }
  memset(up, -1, sizeof(up));
  memset(upid, -1, sizeof(up));
  sid = nid++;
  tid = nid++;
  for (int i = (0); i < (nq); ++i) qid[i] = nid++;
  for (int i = (1); i <= (n); ++i) upid[i][0] = nid++;
  dfs(0, -1);
  mf.init(nid);
  for (int i = (0); i < (nq); ++i) mf.addedge(sid, qid[i], 1);
  for (int i = (1); i < (n); ++i) mf.addedge(upid[i][0], tid, 1);
  for (int i = (0); i < (n); ++i)
    for (int k = 1; (1 << k) <= d[i]; ++k)
      mf.addedge(upid[i][k], upid[i][k - 1], nq + 1),
          mf.addedge(upid[i][k], upid[up[i][k - 1]][k - 1], nq + 1);
  for (int i = (0); i < (nq); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    vector<int> path = getpath(a, b);
    for (int j = (0); j < (((int)(path).size())); ++j)
      mf.addedge(qid[i], path[j], nq + 1);
  }
  int ret = mf.solve(sid, tid);
  printf("%d\n", ret);
  vector<int> citizen, guardian;
  for (int i = (0); i < (nq); ++i)
    if (mf.d[qid[i]] == INT_MAX) citizen.push_back(i);
  for (int i = (1); i < (n); ++i)
    if (mf.d[upid[i][0]] != INT_MAX)
      for (int x = ghead[i]; x != -1; x = gnxt[x])
        if (gto[x] == up[i][0]) guardian.push_back(x >> 1);
  printf("%d", ((int)(citizen).size()));
  for (int i = (0); i < (((int)(citizen).size())); ++i)
    printf(" %d", citizen[i] + 1);
  puts("");
  printf("%d", ((int)(guardian).size()));
  for (int i = (0); i < (((int)(guardian).size())); ++i)
    printf(" %d", guardian[i] + 1);
  puts("");
}
int main() {
  run();
  return 0;
}
