#include <bits/stdc++.h>
using namespace std;
const int maxn = 20001;
int id, S, T, pp[maxn], tp[maxn][17], dep[maxn];
int lg[maxn], f[maxn][17];
int n, m;
map<pair<int, int>, int> mp;
struct flow {
  int he[maxn << 6], ne[maxn << 6], to[maxn << 6], w[maxn << 6], cnt;
  flow() { cnt = 1; }
  void addedge(int x, int y, int z) {
    ne[++cnt] = he[x], he[x] = cnt, to[cnt] = y, w[cnt] = z;
    ne[++cnt] = he[y], he[y] = cnt, to[cnt] = x, w[cnt] = 0;
  }
  int de[maxn << 6];
  int bfs() {
    for (int i = (1); i <= (id); ++i) de[i] = 0;
    de[S] = 1;
    queue<int> q;
    q.push(S);
    while (q.size()) {
      int x = q.front();
      q.pop();
      for (int i = he[x]; i; i = ne[i]) {
        if (w[i] && de[to[i]] == 0) {
          de[to[i]] = de[x] + 1;
          q.push(to[i]);
        }
      }
    }
    return de[T];
  }
  int cur[maxn << 6];
  int dfs(int x, int low) {
    if (low == 0 || x == T) return low;
    int ans = 0;
    for (int i = cur[x]; i && ans < low; i = ne[i]) {
      cur[x] = i;
      if (w[i] && de[to[i]] == de[x] + 1) {
        int qwq = dfs(to[i], min(low - ans, w[i]));
        ans += qwq, w[i] -= qwq, w[i ^ 1] += qwq;
      }
    }
    return ans;
  }
  int dinic() {
    int ans = 0;
    while (bfs()) {
      for (int i = (1); i <= (id); ++i) cur[i] = he[i];
      ans += dfs(S, 1e9);
    }
    return ans;
  }
  void coutans() {
    vector<int> a1, a2;
    for (int i = (1); i <= (m); ++i)
      if (de[pp[i]] == 0) a1.push_back(i);
    for (int i = (2); i <= (n); ++i)
      if (de[tp[i][0]]) a2.push_back(mp[{i, f[i][0]}]);
    printf("%d\n", (int)(a1.size() + a2.size()));
    printf("%d ", (int)a1.size());
    for (int i = (0); i <= ((int)a1.size() - 1); ++i) printf("%d ", a1[i]);
    printf("\n");
    printf("%d ", (int)a2.size());
    for (int i = (0); i <= ((int)a2.size() - 1); ++i) printf("%d ", a2[i]);
  }
} F;
struct tree {
  int he[maxn], ne[maxn << 1], to[maxn << 1], cnt;
  void addedge(int x, int y) {
    ne[++cnt] = he[x], he[x] = cnt, to[cnt] = y;
    ne[++cnt] = he[y], he[y] = cnt, to[cnt] = x;
  }
  void dfs(int x, int fa) {
    f[x][0] = fa;
    dep[x] = dep[fa] + 1;
    for (int i = (1); i <= (lg[dep[x]]); ++i) f[x][i] = f[f[x][i - 1]][i - 1];
    tp[x][0] = ++id;
    for (int i = (1); i <= (lg[dep[x]]); ++i) {
      tp[x][i] = ++id;
      F.addedge(tp[x][i], tp[x][i - 1], 1e9);
      F.addedge(tp[x][i], tp[f[x][i - 1]][i - 1], 1e9);
    }
    for (int i = he[x]; i; i = ne[i]) {
      if (to[i] == fa) continue;
      dfs(to[i], x);
    }
  }
  int lca(int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    for (int i = lg[dep[x] - dep[y]]; i >= 0; i--) {
      if (dep[f[x][i]] >= dep[y]) x = f[x][i];
    }
    if (x == y) return x;
    for (int i = lg[dep[x]]; i >= 0; i--) {
      if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
    }
    return f[x][0];
  }
  int jump(int x, int k) {
    for (int i = lg[dep[x]]; i >= 0; i--) {
      if (k & (1 << i)) x = f[x][i];
    }
    return x;
  }
} tr;
int main() {
  lg[1] = 0;
  for (int i = (2); i <= (maxn - 1); ++i) lg[i] = lg[i >> 1] + 1;
  scanf("%d%d", &n, &m);
  for (int i = (1); i <= (n - 1); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    tr.addedge(a, b);
    mp[{a, b}] = mp[{b, a}] = i;
  }
  tr.dfs(1, 0);
  for (int i = (1); i <= (m); ++i) {
    pp[i] = ++id;
    int a, b;
    scanf("%d%d", &a, &b);
    int c = tr.lca(a, b);
    {
      int d = dep[a] - dep[c], t = tr.jump(a, d - (1 << lg[d]));
      if (d)
        F.addedge(pp[i], tp[t][lg[d]], 1e9),
            t != b ? (F.addedge(pp[i], tp[a][lg[d]], 1e9), 0) : 0;
    }
    {
      int d = dep[b] - dep[c], t = tr.jump(b, d - (1 << lg[d]));
      if (d)
        F.addedge(pp[i], tp[t][lg[d]], 1e9),
            t != b ? (F.addedge(pp[i], tp[b][lg[d]], 1e9), 0) : (0);
    }
  }
  S = ++id, T = ++id;
  for (int i = (1); i <= (n); ++i) F.addedge(tp[i][0], T, 1);
  for (int i = (1); i <= (m); ++i) F.addedge(S, pp[i], 1);
  F.dinic();
  F.coutans();
  return 0;
}
