#include <bits/stdc++.h>
using namespace std;
template <class T>
void read(T& num) {
  char CH;
  bool F = false;
  for (CH = getchar(); CH < '0' || CH > '9'; F = CH == '-', CH = getchar())
    ;
  for (num = 0; CH >= '0' && CH <= '9';
       num = num * 10 + CH - '0', CH = getchar())
    ;
  F && (num = -num);
}
const int maxn = 1e6 + 100;
const int inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
inline long long mul(long long a, long long b) {
  long long c = a * b - (long long)((long double)a * b / mod + 0.5) * mod;
  return c < 0 ? c + mod : c;
}
int head1[maxn], ver1[maxn], edge1[maxn], Next1[maxn], d[maxn];
int n, m, s, t, tot1, maxflow;
vector<int> ans1, ans2;
queue<int> q;
void add_e(int x, int y, int z) {
  ver1[++tot1] = y, edge1[tot1] = z, Next1[tot1] = head1[x], head1[x] = tot1;
  ver1[++tot1] = x, edge1[tot1] = 0, Next1[tot1] = head1[y], head1[y] = tot1;
}
bool bfs() {
  memset(d, 0, sizeof d);
  while (!q.empty()) q.pop();
  q.push(s);
  d[s] = 1;
  while (!q.empty()) {
    int x = q.front();
    q.pop();
    for (int i = head1[x]; i; i = Next1[i]) {
      if (edge1[i] && !d[ver1[i]]) {
        q.push(ver1[i]);
        d[ver1[i]] = d[x] + 1;
        if (ver1[i] == t) return 1;
      }
    }
  }
  return 0;
}
int dinic(int x, int flow) {
  if (x == t) return flow;
  int rest = flow, k;
  for (int i = head1[x]; i && rest; i = Next1[i]) {
    if (edge1[i] && d[ver1[i]] == d[x] + 1) {
      k = dinic(ver1[i], min(rest, edge1[i]));
      if (!k) d[ver1[i]] = 0;
      edge1[i] -= k;
      edge1[i ^ 1] += k;
      rest -= k;
    }
  }
  return flow - rest;
}
int tot, head[maxn], Next[maxn], ver[maxn], wt[maxn], maxx[maxn];
int a[maxn << 2], lazy[maxn << 2], idd[maxn];
map<pair<int, int>, int> w;
int son[maxn], id[maxn], fa[maxn], cnt, dep[maxn], siz[maxn], top[maxn];
int res = 0;
inline void add(int x, int y) {
  ver[++tot] = y;
  Next[tot] = head[x];
  head[x] = tot;
}
int ecnt = 0;
inline void build(int rt, int l, int r) {
  idd[rt] = ++ecnt;
  if (l == r) {
    a[wt[l]] = idd[rt];
    add_e(idd[rt], t, 1);
    return;
  }
  build(rt << 1, l, ((l + r) >> 1));
  build(rt << 1 | 1, ((l + r) >> 1) + 1, r);
  add_e(idd[rt], idd[rt << 1], inf);
  add_e(idd[rt], idd[rt << 1 | 1], inf);
}
inline void update(int rt, int l, int r, int L, int R, int k) {
  if (l > R || r < L) return;
  if (L <= l && r <= R) {
    add_e(k, idd[rt], inf);
    return;
  }
  update(rt << 1, l, ((l + r) >> 1), L, R, k);
  update(rt << 1 | 1, ((l + r) >> 1) + 1, r, L, R, k);
}
inline void updRange(int x, int y, int k) {
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    update(1, 1, n, id[top[x]], id[x], k);
    x = fa[top[x]];
  }
  if (dep[x] > dep[y]) swap(x, y);
  update(1, 1, n, id[x] + 1, id[y], k);
}
inline void dfs1(int x, int f, int deep) {
  dep[x] = deep;
  fa[x] = f;
  siz[x] = 1;
  int maxson = -1;
  for (int i = head[x]; i; i = Next[i]) {
    int y = ver[i];
    if (y == f) continue;
    dfs1(y, x, deep + 1);
    siz[x] += siz[y];
    if (siz[y] > maxson) son[x] = y, maxson = siz[y];
  }
}
inline void dfs2(int x, int topf) {
  id[x] = ++cnt;
  wt[cnt] = w[make_pair(x, fa[x])];
  top[x] = topf;
  if (!son[x]) return;
  dfs2(son[x], topf);
  for (int i = head[x]; i; i = Next[i]) {
    int y = ver[i];
    if (y == fa[x] || y == son[x]) continue;
    dfs2(y, y);
  }
}
int b[maxn], vis[maxn];
void dfs_get(int x) {
  vis[x] = 1;
  for (int i = head1[x]; i; i = Next1[i]) {
    if (edge1[i] && !vis[ver1[i]]) {
      dfs_get(ver1[i]);
    }
  }
}
int main() {
  tot = 0;
  tot1 = 1;
  read(n);
  read(m);
  for (int i = 1; i < n; i++) {
    int x, y;
    read(x);
    read(y);
    add(x, y);
    add(y, x);
    w[make_pair(x, y)] = w[make_pair(y, x)] = i;
  }
  s = ++ecnt;
  t = ++ecnt;
  dfs1(1, 0, 1);
  dfs2(1, 1);
  build(1, 1, n);
  for (int i = 1; i <= m; i++) {
    int x, y;
    read(x);
    read(y);
    b[i] = ++ecnt;
    add_e(s, b[i], 1);
    updRange(x, y, b[i]);
  }
  int flow = 0;
  while (bfs()) {
    while (flow = dinic(s, inf)) maxflow += flow;
  }
  printf("%d\n", maxflow);
  dfs_get(s);
  for (int i = 1; i <= m; ++i) {
    if (!vis[b[i]]) {
      ans1.push_back(i);
    }
  }
  for (int i = 1; i < n; ++i) {
    if (vis[a[i]]) {
      ans2.push_back(i);
    }
  }
  printf("%d ", (int)(ans1.size()));
  for (int i = 0; i < ans1.size(); ++i) {
    printf("%d ", ans1[i]);
  }
  printf("\n%d ", (int)(ans2.size()));
  for (int i = 0; i < ans2.size(); ++i) {
    printf("%d ", ans2[i]);
  }
  puts("");
  return 0;
}
