#include <bits/stdc++.h>
using namespace std;
inline int getInt() {
  int s;
  scanf("%d", &s);
  return s;
}
class Tree {
 public:
  vector<vector<int> > next;
  vector<vector<int> > prev2;
  vector<int> depth;
  int root;
  Tree(const vector<vector<int> > &next, const vector<vector<int> > &prev2,
       const vector<int> depth, const int root)
      : next(next), prev2(prev2), depth(depth), root(root) {}
  int lca(int a, int b) {
    if (depth[a] > depth[b]) swap(a, b);
    int ddiff = depth[b] - depth[a];
    int dmax = prev2[0].size();
    for (int i = 0; i < (int)(dmax); i++) {
      if (ddiff & (1 << i)) b = prev2[b][i];
    }
    if (a == b) return a;
    for (int i = dmax - 1; i >= 0; i--) {
      if (prev2[a][i] != prev2[b][i]) {
        a = prev2[a][i];
        b = prev2[b][i];
      }
    }
    return prev2[a][0];
  }
};
Tree fromGraph(const vector<vector<int> > &g, int root = 0) {
  const int n = g.size();
  vector<vector<int> > next(n);
  vector<vector<int> > prev2(n);
  vector<int> depth(n, -1);
  queue<pair<int, int> > q;
  q.push(make_pair(root, -1));
  depth[root] = 0;
  prev2[root].push_back(root);
  while (q.size()) {
    const pair<int, int> d = q.front();
    q.pop();
    const int now = d.first;
    const int prev = d.second;
    for (int i = 0; i < (int)(g[now].size()); i++) {
      int next = g[now][i];
      if (next != prev) {
        q.push(make_pair(next, now));
        depth[next] = depth[now] + 1;
        prev2[next].push_back(now);
      }
    }
  }
  bool flag = true;
  while (flag) {
    const int last = prev2[root].size() - 1;
    flag = false;
    for (int i = 0; i < (int)(n); i++) {
      int data = prev2[prev2[i][last]][last];
      prev2[i].push_back(data);
      flag |= data != 0;
    }
  }
  return Tree(next, prev2, depth, root);
}
int main() {
  const int n = getInt();
  vector<vector<int> > g(n);
  vector<pair<int, int> > e;
  for (int i = 0; i < (int)(n - 1); i++) {
    const int a = getInt() - 1;
    const int b = getInt() - 1;
    g[a].push_back(b);
    g[b].push_back(a);
    e.push_back(make_pair(min(a, b), max(a, b)));
  }
  Tree t = fromGraph(g, 0);
  vector<int> memo(n);
  const int m = getInt();
  for (int i = 0; i < (int)(m); i++) {
    const int a = getInt() - 1;
    const int b = getInt() - 1;
    const int c = t.lca(a, b);
    memo[a]++;
    memo[b]++;
    memo[c]--;
    memo[c]--;
  }
  vector<pair<int, int> > d(n);
  for (int i = 0; i < (int)(n); i++) d[i] = make_pair(t.depth[i], i);
  sort(d.rbegin(), d.rend());
  map<pair<int, int>, int> ans;
  for (int i = 0; i < (int)(n); i++) {
    int j = d[i].second;
    int p = t.prev2[j][0];
    ans[make_pair(min(j, p), max(j, p))] += memo[j];
    memo[p] += memo[j];
  }
  for (int i = 0; i < (int)(n - 1); i++) {
    printf("%d%c", ans[e[i]], i == n - 2 ? '\n' : ' ');
  }
  return 0;
}
