#include <bits/stdc++.h>
using namespace std;
const int N = 2e4 + 5;
const int M = 1e6 + 5;
const int inf = 0x7fffffff;
struct Edge {
  int v, f, nxt;
} edge[M << 1];
int s, t, head[M], cnt, level[M];
queue<int> q;
void add(int u, int v, int f) {
  edge[cnt].v = v;
  edge[cnt].f = f;
  edge[cnt].nxt = head[u];
  head[u] = cnt++;
  edge[cnt].v = u;
  edge[cnt].f = 0;
  edge[cnt].nxt = head[v];
  head[v] = cnt++;
}
bool bfs() {
  memset(level, -1, sizeof(level));
  level[s] = 0;
  q.push(s);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = head[u]; i != -1; i = edge[i].nxt) {
      int v = edge[i].v;
      if (edge[i].f > 0 && level[v] < 0) {
        level[v] = level[u] + 1;
        q.push(v);
      }
    }
  }
  return level[t] > 0;
}
int dfs(int u, int mx) {
  if (u == t || !mx) return mx;
  int res = 0, tmp;
  for (int i = head[u]; i != -1 && mx; i = edge[i].nxt) {
    int v = edge[i].v;
    if (level[v] == level[u] + 1 && (tmp = dfs(v, min(mx, edge[i].f)))) {
      edge[i].f -= tmp;
      edge[i ^ 1].f += tmp;
      res += tmp;
      mx -= tmp;
    }
  }
  if (!res) level[u] = -1;
  return res;
}
int dinic() {
  int maxflow = 0;
  while (bfs()) {
    maxflow += dfs(s, inf);
  }
  return maxflow;
}
struct E {
  int v, id, nxt;
} e[N << 1];
int n, m, hd[N], ct;
int fa[N][25], dep[N], up[N], b[N][25];
void add_edge(int u, int v, int id) {
  e[++ct].v = v;
  e[ct].id = id;
  e[ct].nxt = hd[u];
  hd[u] = ct;
}
void dfsT(int u, int f) {
  for (int i = hd[u]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == f) continue;
    fa[v][0] = u;
    dep[v] = dep[u] + 1;
    up[v] = e[i].id;
    dfsT(v, u);
  }
}
int LCA(int u, int v) {
  if (dep[u] < dep[v]) swap(u, v);
  int diff = dep[u] - dep[v];
  for (int i = 20; i >= 0; i--) {
    if (diff & (1 << i)) u = fa[u][i];
  }
  for (int i = 20; i >= 0; i--) {
    if (fa[u][i] != fa[v][i]) {
      u = fa[u][i];
      v = fa[u][i];
    }
  }
  if (u == v)
    return u;
  else
    return fa[u][0];
}
void connect(int nd, int x, int tp) {
  int diff = dep[x] - dep[tp];
  for (int i = 20; i >= 0; i--) {
    if (diff & (1 << i)) {
      add(nd, b[x][i], inf);
      x = fa[x][i];
    }
  }
}
int nam[M];
bool vis[M];
vector<int> citizen, soldier;
void DFS(int u) {
  vis[u] = 1;
  for (int i = head[u]; i != -1; i = edge[i].nxt) {
    int v = edge[i].v;
    if (edge[i].f && !vis[v]) DFS(v);
  }
}
int main() {
  memset(head, -1, sizeof(head));
  scanf("%d%d", &n, &m);
  for (int i = 1; i < n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    add_edge(x, y, i);
    add_edge(y, x, i);
  }
  dfsT(1, 0);
  int num = 0;
  s = ++num;
  for (int i = 2; i <= n; i++) {
    b[i][0] = ++num;
    nam[num] = up[i];
  }
  for (int j = 1; j <= 20; j++) {
    for (int i = 1; i <= n; i++) {
      if (fa[fa[i][j - 1]][j - 1]) {
        fa[i][j] = fa[fa[i][j - 1]][j - 1];
        b[i][j] = ++num;
        add(b[i][j], b[i][j - 1], inf);
        add(b[i][j], b[fa[i][j - 1]][j - 1], inf);
      }
    }
  }
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    int lca = LCA(x, y);
    num++;
    nam[num] = i;
    add(s, num, 1);
    connect(num, x, lca);
    connect(num, y, lca);
  }
  t = ++num;
  for (int i = 2; i <= n; i++) add(b[i][0], t, 1);
  printf("%d\n", dinic());
  DFS(1);
  for (int i = head[s]; i != -1; i = edge[i].nxt) {
    int v = edge[i].v;
    if (!vis[v]) citizen.push_back(nam[v]);
  }
  for (int i = head[t]; i != -1; i = edge[i].nxt) {
    int v = edge[i].v;
    if (vis[v]) soldier.push_back(nam[v]);
  }
  printf("%d ", citizen.size());
  for (int i = 0; i < citizen.size(); i++) printf("%d ", citizen[i]);
  puts("");
  printf("%d ", soldier.size());
  for (int i = 0; i < soldier.size(); i++) printf("%d ", soldier[i]);
  return 0;
}
