#include <bits/stdc++.h>
using std::cerr;
using std::endl;
inline int rd() {
  int x;
  scanf("%d", &x);
  return x;
}
const int N = 2e4 + 233, INF = 1e9;
int n, m, dep[N], dad[N][20], id[N][20], num, s, t;
std::map<std::pair<int, int>, int> map;
int edge_id[N];
std::vector<int> T[N];
struct Graph {
  int to, nxt, flow;
} G[N * 100];
int head[N * 20], etot = 1;
inline void addedge(int x, int y, int f) {
  G[++etot] = {y, head[x], f}, head[x] = etot;
  G[++etot] = {x, head[y], 0}, head[y] = etot;
}
void dfs(int x, int fa) {
  dad[x][0] = fa, dep[x] = dep[fa] + 1;
  if (x != 1) {
    id[x][0] = ++num;
    edge_id[map[std::make_pair(std::min(x, fa), std::max(x, fa))]] = num;
    addedge(id[x][0], t, 1);
    for (int i = 1; i <= 15; ++i) {
      dad[x][i] = dad[dad[x][i - 1]][i - 1];
      if (!dad[x][i]) break;
      id[x][i] = ++num;
      addedge(id[x][i], id[x][i - 1], INF);
      if (dad[x][i - 1] && dad[x][i - 1] != 1)
        addedge(id[x][i], id[dad[x][i - 1]][i - 1], INF);
    }
  }
  for (int y : T[x])
    if (y != fa) dfs(y, x);
}
inline int get_lca(int x, int y) {
  if (dep[x] < dep[y]) std::swap(x, y);
  for (int i = 15; ~i; --i)
    if (dep[dad[x][i]] >= dep[y]) x = dad[x][i];
  if (x == y) return x;
  for (int i = 15; ~i; --i)
    if (dad[x][i] != dad[y][i]) x = dad[x][i], y = dad[y][i];
  return dad[x][0];
}
inline void work(int x, int y, int st) {
  for (int i = 15; ~i; --i)
    if (dep[dad[x][i]] >= dep[y]) {
      addedge(st, id[x][i], INF);
      x = dad[x][i];
    }
}
int dis[N * 20], cur[N * 20];
std::queue<int> que;
inline bool bfs() {
  for (int i = 1; i <= num; ++i) dis[i] = 0, cur[i] = head[i];
  dis[s] = 1, que.push(s);
  while (!que.empty()) {
    int x = que.front();
    que.pop();
    for (int i = head[x]; i; i = G[i].nxt) {
      int y = G[i].to;
      if (G[i].flow && !dis[y]) {
        dis[y] = dis[x] + 1;
        que.push(y);
      }
    }
  }
  return dis[t];
}
int Dfs(int x, int mf) {
  if (x == t) return mf;
  int used = 0;
  for (int &i = cur[x]; i; i = G[i].nxt) {
    int y = G[i].to;
    if (G[i].flow && dis[y] == dis[x] + 1) {
      int tmp = Dfs(y, std::min(mf - used, G[i].flow));
      if (!tmp)
        dis[y] = -1;
      else {
        G[i].flow -= tmp, G[i ^ 1].flow += tmp;
        if ((used += tmp) == mf) break;
      }
    }
  }
  return used;
}
inline void dinic() {
  int flow = 0;
  while (bfs()) flow += Dfs(s, INF);
  printf("%d\n", flow);
  std::vector<int> ans;
  for (int i = 1; i <= m; ++i)
    if (!dis[i]) ans.emplace_back(i);
  printf("%d ", (int)ans.size());
  for (int i : ans) printf("%d ", i);
  putchar('\n');
  ans.clear();
  for (int i = 1; i < n; ++i)
    if (dis[edge_id[i]]) ans.emplace_back(i);
  printf("%d ", (int)ans.size());
  for (int i : ans) printf("%d ", i);
  putchar('\n');
}
int main() {
  n = rd(), m = rd();
  for (int i = 1; i < n; ++i) {
    int x = rd(), y = rd();
    T[x].push_back(y);
    T[y].push_back(x);
    map[std::make_pair(std::min(x, y), std::max(x, y))] = i;
  }
  num = m, s = ++num, t = ++num, dfs(1, 0);
  for (int i = 1; i <= m; ++i) {
    int x = rd(), y = rd(), lca = get_lca(x, y);
    work(x, lca, i), work(y, lca, i);
  }
  for (int i = 1; i <= m; ++i) addedge(s, i, 1);
  dinic();
  return 0;
}
