#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
const int inf=100010;

typedef long long ll;

const int N = 100010;
struct e{
    int v;
    e* nxt;
}es[N<<1], *fir[N];

map<pair<int,int> ,int> mp;
struct node{
    int ls, rs;
    int l, r;
    int sum,add;

    int mid() { return (l + r) >> 1;  }
}nodes[N<<2];
int n, en, val[N];
int que[N], par[N], dep[N], root[N], seg[N], st[N], ed[N], top[N], sons[N], id[N];

int ln, cnt, tr;

inline void init(){
    en=0;
    memset(fir,0,sizeof(fir));
}
inline void add_e(int u, int v){
    es[en].v = v;
    es[en].nxt = fir[u];
    fir[u] = &es[en++];
}
inline void newNode(int &id, int l, int r){
    nodes[cnt].ls = nodes[cnt].rs = -1;
    nodes[cnt].l = l;
    nodes[cnt].r = r;
    id = cnt++;
}
void build(int &id, int l, int r){
    newNode(id, l, r);
    if(l+1>= r){
        nodes[id].sum=0;
        return ;
    }
    int mid = (l+r)>>1;
    build(nodes[id].ls, l, mid);
    build(nodes[id].rs, mid, r);
    nodes[id].sum=nodes[nodes[id].ls].sum+nodes[nodes[id].rs].sum;
}
void initTree(){
    int l, r, u, v, i;
    e* cur;
    l = r = 0;tr=1;
    que[r++] = tr;
    par[tr] = -1;
    dep[tr] = 0;
    while(l != r){
        u = que[l++];
        for(cur = fir[u]; cur; cur = cur->nxt){
            if((v = cur->v) != par[u]){
                que[r++] = v;
                par[v] = u;
                dep[v] = dep[u]+1;
            }
        }
    }
    for(i = 1; i <= n; i++){
        sons[i] = 1;
        id[i] = -1;
    }
    for(i = r-1; i >= 0; i--){
        u = que[i];
        if(par[u] >= 0){
            sons[par[u]] += sons[u];
        }
    }
    l = r = 0;
    que[r++] = tr;
    ln = cnt = 0;
    while(l != r){
        u = que[l++];
        st[ln] = dep[u];
        top[ln] = u;
        while(u >= 0){
            id[u] = ln;
            ed[ln] = dep[u];
            seg[dep[u]] = u;
            int best;
            for(cur = fir[u], best=-1; cur; cur = cur->nxt){
                if(id[v = cur->v] == -1){
                    if(best == -1 || (best >= 0 && sons[v] > sons[best])){
                        best = v;
                    }
                }
            }
            if(best >= 0){
                for(cur = fir[u]; cur; cur = cur->nxt){
                    if(id[v = cur->v] == -1 && best != v){
                        que[r++] = v;
                    }
                }
            }
            u = best;
        }
        root[ln] = -1;
        build(root[ln], st[ln], ed[ln]);
        ln++;
    }
}
int S;
void down(int id)
{
	if (nodes[id].ls != -1) {
		nodes[nodes[id].ls].add += nodes[id].add;
		nodes[nodes[id].ls].sum += nodes[id].add;
	}
	if (nodes[id].rs != -1) {
		nodes[nodes[id].rs].add += nodes[id].add;
		nodes[nodes[id].rs].sum += nodes[id].add;
	}
	nodes[id].add = 0;
}
void lqry(int &id, int ql, int qr){
    if(id == -1) return ;
    if(ql==qr) return;
    if(ql <= nodes[id].l  && nodes[id].r <= qr){
        S+=nodes[id].sum;
        return ;
    }
    if(nodes[id].l+1 == nodes[id].r){
        S+=nodes[id].sum;
        return ;
    }
    if(nodes[id].add)
       	down(id);
    int mid = (nodes[id].l+nodes[id].r)>>1;
    if(ql < mid){
       lqry(nodes[id].ls, ql, qr);
    }
    if(qr > mid){
       lqry(nodes[id].rs, ql, qr);
    }
    nodes[id].sum=0;
    if (nodes[id].ls != -1)
		nodes[id].sum += nodes[nodes[id].ls].sum;
	if (nodes[id].rs != -1)
		nodes[id].sum += nodes[nodes[id].rs].sum;
}

void update(int &id, int x,int y,int val)
{
    if(id == -1) return ;
    if(nodes[id].l+1 == nodes[id].r){
        nodes[id].sum+=val;
        return ;
    }
    if(x <= nodes[id].l  && nodes[id].r <= y){
    	 nodes[id].sum+=val;
    	 nodes[id].add+=val;
    	 return;
    }
    if(nodes[id].add)
    	down(id);
    int mid = (nodes[id].l+nodes[id].r)>>1;
    if(x<mid)
        update(nodes[id].ls, x, y,val);
    if(y>mid)
        update(nodes[id].rs, x, y,val);
    nodes[id].sum=0;
    if(nodes[id].ls!=-1)
    	nodes[id].sum+=nodes[nodes[id].ls].sum;
    if(nodes[id].rs!=-1)
        nodes[id].sum+=nodes[nodes[id].rs].sum;
}
void upd(int u, int v,int vv){
    while(id[u] != id[v]){
        if(id[u] > id[v]){
            swap(u, v);
        }
        int b = id[v];
        update(root[b], st[b], dep[v],vv);
        v = par[top[b]];
        if(mp.find(make_pair(top[b],par[top[b]]))!=mp.end())
        	val[mp[make_pair(top[b],par[top[b]])]]+=vv;
        else
        	val[mp[make_pair(par[top[b]],top[b])]]+=vv;
    }
    if(dep[u] > dep[v]){
        swap(u, v);
    }
    update(root[id[u]], dep[u], dep[v],vv);
}
void qry(int u, int v){
    while(id[u] != id[v]){
        if(id[u] > id[v]){
            swap(u, v);
        }
        int b = id[v];
        lqry(root[b], st[b], dep[v]);
        v = par[top[b]];
        if(mp.find(make_pair(top[b],par[top[b]]))!=mp.end()){
        	S+=val[mp[make_pair(top[b],par[top[b]])]];
        }
        else{
        	S+=val[mp[make_pair(par[top[b]],top[b])]];
        }
    }
    if(dep[u] > dep[v]){
        swap(u, v);
    }
    lqry(root[id[u]], dep[u], dep[v]);
}
struct ee{
	int x,y;
}edge[100010];
int main(){
    int m,x,y,u,v;
    scanf("%d",&n);
    init();
    for(int i=1;i<n;i++){
      scanf("%d%d",&x,&y);
      mp[make_pair(x,y)]=i;
      edge[i].x=x;edge[i].y=y;
      add_e(x,y);
      add_e(y,x);
    }
    initTree();

	scanf("%d", &m);
	for (int i = 0; i < m; i++) {
		scanf("%d%d",&u,&v);
		upd(u, v, 1);
	}
	for(int i=1;i<n;i++){
		S = 0;
		qry(edge[i].x,edge[i].y);
		if(i!=n-1)
			printf("%d ",S);
		else
			printf("%d\n",S);
	}
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<cmath>
#include<assert.h>

#define FO(i,s,e,p) for(int i=(s);i<(e);i+=p)
#define FOD(i,s,e,p) for(int i=(s);i>(e);i-=p)

#define FOR(i,s,e) FO(i,s,e,1)
#define FORE(i,s,e) FOR(i,s,e+1)
#define FORD(i,s,e) FOD(i,s,e,1)
#define FORDE(i,s,e) FORD(i,s,e-1)

#define ALL(i,s) for(__typeof(s.begin()) i=s.begin();i!=s.end();i++)

#define MEM(tab,fill) memset(tab,fill,sizeof(tab))

#include<iostream>
#include<set>
#include<vector>
#include<string>
#include<sstream>
#include<stack>
#include<queue>
#include<algorithm>
#include<utility>
#include<bitset>
#include<map>

using namespace std;
#define ll long long
#define inf ((1<<20)-1)
#define deb(a) cout<<#a<<" "<<a<<endl
#define pb push_back
#define mp make_pair

#define llu unsigned long long
#define PI pair<int,int>

#define SZ 100100
#define LG 20

int p[SZ][LG];
int ad[SZ][LG];

int in[SZ],out[SZ];

int bs;

int cl=0;

vector<int> g[SZ];

void dfs(int nod,int pp=0)
{
    p[nod][0]=pp;
    FOR(i,1,LG) p[nod][i]=p[p[nod][i-1]][i-1];

    in[nod]=cl++;
    ALL(i,g[nod]) if(*i!=pp) dfs(*i,nod);
    out[nod]=cl++;
}

bool isup(int a,int b)
{
    return (in[a]<=in[b] && out[a]>=out[b]);
}
void rame(int a,int b)
{
    FORDE(i,LG-1,0){
        if(!isup(p[a][i],b)) ad[a][i]++,a=p[a][i];
    }

    if(!isup(a,b)) ad[a][0]++,a=p[a][0];
   // cout<<a<<endl;
}

map<PI,int> mm;

void cal(int on,int ax,int dep)
{
     FORDE(i,LG-1,0)
     {
          if(!(dep&(1<<i))) continue;
          ad[on][i]+=ax;
          dep^=(1<<i);
     }
}

void proc(int on,int p=0)
{

    ALL(i,g[on]) if(*i!=p) proc(*i,on);

    FOR(i,0,LG)
    {
       mm[mp(on,p)]+=ad[on][i];
       int heg=(1<<i)-1;
       cal(p,ad[on][i],heg);
    }

}
int n;
void prnt()
{
   /* FORE(i,1,n){
    FOR(j,0,3) cout<<ad[i][j]<<' ';
    cout<<endl;
    }
    cout<<endl<<endl;*/
}
vector<PI> v;
int main()
{
    //freopen("a.txt","r",stdin);
    cin>>n;
    bs=(int)sqrt(n)+1;
    FOR(i,1,n){
        int a,b;cin>>a>>b;
        v.pb(mp(a,b));
        g[a].pb(b);g[b].pb(a);
    }
    in[0]=cl++;
    dfs(1);
    out[0]=cl++;

    int m;cin>>m;
    FOR(i,0,m){
        int a,b;cin>>a>>b;
        rame(a,b);prnt();
        rame(b,a);prnt();
    }

    proc(1);

    ALL(i,v){
        int res=mm[mp(i->first,i->second)]+mm[mp(i->second,i->first)];
        cout<<res<<' ';
    }
   // while(1){};

    return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<cmath>
#include<assert.h>

#define FO(i,s,e,p) for(int i=(s);i<(e);i+=p)
#define FOD(i,s,e,p) for(int i=(s);i>(e);i-=p)

#define FOR(i,s,e) FO(i,s,e,1)
#define FORE(i,s,e) FOR(i,s,e+1)
#define FORD(i,s,e) FOD(i,s,e,1)
#define FORDE(i,s,e) FORD(i,s,e-1)

#define ALL(i,s) for(__typeof(s.begin()) i=s.begin();i!=s.end();i++)

#define MEM(tab,fill) memset(tab,fill,sizeof(tab))

#include<iostream>
#include<set>
#include<vector>
#include<string>
#include<sstream>
#include<stack>
#include<queue>
#include<algorithm>
#include<utility>
#include<bitset>
#include<map>

using namespace std;
#define ll long long
#define inf ((1<<20)-1)
#define deb(a) cout<<#a<<" "<<a<<endl
#define pb push_back
#define mp make_pair

#define llu unsigned long long
#define PI pair<int,int>

#define SZ 100100
#define LG 20

int p[SZ][LG];
int ad[SZ][LG];

int in[SZ],out[SZ];

int cl=0;

vector<int> g[SZ];

void dfs(int nod,int pp=0)
{
    p[nod][0]=pp;
    FOR(i,1,LG) p[nod][i]=p[p[nod][i-1]][i-1];

    in[nod]=cl++;
    ALL(i,g[nod]) if(*i!=pp) dfs(*i,nod);
    out[nod]=cl++;
}

bool isup(int a,int b)
{
    return (in[a]<=in[b] && out[a]>=out[b]);
}
void rame(int a,int b)
{
    FORDE(i,LG-1,0){
        if(!isup(p[a][i],b)) ad[a][i]++,a=p[a][i];
    }

    if(!isup(a,b)) ad[a][0]++,a=p[a][0];
   // cout<<a<<endl;
}

map<PI,int> mm;

void cal(int on,int ax,int dep)
{
     FORDE(i,LG-1,0)
     {
          if(!(dep&(1<<i))) continue;
          ad[on][i]+=ax;
          on=p[on][i];
     }
}
int x=0;
void proc(int on,int p=0)
{
    x++;
    ALL(i,g[on]) if(*i!=p) proc(*i,on);

    FOR(i,0,LG)
    {
       mm[mp(on,p)]+=ad[on][i];
       int heg=(1<<i)-1;
       cal(p,ad[on][i],heg);
    }

}
int n;
void prnt()
{
   /* FORE(i,1,n){
    FOR(j,0,3) cout<<ad[i][j]<<' ';
    cout<<endl;
    }
    cout<<endl<<endl;*/
}
vector<PI> v;
int main()
{
   // freopen("a.txt","r",stdin);
    cin>>n;

    FOR(i,1,n){
        int a,b;cin>>a>>b;
        v.pb(mp(a,b));
        g[a].pb(b);g[b].pb(a);
    }
    in[0]=cl++;
    dfs(1);
    out[0]=cl++;

    int m;cin>>m;
    FOR(i,0,m){
        int a,b;cin>>a>>b;
        rame(a,b);prnt();
        rame(b,a);prnt();
    }

    proc(1);

    ALL(i,v){
        int res=mm[mp(i->first,i->second)]+mm[mp(i->second,i->first)];
        cout<<res<<' ';
    }
    assert(x==n);
   // while(1){};

    return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<cmath>
#include<assert.h>

#define FO(i,s,e,p) for(int i=(s);i<(e);i+=p)
#define FOD(i,s,e,p) for(int i=(s);i>(e);i-=p)

#define FOR(i,s,e) FO(i,s,e,1)
#define FORE(i,s,e) FOR(i,s,e+1)
#define FORD(i,s,e) FOD(i,s,e,1)
#define FORDE(i,s,e) FORD(i,s,e-1)

#define ALL(i,s) for(__typeof(s.begin()) i=s.begin();i!=s.end();i++)

#define MEM(tab,fill) memset(tab,fill,sizeof(tab))

#include<iostream>
#include<set>
#include<vector>
#include<string>
#include<sstream>
#include<stack>
#include<queue>
#include<algorithm>
#include<utility>
#include<bitset>
#include<map>

using namespace std;
#define ll long long
#define inf ((1<<20)-1)
#define deb(a) cout<<#a<<" "<<a<<endl
#define pb push_back
#define mp make_pair

#define llu unsigned long long
#define PI pair<int,int>

#define SZ 100100
#define LG 20

int p[SZ][LG];
int in[SZ],out[SZ];

int bs;

int cl=0;

vector<int> g[SZ];

void dfs(int nod,int pp=0)
{
    p[nod][0]=pp;
    FOR(i,1,LG) p[nod][i]=p[p[nod][i-1]][i-1];

    in[nod]=cl++;
    ALL(i,g[nod]) if(*i!=pp) dfs(*i,nod);
    out[nod]=cl++;
}

bool isup(int a,int b)
{
    return (in[a]<in[b] && out[a]>out[b]);
}
int rame(int a,int b)
{
    FORDE(i,LG-1,0){
        if(!isup(p[a][i],b)) a=p[a][i];
    }
    if(!isup(a,b)) a=p[a][0];
   // cout<<a<<endl;
    return a;
}

map<PI,int> mm;
int AD[SZ];

int proc(int on,int p=0)
{
    int res=AD[on];
    ALL(i,g[on]) if(*i!=p) {
        int gg=proc(*i,on);
        mm[mp(on,*i)]+=gg;
        res+=gg;
    }
    return res;
}

vector<PI> v;
int main()
{
   // freopen("C:\\a","r",stdin);
    int n;cin>>n;
    bs=sqrt(n)+1;
    FOR(i,1,n){
        int a,b;cin>>a>>b;
        v.pb(mp(a,b));
        g[a].pb(b);g[b].pb(a);
    }
    in[0]=cl++;
    dfs(1,1);
    out[0]=cl++;

    int m;cin>>m;
    FOR(i,0,m){
        int a,b;cin>>a>>b;
        int md=rame(a,b);
        AD[a]++;AD[b]++;
        AD[md]-=2;
    }

    proc(1);

    ALL(i,v){
        int res=mm[mp(i->first,i->second)]+mm[mp(i->second,i->first)];
        cout<<res<<' ';
    }

    return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<cmath>
#include<assert.h>

#define FO(i,s,e,p) for(int i=(s);i<(e);i+=p)
#define FOD(i,s,e,p) for(int i=(s);i>(e);i-=p)

#define FOR(i,s,e) FO(i,s,e,1)
#define FORE(i,s,e) FOR(i,s,e+1)
#define FORD(i,s,e) FOD(i,s,e,1)
#define FORDE(i,s,e) FORD(i,s,e-1)

#define ALL(i,s) for(__typeof(s.begin()) i=s.begin();i!=s.end();i++)

#define MEM(tab,fill) memset(tab,fill,sizeof(tab))

#include<iostream>
#include<set>
#include<vector>
#include<string>
#include<sstream>
#include<stack>
#include<queue>
#include<algorithm>
#include<utility>
#include<bitset>
#include<map>

using namespace std;
#define ll long long
#define inf ((1<<20)-1)
#define deb(a) cout<<#a<<" "<<a<<endl
#define pb push_back
#define mp make_pair

#define llu unsigned long long
#define PI pair<int,int>

#define SZ 100100
#define LG 20

int p[SZ][LG];
int ad[SZ][LG];

int in[SZ],out[SZ];

int bs;

int cl=0;

vector<int> g[SZ];

void dfs(int nod,int pp=0)
{
    p[nod][0]=pp;
    FOR(i,1,LG) p[nod][i]=p[p[nod][i-1]][i-1];

    in[nod]=cl++;
    ALL(i,g[nod]) if(*i!=pp) dfs(*i,nod);
    out[nod]=cl++;
}

bool isup(int a,int b)
{
    return (in[a]<=in[b] && out[a]>=out[b]);
}
void rame(int a,int b)
{
    FORDE(i,LG-1,0){
        if(!isup(p[a][i],b)) ad[a][i]++,a=p[a][i];
    }

    if(!isup(a,b)) ad[a][0]++,a=p[a][0];
   // cout<<a<<endl;
}

map<PI,int> mm;

void cal(int on,int ax,int dep)
{
     FORDE(i,LG-1,0)
     {
          if(!(dep&(1<<i))) continue;
          ad[on][i]+=ax;
          dep^=(1<<i);
     }
}
int x=0;
void proc(int on,int p=0)
{
    x++;
    ALL(i,g[on]) if(*i!=p) proc(*i,on);

    FOR(i,0,LG)
    {
       mm[mp(on,p)]+=ad[on][i];
       int heg=(1<<i)-1;
       cal(p,ad[on][i],heg);
    }

}
int n;
void prnt()
{
   /* FORE(i,1,n){
    FOR(j,0,3) cout<<ad[i][j]<<' ';
    cout<<endl;
    }
    cout<<endl<<endl;*/
}
vector<PI> v;
int main()
{
    //freopen("a.txt","r",stdin);
    cin>>n;
    bs=(int)sqrt(n)+1;
    FOR(i,1,n){
        int a,b;cin>>a>>b;
        v.pb(mp(a,b));
        g[a].pb(b);g[b].pb(a);
    }
    in[0]=cl++;
    dfs(1);
    out[0]=cl++;

    int m;cin>>m;
    FOR(i,0,m){
        int a,b;cin>>a>>b;
        rame(a,b);prnt();
        rame(b,a);prnt();
    }

    proc(1);

    ALL(i,v){
        int res=mm[mp(i->first,i->second)]+mm[mp(i->second,i->first)];
        cout<<res<<' ';
    }
    assert(x==n);
   // while(1){};

    return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#include<cmath>
#include<assert.h>

#define FO(i,s,e,p) for(int i=(s);i<(e);i+=p)
#define FOD(i,s,e,p) for(int i=(s);i>(e);i-=p)

#define FOR(i,s,e) FO(i,s,e,1)
#define FORE(i,s,e) FOR(i,s,e+1)
#define FORD(i,s,e) FOD(i,s,e,1)
#define FORDE(i,s,e) FORD(i,s,e-1)

#define ALL(i,s) for(__typeof(s.begin()) i=s.begin();i!=s.end();i++)

#define MEM(tab,fill) memset(tab,fill,sizeof(tab))

#include<iostream>
#include<set>
#include<vector>
#include<string>
#include<sstream>
#include<stack>
#include<queue>
#include<algorithm>
#include<utility>
#include<bitset>
#include<map>

using namespace std;
#define ll long long
#define inf ((1<<20)-1)
#define deb(a) cout<<#a<<" "<<a<<endl
#define pb push_back
#define mp make_pair

#define llu unsigned long long
#define PI pair<int,int>

#define SZ 100100
#define LG 20

int p[SZ][LG];
int in[SZ],out[SZ];

int bs;

int cl=0;

vector<int> g[SZ];

void dfs(int nod,int pp=0)
{
    p[nod][0]=pp;
    FOR(i,1,LG) p[nod][i]=p[p[nod][i-1]][i-1];

    in[nod]=cl++;
    ALL(i,g[nod]) if(*i!=pp) dfs(*i,nod);
    out[nod]=cl++;
}

bool isup(int a,int b)
{
    return (in[a]<in[b] && out[a]>out[b]);
}
int rame(int a,int b)
{
    FORDE(i,LG-1,0){
        if(!isup(p[a][i],b)) a=p[a][i];
    }
    if(!isup(a,b)) a=p[a][0];
   // cout<<a<<endl;
    return a;
}

map<PI,int> mm;
int AD[SZ];

int proc(int on,int p=0)
{
    int res=AD[on];
    ALL(i,g[on]) if(*i!=p) {
        int gg=proc(*i,on);
        mm[mp(on,*i)]+=gg;
        res+=gg;
    }
    return res;
}

vector<PI> v;
int main()
{
   // freopen("C:\\a","r",stdin);
    int n;cin>>n;
    bs=sqrt(n)+1;
    FOR(i,1,n){
        int a,b;cin>>a>>b;
        v.pb(mp(a,b));
        g[a].pb(b);g[b].pb(a);
    }
    in[0]=cl++;
    dfs(1,1);
    out[0]=cl++;

    int m;cin>>m;
    FOR(i,0,m){
        int a,b;cin>>a>>b;
        int md=rame(a,b);
        AD[a]++;AD[b]++;
        AD[md]-=2;
    }

    assert(!proc(1));

    ALL(i,v){
        int res=mm[mp(i->first,i->second)]+mm[mp(i->second,i->first)];
        cout<<res<<' ';
    }

    return 0;
}


/// بسم الله الرحمن الرحيم

/* *********************************************************************
   *                       Problem: --------------                     *
   *                   Runtime: 0.000 sec; Rank: 0000                  *
   *                     Algo Used: ----------------                   *
   *                    Solved By : Niloy - JU-CSE-21                  *
   ********************************************************************* */

#include <bits/stdc++.h>

#define S scanf
#define P printf

#define LL long long int
#define ULL unsigned long long int

#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SQR(n) (n*n)
#define eps 1e-9
#define PI 2.0*acos(0.0) //#define PI acos(-1.0)
#define MEM(a,val) memset(a,val,sizeof(a))

#define all(a) a.begin(),a.end()
#define X first
#define Y second

#define PCC cout<<"Case "<<cas++<<": ";
#define PC printf("Case %d:",cas++);
#define PCN printf("Case %d:\n",cas++);
#define NL printf("\n");

#define SET(a,i) memset(a,i,sizeof a)
#define open freopen("input.txt","r",stdin)
#define close freopen ("output.txt","w",stdout)
#define Case(a) printf("Case %d:",a)
#define caseh(a) printf("Case #%d: ",a)
#define S1(a) scanf("%d",&a)
#define S2(a,b) scanf("%d%d",&a,&b)
#define S3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define SL1(a) scanf("%lld",&a)
#define SL2(a,b) scanf("%lld%lld",&a,&b)
#define SL3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define CHR getchar()
#define PB(x) push_back(x)
#define PP pop_back()
#define PF(x) push_front(x)
#define PPF(x) pop_front()
#define PS(x) push(x)
#define SZ() size()
#define MOD 1000000007
#define INF (1<<28)
#define UB(a,b,x) upper_bound(a,a+b,x)-a
#define LB(a,b,x) lower_bound(a,a+b,x)-a
#define mxe(a,n) (*max_element(a,a+n))
#define mne(a,n) (*min_element(a,a+n))
#define SUM(a,n) (accumulate(a,a+n,0))
#define onbits  __builtin_popcount
#define VI vector<int>
#define DBG(n) P("Done %d\n",n);
#define INI in<int>()
#define INL in<LL>()

using namespace std;

template <typename T> T BigMod (T b,T p,T m){if (p == 0) return 1;if (p%2 == 0){T s = BigMod(b,p/2,m);return ((s%m)*(s%m))%m;}return ((b%m)*(BigMod(b,p-1,m)%m))%m;}
template <typename T> T ModInv (T b,T m){return BigMod(b,m-2,m);}
template <typename T> void ia (T a[],int n){for (int i=0; i<n; i++) cin >> a[i];}
template <typename T> void pa (T a[],int n){for (int i=0; i<n-1; i++) cout << a[i] << " ";cout << a[n-1] << endl;}
template <typename T> LL isLeft(T a,T b,T c) { return (a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y); }
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Bigmod(T b,T p,T m){ if(p==0) return 1; else if (!(p&1)) return SQR(Bigmod(b,p/2,m)) % m;else return ((b % m) * Bigmod(b,p-1,m)) % m;}
template<typename T>inline T Dis(T x1,T y1,T x2, T y2){return sqrt( SQR(x1-x2) + SQR(y1-y2) );}
template<typename T>inline T Angle(T x1,T y1,T x2, T y2){ return atan( double(y1-y2) / double(x1-x2));}
template<typename T>inline T DIFF(T a,T b) { T d = a-b;if(d<0)return -d;else return d;}
template<typename T>inline T ABS(T a) {if(a<0)return -a;else return a;}
template<typename T>inline T gcd(T a,T b){if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template<typename T>inline T lcm(T a,T b) {if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}
template<typename T>inline T euclide(T a,T b,T &x,T &y) {if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}

int Set(int N,int pos){ return N=N | (1<<pos);}
int Reset(int N,int pos){return N= N & ~(1<<pos);}
bool Check(int N,int pos){return (bool)(N & (1<<pos));}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
int toLlint(string s) { long long int sm; stringstream ss(s); ss>>sm; return sm;}
int cdigittoint(char ch){return ch-'0';}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}

/* ------------------------------------------------------------------------------------------------------- */
//         0123456789
#define MX 100007

VI adj[MX];
int L[MX];
int T[MX];
int a[MX][2];
int e[MX];
int DP[MX][17];
int m;
int BIT[(MX<<1)+7];
int mxVal;

void Update(int idx,int val){ while (idx<=mxVal) BIT[idx] += val,idx += idx&-idx; }
int Query(int idx){ int ans = 0; while (idx) ans += BIT[idx],idx -= idx&-idx; return ans; }

void dfs(int u,int l,int p,int en)
{
    T[u] = p;
    L[u] = l;
    e[en] = u;

    a[u][0] = ++m;

    for (int i=0;i<adj[u].size();i+=2)
    {
        int v = adj[u][i];
        int y = adj[u][i+1];

        if (v != p)     dfs(v,l+1,u,y);
    }

    a[u][1] = ++m;
}

void Sparse(int n)
{
    SET(DP,-1);

    for (int i=1;i<=n;i++)      DP[i][0] = T[i];

    for (int j=1;(1<<j)<n;j++)
    {
        for (int i=1;i<=n;i++)
        {
            if (DP[i][j-1] != -1)
            {
                DP[i][j] = DP[DP[i][j-1]][j-1];
            }
        }
    }
}

int lca(int p,int q)
{
    if (L[p] < L[q])        swap(p,q);

    int b;

    for (b=1;(1<<b)<= L[p];b++);b--;

    for (int i=b;i>=0;i--)
        if (L[p] - (1<<i) >= L[q])
            p = DP[p][i];

    if (p == q)     return p;

    for (int i=b;i>=0;i--)
    {
        if (DP[p][i] != -1 && DP[p][i] != DP[q][i])
        {
            p = DP[p][i];
            q = DP[q][i];
        }
    }

    return T[p];
}

int main()
{
    int n;

    S1(n);

    for (int i=1;i<n;i++)
    {
        int u = INI,v = INI;

        adj[u].PB(v);
        adj[u].PB(i);

        adj[v].PB(u);
        adj[v].PB(i);
    }

    dfs(1,0,-1,0);
    Sparse(n);
    mxVal = m;

    int q = INI;

    while (q--)
    {
        int u = INI, v = INI;

        int LCA = lca(u,v);

        Update(a[LCA][0]+1,1);
        Update(a[u][0]+1,-1);

        Update(a[LCA][0]+1,1);
        Update(a[v][0]+1,-1);
    }

    for (int i=1;i<n;i++)
    {
        P("%d%c",Query(a[e[i]][0])-Query(a[e[i]][1]),i==n-1?'\n':' ');
    }
return 0;
}


/// بسم الله الرحمن الرحيم

/* *********************************************************************
   *                       Problem: --------------                     *
   *                   Runtime: 0.000 sec; Rank: 0000                  *
   *                     Algo Used: ----------------                   *
   *                    Solved By : Niloy - JU-CSE-21                  *
   ********************************************************************* */

#include <bits/stdc++.h>

#define S scanf
#define P printf

#define LL long long int
#define ULL unsigned long long int

#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
#define _Max(a,b,c) Max(a,Max(b,c))
#define _Min(a,b,c) Min(a,Min(b,c))
#define SQR(n) (n*n)
#define eps 1e-9
#define PI 2.0*acos(0.0) //#define PI acos(-1.0)
#define MEM(a,val) memset(a,val,sizeof(a))

#define all(a) a.begin(),a.end()
#define X first
#define Y second

#define PCC cout<<"Case "<<cas++<<": ";
#define PC printf("Case %d:",cas++);
#define PCN printf("Case %d:\n",cas++);
#define NL printf("\n");

#define SET(a,i) memset(a,i,sizeof a)
#define open freopen("input.txt","r",stdin)
#define close freopen ("output.txt","w",stdout)
#define Case(a) printf("Case %d:",a)
#define caseh(a) printf("Case #%d: ",a)
#define S1(a) scanf("%d",&a)
#define S2(a,b) scanf("%d%d",&a,&b)
#define S3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define SL1(a) scanf("%lld",&a)
#define SL2(a,b) scanf("%lld%lld",&a,&b)
#define SL3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define CHR getchar()
#define PB(x) push_back(x)
#define PP pop_back()
#define PF(x) push_front(x)
#define PPF(x) pop_front()
#define PS(x) push(x)
#define SZ() size()
#define MOD 1000000007
#define INF (1<<28)
#define UB(a,b,x) upper_bound(a,a+b,x)-a
#define LB(a,b,x) lower_bound(a,a+b,x)-a
#define mxe(a,n) (*max_element(a,a+n))
#define mne(a,n) (*min_element(a,a+n))
#define SUM(a,n) (accumulate(a,a+n,0))
#define onbits  __builtin_popcount
#define VI vector<int>
#define DBG(n) P("Done %d\n",n);
#define INI in<int>()
#define INL in<LL>()

using namespace std;

template <typename T> T BigMod (T b,T p,T m){if (p == 0) return 1;if (p%2 == 0){T s = BigMod(b,p/2,m);return ((s%m)*(s%m))%m;}return ((b%m)*(BigMod(b,p-1,m)%m))%m;}
template <typename T> T ModInv (T b,T m){return BigMod(b,m-2,m);}
template <typename T> void ia (T a[],int n){for (int i=0; i<n; i++) cin >> a[i];}
template <typename T> void pa (T a[],int n){for (int i=0; i<n-1; i++) cout << a[i] << " ";cout << a[n-1] << endl;}
template <typename T> LL isLeft(T a,T b,T c) { return (a.x-b.x)*(b.y-c.y)-(b.x-c.x)*(a.y-b.y); }
template <typename T> T in(){char ch;T n = 0;bool ng = false;while (1){ch = getchar();if (ch == '-'){ng = true;ch = getchar();break;}if (ch>='0' && ch<='9')     break;}while (1){n = n*10 + (ch - '0');ch = getchar();if (ch<'0' || ch>'9')   break;}return (ng?-n:n);}
template<typename T>inline T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}
template<typename T>inline T Bigmod(T b,T p,T m){ if(p==0) return 1; else if (!(p&1)) return SQR(Bigmod(b,p/2,m)) % m;else return ((b % m) * Bigmod(b,p-1,m)) % m;}
template<typename T>inline T Dis(T x1,T y1,T x2, T y2){return sqrt( SQR(x1-x2) + SQR(y1-y2) );}
template<typename T>inline T Angle(T x1,T y1,T x2, T y2){ return atan( double(y1-y2) / double(x1-x2));}
template<typename T>inline T DIFF(T a,T b) { T d = a-b;if(d<0)return -d;else return d;}
template<typename T>inline T ABS(T a) {if(a<0)return -a;else return a;}
template<typename T>inline T gcd(T a,T b){if(a<0)return gcd(-a,b);if(b<0)return gcd(a,-b);return (b==0)?a:gcd(b,a%b);}
template<typename T>inline T lcm(T a,T b) {if(a<0)return lcm(-a,b);if(b<0)return lcm(a,-b);return a*(b/gcd(a,b));}
template<typename T>inline T euclide(T a,T b,T &x,T &y) {if(a<0){T d=euclide(-a,b,x,y);x=-x;return d;}   if(b<0){T d=euclide(a,-b,x,y);y=-y;return d;}   if(b==0){x=1;y=0;return a;}else{T d=euclide(b,a%b,x,y);T t=x;x=y;y=t-(a/b)*y;return d;}}

int Set(int N,int pos){ return N=N | (1<<pos);}
int Reset(int N,int pos){return N= N & ~(1<<pos);}
bool Check(int N,int pos){return (bool)(N & (1<<pos));}
int toInt(string s)  { int sm; stringstream ss(s); ss>>sm; return sm; }
int toLlint(string s) { long long int sm; stringstream ss(s); ss>>sm; return sm;}
int cdigittoint(char ch){return ch-'0';}
bool isVowel(char ch){ ch=toupper(ch); if(ch=='A'||ch=='U'||ch=='I'||ch=='O'||ch=='E') return true; return false;}
bool isConst(char ch){if (isalpha(ch) && !isVowel(ch)) return true; return false;}

/* ------------------------------------------------------------------------------------------------------- */
//         0123456789
#define MX 100007

VI adj[MX];
int L[MX];
int T[MX];
int a[MX][2];
int e[MX];
int DP[MX][17];
int m;
int BIT[(MX<<1)+7];
int mxVal;

void Update(int idx,int val){ while (idx<=mxVal) BIT[idx] += val,idx += idx&-idx; }
int Query(int idx){ int ans = 0; while (idx) ans += BIT[idx],idx -= idx&-idx; return ans; }

void dfs(int u,int l,int p,int en)
{
    T[u] = p;
    L[u] = l;
    e[en] = u;

    a[u][0] = ++m;

    for (int i=0;i<adj[u].size();i+=2)
    {
        int v = adj[u][i];
        int y = adj[u][i+1];

        if (v != p)     dfs(v,l+1,u,y);
    }

    a[u][1] = ++m;
}

void Sparse(int n)
{
    for (int i=1;i<=n;i++)      DP[i][0] = T[i];

    for (int j=1;(1<<j)<n;j++)
    {
        for (int i=1;i<=n;i++)
        {
            if (DP[i][j-1] != -1)
            {
                DP[i][j] = DP[DP[i][j-1]][j-1];
            }

            else DP[i][j] = -1;
        }
    }
}

int lca(int p,int q)
{
    if (L[p] < L[q])        swap(p,q);

    int b;

    for (b=1;(1<<b)<= L[p];b++);b--;

    for (int i=b;i>=0;i--)
        if (L[p] - (1<<i) >= L[q])
            p = DP[p][i];

    if (p == q)     return p;

    for (int i=b;i>=0;i--)
    {
        if (DP[p][i] != -1 && DP[p][i] != DP[q][i])
        {
            p = DP[p][i];
            q = DP[q][i];
        }
    }

    return T[p];
}

int main()
{
    int n;

    S1(n);

    for (int i=1;i<n;i++)
    {
        int u = INI,v = INI;

        adj[u].PB(v);
        adj[u].PB(i);

        adj[v].PB(u);
        adj[v].PB(i);
    }

    dfs(1,0,-1,0);
    Sparse(n);
    mxVal = m;

    int q = INI;

    while (q--)
    {
        int u = INI, v = INI;

        int LCA = lca(u,v);

        Update(a[LCA][0]+1,1);
        Update(a[u][0]+1,-1);

        Update(a[LCA][0]+1,1);
        Update(a[v][0]+1,-1);
    }

    for (int i=1;i<n;i++)
    {
        P("%d%c",Query(a[e[i]][0])-Query(a[e[i]][1]),i==n-1?'\n':' ');
    }
return 0;
}


#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>

using namespace std;

int n, k;
vector<int>v[100100];
vector<pair<int, int> >edge;
int parent[100100], depth[100100], d[100100][22], e[100100], node[100100];

void dfs(int p, int t, int d) {
  parent[t]=p;
  depth[t]=d;
  for (int i=0; i<(int)v[t].size(); i++) {
    if (v[t][i]==p) continue;
    dfs(t, v[t][i], d+1);
  }
}

int lca(int a, int b) {
  for (int i=20; i>=0; i--) if (depth[b] <= depth[a]-(1<<i)) a=d[a][i];
  for (int i=20; i>=0; i--) if (depth[a] <= depth[b]-(1<<i)) b=d[b][i];

  if (a==b) return a;

  for (int i=20; i>=0; i--) {
    if (d[a][i]!=d[b][i]) {
      a=d[a][i];
      b=d[b][i];
    }
  }
  return parent[a];
}

int dfss(int p, int t) {
  int s=0;
  for (int i=0; i<(int)v[t].size(); i++) {
    if (v[t][i]==p) continue;
    s+=dfss(t, v[t][i]);
  }
  return e[t]=e[t]+s;
}

int main() {

  scanf("%d", &n);

  for (int i=0; i<n-1; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    x--; y--;
    v[x].push_back(y);
    v[y].push_back(x);
    edge.push_back(make_pair(x, y));
  }

  dfs(-1, 0, 0);

  for (int i=0; i<n; i++) d[i][0]=parent[i];
  d[0][0]=0;

  for (int i=1; i<20; i++) for (int j=0; j<n; j++) d[j][i]=d[d[j][i-1]][i-1];

  scanf("%d", &k);
  for (int i=0; i<k; i++) {
    int x, y, z;
    scanf("%d%d", &x, &y);
    x--; y--;
    z=lca(x, y);
    e[x]++; e[y]++; e[z]-=2;
  }

  dfss(-1, 0);

  for (int i=0; i<n; i++) {
    int x;
    if (depth[edge[i].first]<depth[edge[i].second]) x=edge[i].second;
    else x=edge[i].first;
    printf("%d%c", e[x], i-n+1?' ':'\n');
  }

  return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int n, k;
vector<int>v[100100];
vector<pair<int, int> >edge;
int parent[100100], depth[100100], d[100100][22], e[100100];

void dfs(int p, int t, int d) {
  parent[t]=p;
  depth[t]=d;
  for (int i=0; i<(int)v[t].size(); i++) {
    if (v[t][i]==p) continue;
    dfs(t, v[t][i], d+1);
  }
}

int lca(int a, int b) {
  for (int i=20; i>=0; i--) if (depth[b] <= depth[a]-(1<<i)) a=d[a][i];
  for (int i=20; i>=0; i--) if (depth[a] <= depth[b]-(1<<i)) b=d[b][i];

  if (a==b) return a;

  for (int i=20; i>=0; i--) {
    if (d[a][i]!=d[b][i]) {
      a=d[a][i];
      b=d[b][i];
    }
  }
  return parent[a];
}

int dfss(int p, int t) {
  int s=0;
  for (int i=0; i<(int)v[t].size(); i++) {
    if (v[t][i]==p) continue;
    s+=dfss(t, v[t][i]);
  }
  return e[t]=e[t]+s;
}

int main() {

  scanf("%d", &n);

  for (int i=0; i<n-1; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    x--; y--;
    v[x].push_back(y);
    v[y].push_back(x);
    edge.push_back(make_pair(x, y));
  }

  dfs(-1, 0, 0);

  for (int i=0; i<n; i++) d[i][0]=parent[i];
  d[0][0]=0;

  for (int i=1; i<=20; i++) for (int j=0; j<n; j++) d[j][i]=d[d[j][i-1]][i-1];

  scanf("%d", &k);
  for (int i=0; i<k; i++) {
    int x, y, z;
    scanf("%d%d", &x, &y);
    x--; y--;
    z=lca(x, y);
    e[x]++; e[y]++; e[z]-=2;
  }

  dfss(-1, 0);

  for (int i=0; i<n-1; i++) {
    int x;
    if (depth[edge[i].first]<depth[edge[i].second]) x=edge[i].second;
    else x=edge[i].first;
    printf("%d%c", e[x], n-2-i?' ':'\n');
  }

  return 0;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int n, k;
vector<int>v[100100];
vector<pair<int, int> >edge;
int parent[100100], depth[100100], d[100100][22], e[100100], node[100100];

void dfs(int p, int t, int d) {
  parent[t]=p;
  depth[t]=d;
  for (int i=0; i<(int)v[t].size(); i++) {
    if (v[t][i]==p) continue;
    dfs(t, v[t][i], d+1);
  }
}

int lca(int a, int b) {
  for (int i=20; i>=0; i--) if (depth[b] <= depth[a]-(1<<i)) a=d[a][i];
  for (int i=20; i>=0; i--) if (depth[a] <= depth[b]-(1<<i)) b=d[b][i];

  if (a==b) return a;

  for (int i=20; i>=0; i--) {
    if (d[a][i]!=d[b][i]) {
      a=d[a][i];
      b=d[b][i];
    }
  }
  return parent[a];
}

int dfss(int p, int t) {
  int s=0;
  for (int i=0; i<(int)v[t].size(); i++) {
    if (v[t][i]==p) continue;
    s+=dfss(t, v[t][i]);
  }
  return e[t]=e[t]+s;
}

int main() {

  scanf("%d", &n);

  for (int i=0; i<n-1; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    x--; y--;
    v[x].push_back(y);
    v[y].push_back(x);
    edge.push_back(make_pair(x, y));
  }

  dfs(-1, 0, 0);

  for (int i=0; i<n; i++) d[i][0]=parent[i];
  d[0][0]=0;

  for (int i=1; i<=20; i++) for (int j=0; j<n; j++) d[j][i]=d[d[j][i-1]][i-1];

  scanf("%d", &k);
  for (int i=0; i<k; i++) {
    int x, y, z;
    scanf("%d%d", &x, &y);
    x--; y--;
    z=lca(x, y);
    e[x]++; e[y]++; e[z]-=2;
  }

  dfss(-1, 0);

  for (int i=0; i<n; i++) {
    int x;
    if (depth[edge[i].first]<depth[edge[i].second]) x=edge[i].second;
    else x=edge[i].first;
    printf("%d%c", e[x], i-n+1?' ':'\n');
  }

  return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <vector>

#define mp make_pair
#define pb push_back
#define fs first
#define sc second

typedef long long int64;
typedef long double ext;

using namespace std;

const int maxv = 200000;
const int maxe = 400000;
const int maxt = 400000;

struct lst
{
    int first[maxv], last[maxv];
    int next[maxe], to[maxe];
    int cnt;
    void clear(int n)
    {
        cnt = 0;
        for (int i = 0; i < n; i++)
            first[i] = last[i] = -1;
    }
    void add(int v, int u)
    {
        if (first[v] == -1)
            first[v] = cnt;
        else
            next[last[v]] = cnt;
        next[cnt] = -1;
        last[v] = cnt;
        to[cnt] = u;
        cnt++;
    }
};

struct tree
{
    int x, y;
    int cnt;
    tree *l, *r;
};

int n, k;
int ans[maxe];
tree forest[maxt];
int tcnt;
tree *rt;
lst query, edge;

tree *mktree(int x)
{
    tree *a = &forest[tcnt++];
    a->x = x;
    a->y = (rand() << 16) + rand();
    a->l = a->r = NULL;
    a->cnt = 1;
    return a;
}

int cnt(tree *rt)
{
    if (!rt)
        return 0;
    else
        return rt->cnt;
}

void update(tree *rt)
{
    if (!rt)
        return;
    rt->cnt = cnt(rt->l) + cnt(rt->r) + 1;
}

void split(tree *rt, tree *&l, tree *&r, int x)
{
    if (!rt)
        l = r = NULL;
    else if (rt->x < x)
    {
        split(rt->r, rt->r, r, x);
        l = rt;
    }
    else
    {
        split(rt->l, l, rt->l, x);
        r = rt;
    }
    update(l);
    update(r);
}

void merge(tree *&rt, tree *l, tree *r)
{
    if ((!l) || (!r))
        rt = l ? l : r;
    else if (l->y < r->y)
    {
        merge(l->r, l->r, r);
        rt = l;
    }
    else
    {
        merge(r->l, l, r->l);
        rt = r;
    }
    update(rt);
}

tree *find(tree *rt, int x)
{
    if (!rt)
        return NULL;
    else if (rt->x == x)
        return rt;
    else if (rt->x > x)
        return find(rt->l, x);
    else
        return find(rt->r, x);
}

void add(tree *&rt, tree *a)
{
    if (!rt)
        rt = a;
    else if (a->y < rt->y)
    {
        tree *l, *r;
        split(rt, l, r, a->x);
        rt = a;
        rt->l = l;
        rt->r = r;
    }
    else if (rt->x > a->x)
        add(rt->l, a);
    else
        add(rt->r, a);
    update(rt);

}

void erase(tree *&rt, int x)
{
    if (!rt)
        return;
    else if (rt->x == x)
        merge(rt, rt->l, rt->r);
    else if (rt->x > x)
        erase(rt->l, x);
    else
        erase(rt->r, x);
    update(rt);
}

void push(tree *&rt, tree *w)
{
    tree *a = find(rt, w->x);
    if (a)
        erase(rt, w->x);
    else
        add(rt, w);
}

void drop(tree *rt, tree *&to)
{
    if (!rt)
        return;
    drop(rt->l, to);
    drop(rt->r, to);
    rt->l = rt->r = NULL;
    rt->cnt = 1;
    push(to, rt);
}

void mergetree(tree *&rt, tree *a)
{
    if (cnt(a) > cnt(rt))
        swap(rt, a);
    drop(a, rt);
}

void dfs(int v, int p, tree *&rt)
{
	//cerr << v << endl;
    for (int i = edge.first[v]; i != -1; i = edge.next[i])
    {
        int u = edge.to[i];
        if (u == p)
            continue;
        tree *a = NULL;
        dfs(u, v, a);
        //cerr << v << endl;
        //cerr << "MERGE" << endl;
        ans[i / 2] = cnt(a);
        mergetree(rt, a);
        //cerr << "MERGE" << endl;
    }
    for (int i = query.first[v]; i != -1; i = query.next[i])
    {
        int x = query.to[i];
    //    cerr << "PUSH";
        push(rt, mktree(x));
  //      cerr << "PUSH" << endl;
    }
//    cerr << "SIZE " << v << " " << cnt(rt) << endl;
}

int main()
{
    //freopen("input.txt", "rt", stdin);
    //freopen("output.txt", "wt", stdout);
    scanf("%d", &n);
    query.clear(n);
    edge.clear(n);
    tcnt = 0;
    for (int i = 1; i < n; i++)
    {
        int v, u;
        scanf("%d %d", &v, &u);
        v--; u--;
        edge.add(v, u);
        edge.add(u, v);
    }
    scanf("%d", &k);
    for (int i = 0; i < k; i++)
    {
        int v, u;
        scanf("%d %d", &v, &u);
        v--; u--;
        query.add(v, i);
        query.add(u, i);
    }
    rt = NULL;
    //cerr << "GOOD " << endl;
    dfs(0, -1, rt);
    //cerr << "GOOD " << endl;
    for (int i = 0; i < n - 1; i++)
        printf("%d ", ans[i]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <vector>

#define mp make_pair
#define pb push_back
#define fs first
#define sc second

typedef long long int64;
typedef long double ext;

using namespace std;

const int maxv = 300000;
const int maxe = 500000;
const int maxt = 1000000;

struct lst
{
    int first[maxv], last[maxv];
    int next[maxe], to[maxe];
    int cnt;
    void clear(int n)
    {
        cnt = 0;
        for (int i = 0; i < n; i++)
            first[i] = last[i] = -1;
    }
    void add(int v, int u)
    {
        if (first[v] == -1)
            first[v] = cnt;
        else
            next[last[v]] = cnt;
        next[cnt] = -1;
        last[v] = cnt;
        to[cnt] = u;
        cnt++;
    }
};

struct tree
{
    int x, y;
    int cnt;
    tree *l, *r;
};

int n, k;
lst query, edge;
int ans[maxe];
tree forest[maxt];
int tcnt;
tree *rt;

tree *mktree(int x)
{
    tree *a = &forest[tcnt++];
    a->x = x;
    a->y = (rand() << 16) + rand();
    a->l = a->r = NULL;
    a->cnt = 1;
    return a;
}

int cnt(tree *rt)
{
    if (!rt)
        return 0;
    else
        return rt->cnt;
}

void update(tree *rt)
{
    if (!rt)
        return;
    rt->cnt = cnt(rt->l) + cnt(rt->r) + 1;
}

void split(tree *rt, tree *&l, tree *&r, int x)
{
    if (!rt)
        l = r = NULL;
    else if (rt->x < x)
    {
        split(rt->r, rt->r, r, x);
        l = rt;
    }
    else
    {
        split(rt->l, l, rt->l, x);
        r = rt;
    }
    update(l);
    update(r);
}

void merge(tree *&rt, tree *l, tree *r)
{
    if ((!l) || (!r))
        rt = l ? l : r;
    else if (l->y < r->y)
    {
        merge(l->r, l->r, r);
        rt = l;
    }
    else
    {
        merge(r->l, l, r->l);
        rt = r;
    }
    update(rt);
}

tree *find(tree *rt, int x)
{
    if (!rt)
        return NULL;
    else if (rt->x == x)
        return rt;
    else if (rt->x > x)
        return find(rt->l, x);
    else
        return find(rt->r, x);
}

void add(tree *&rt, tree *a)
{
    if (!rt)
        rt = a;
    else if (a->y < rt->y)
    {
        tree *l, *r;
        split(rt, l, r, a->x);
        rt = a;
        rt->l = l;
        rt->r = r;
    }
    else if (rt->x > a->x)
        add(rt->l, a);
    else
        add(rt->r, a);
    update(rt);

}

void erase(tree *&rt, int x)
{
    if (!rt)
        return;
    else if (rt->x == x)
        merge(rt, rt->l, rt->r);
    else if (rt->x > x)
        erase(rt->l, x);
    else
        erase(rt->r, x);
    update(rt);
}

void push(tree *&rt, tree *w)
{
    tree *a = find(rt, w->x);
    if (a)
        erase(rt, w->x);
    else
        add(rt, w);
}

void drop(tree *rt, tree *&to)
{
    if (!rt)
        return;
    drop(rt->l, to);
    drop(rt->r, to);
    rt->l = rt->r = NULL;
    rt->cnt = 1;
    push(to, rt);
}

void mergetree(tree *&rt, tree *a)
{
    if (cnt(a) > cnt(rt))
        swap(rt, a);
    drop(a, rt);
}

void dfs(int v, int p, tree *&rt)
{
    for (int i = edge.first[v]; i != -1; i = edge.next[i])
    {
        int u = edge.to[i];
        if (u == p)
            continue;
        tree *a = NULL;
        dfs(u, v, a);
        mergetree(rt, a);
        ans[i / 2] = cnt(a);
    }
    for (int i = query.first[v]; i != -1; i = query.next[i])
    {
        int x = query.to[i];
        push(rt, mktree(x));
    }
}

int main()
{
    //freopen("input.txt", "rt", stdin);
    //freopen("output.txt", "wt", stdout);
    scanf("%d", &n);
    query.clear(n);
    edge.clear(n);
    for (int i = 1; i < n; i++)
    {
        int v, u;
        scanf("%d %d", &v, &u);
        v--; u--;
        edge.add(v, u);
        edge.add(u, v);
    }
    scanf("%d", &k);
    for (int i = 0; i < k; i++)
    {
        int v, u;
        scanf("%d %d", &v, &u);
        v--; u--;
        query.add(v, i);
        query.add(u, i);
    }
    rt = NULL;
    dfs(0, -1, rt);
    for (int i = 0; i < n - 1; i++)
        printf("%d ", ans[i]);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cstdlib>
#include <vector>

#define mp make_pair
#define pb push_back
#define fs first
#define sc second

typedef long long int64;
typedef long double ext;

using namespace std;

const int maxv = 200000;
const int maxe = 400000;
const int maxt = 400000;

struct lst
{
    int first[maxv], last[maxv];
    int next[maxe], to[maxe];
    int cnt;
    void clear(int n)
    {
        cnt = 0;
        for (int i = 0; i < n; i++)
            first[i] = last[i] = -1;
    }
    void add(int v, int u)
    {
        if (first[v] == -1)
            first[v] = cnt;
        else
            next[last[v]] = cnt;
        next[cnt] = -1;
        last[v] = cnt;
        to[cnt] = u;
        cnt++;
    }
};

struct tree
{
    int x, y;
    int cnt;
    tree *l, *r;
};

int n, k;
int ans[maxe];
tree forest[maxt];
int tcnt;
tree *rt;
lst query, edge;

tree *mktree(int x)
{
    tree *a = &forest[tcnt++];
    a->x = x;
    a->y = (rand() << 16) + rand();
    a->l = a->r = NULL;
    a->cnt = 1;
    return a;
}

int cnt(tree *rt)
{
    if (!rt)
        return 0;
    else
        return rt->cnt;
}

void update(tree *rt)
{
    if (!rt)
        return;
    rt->cnt = cnt(rt->l) + cnt(rt->r) + 1;
}

void split(tree *rt, tree *&l, tree *&r, int x)
{
    if (!rt)
        l = r = NULL;
    else if (rt->x < x)
    {
        split(rt->r, rt->r, r, x);
        l = rt;
    }
    else
    {
        split(rt->l, l, rt->l, x);
        r = rt;
    }
    update(l);
    update(r);
}

void merge(tree *&rt, tree *l, tree *r)
{
    if ((!l) || (!r))
        rt = l ? l : r;
    else if (l->y < r->y)
    {
        merge(l->r, l->r, r);
        rt = l;
    }
    else
    {
        merge(r->l, l, r->l);
        rt = r;
    }
    update(rt);
}

tree *find(tree *rt, int x)
{
    if (!rt)
        return NULL;
    else if (rt->x == x)
        return rt;
    else if (rt->x > x)
        return find(rt->l, x);
    else
        return find(rt->r, x);
}

void add(tree *&rt, tree *a)
{
    if (!rt)
        rt = a;
    else if (a->y < rt->y)
    {
        tree *l, *r;
        split(rt, l, r, a->x);
        rt = a;
        rt->l = l;
        rt->r = r;
    }
    else if (rt->x > a->x)
        add(rt->l, a);
    else
        add(rt->r, a);
    update(rt);

}

void erase(tree *&rt, int x)
{
    if (!rt)
        return;
    else if (rt->x == x)
        merge(rt, rt->l, rt->r);
    else if (rt->x > x)
        erase(rt->l, x);
    else
        erase(rt->r, x);
    update(rt);
}

void push(tree *&rt, tree *w)
{
    tree *a = find(rt, w->x);
    if (a)
        erase(rt, w->x);
    else
        add(rt, w);
}

void drop(tree *rt, tree *&to)
{
    if (!rt)
        return;
    drop(rt->l, to);
    drop(rt->r, to);
    rt->l = rt->r = NULL;
    rt->cnt = 1;
    push(to, rt);
}

void mergetree(tree *&rt, tree *a)
{
    if (cnt(a) > cnt(rt))
        swap(rt, a);
    drop(a, rt);
}

void dfs(int v, int p, tree *&rt)
{
	//cerr << v << endl;
    for (int i = edge.first[v]; i != -1; i = edge.next[i])
    {
        int u = edge.to[i];
        if (u == p)
            continue;
        tree *a = NULL;
        dfs(u, v, a);
        //cerr << v << endl;
        //cerr << "MERGE" << endl;
        ans[i / 2] = cnt(a);
        mergetree(rt, a);
        //cerr << "MERGE" << endl;
    }
    for (int i = query.first[v]; i != -1; i = query.next[i])
    {
        int x = query.to[i];
    //    cerr << "PUSH";
        push(rt, mktree(x));
  //      cerr << "PUSH" << endl;
    }
//    cerr << "SIZE " << v << " " << cnt(rt) << endl;
}

int main()
{
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
    scanf("%d", &n);
    query.clear(n);
    edge.clear(n);
    tcnt = 0;
    for (int i = 1; i < n; i++)
    {
        int v, u;
        scanf("%d %d", &v, &u);
        v--; u--;
        edge.add(v, u);
        edge.add(u, v);
    }
    scanf("%d", &k);
    for (int i = 0; i < k; i++)
    {
        int v, u;
        scanf("%d %d", &v, &u);
        v--; u--;
        query.add(v, i);
        query.add(u, i);
    }
    rt = NULL;
    //cerr << "GOOD " << endl;
    dfs(0, -1, rt);
    //cerr << "GOOD " << endl;
    for (int i = 0; i < n - 1; i++)
        printf("%d ", ans[i]);
    return 0;
}


#include<stdio.h>
#include<algorithm>
#include<vector>
#include<string.h>
#include <map>

using namespace std;

#define MAX 100100//Maxima entrada, nao se preocupar com o size de Tree[]

struct no {
	int ini, fim;
	int id;
};

// G[]-> grafo que guarda a arvore inicial
// C[]-> custo de cada aresta
vector <int> G[MAX], C[MAX];
// E[]->Despodiçao dos nos depois da dfs
// L[]->Nivel de cada no arvore inicial
// H[]-> E[H[i]] = i, uma indice do elemento i no vetor E[]
int E[2*MAX], L[2*MAX], H[MAX], Pai[MAX];
int topoE;
int n, q;

no Tree[20*MAX];

void dfs(int p, int veio, int nivel) {
	Pai[p] = veio;
	E[topoE] = p;
	L[topoE++] = nivel;
	bool b = false;
	for (int i = 0; i < G[p].size(); i++)
		if (G[p][i] != veio) {
			dfs(G[p][i], p, nivel+1);
			E[topoE] = p;
			L[topoE++] = nivel;
		}
}

void buildTree(int p, int ini, int fim) {
	Tree[p].ini = ini;
	Tree[p].fim = fim;
	if (ini == fim)
		Tree[p].id = ini;
	else {
		int mid = (ini+fim) >> 1;
		buildTree(2*p, ini, mid);
		buildTree(2*p+1, mid+1, fim);

		if (L[Tree[2*p].id] < L[Tree[2*p+1].id])
			Tree[p].id = Tree[2*p].id;
		else
			Tree[p].id = Tree[2*p+1].id;
	}
}

// Retorna o indice i de E[], tal que E[i] = LCA de x e y;
int query(int p, int x, int y) {
	if (x <= Tree[p].ini && Tree[p].fim <= y)
		return Tree[p].id;
	if ((Tree[p].ini <= x && x <= Tree[p].fim) || (Tree[p].ini <= y && y <= Tree[p].fim)) {
		int id1 = query(2*p, x, y);
		int id2 = query(2*p+1, x, y);
		if (id1 == -1 && id2 == -1) return -1;
		if (id1 == -1) return id2;
		if (id2 == -1) return id1;
		if (L[id1] < L[id2]) return id1;
		return id2;
	}
	return -1;
}

pair <int, int> edge[MAX], aux;
map <pair<int,int>, int> mapa;
int resp[MAX];
bool flag[MAX];

int busca(int id) {
	if (flag[id] == true) return 0;
	flag[id] = true;

	int cont = 0;
	for (int i = 0; i < G[id].size(); i++) if (G[id][i] != Pai[id]) {
		pair <int, int> aux = make_pair(min(id, G[id][i]), max(id, G[id][i]));
		//printf("id=%d  aux=(%d %d)\n", id, aux.first, aux.second);
		mapa[aux] += busca(G[id][i]);
		//printf("mapa[%d %d] = %d\n", aux.first, aux.second, mapa[aux]);
		cont += mapa[aux];
	}
	return cont;
}

int main() {
	int x, y, n;
	scanf("%d", &n);

	for (int i = 0; i < n-1; i++) {
		scanf("%d %d", &x, &y);
		x--, y--;
		edge[i] = make_pair(min(x,y), max(x,y));
		mapa[edge[i]] = 0;

		G[x].push_back(y);
		G[y].push_back(x);
	}
	topoE = 0;
	dfs(0, -1, 1);
	Pai[0] = 0;

	for (int i = 0; i < topoE; i++)
		H[E[i]] = i;

	buildTree(1, 0, topoE-1);
	//dfs_custo(0, -1, 0);
	scanf("%d", &q);
	while(q--) {
		scanf("%d %d", &x, &y);
		x--, y--;
		if (H[x] > H[y]) swap(x, y); //Nunca esquecer de dar o swap se necessario
		int lca = E[query(1, H[x], H[y])];// Começa a query sempre do 1
		//printf("x=%d xp=%d y=%d yp=%d lca=%d\n", x, Pai[x], y, Pai[y], lca);
		int tmp = 0;
		if (x != lca) {
			aux = make_pair(min(x, Pai[x]), max(x, Pai[x]));
			mapa[aux]++;
			tmp++;
		}
		if (y != lca) {
			aux = make_pair(min(y, Pai[y]), max(y, Pai[y]));
			mapa[aux]++;
			tmp++;
		}
		if (Pai[lca] != lca) {
			aux = make_pair(min(lca, Pai[lca]), max(lca, Pai[lca]));
			mapa[aux]-=tmp;
		}
	}
	for (int i = 0; i < n; i++) flag[i] = false;

	/*for (int i = 0; i < n; i++) {
		printf("%d: ", i);
		for (int j = 0; j < G[i].size(); j++) {
			aux = make_pair(min(i, G[i][j]), max(i, G[i][j]));
			printf("(%d %d) ", G[i][j], mapa[aux]);
		}
		printf("\n");
	}printf("\n");*/

	//printf("retorno = %d\n", busca(0));
	busca(0);
	for (int i = 0; i < n-1; i++) {
		if (i != 0) printf(" ");
		printf("%d", mapa[edge[i]]);
	}
	printf("\n");
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<vector>
#include<string.h>
#include <map>

using namespace std;

#define MAX 100100//Maxima entrada, nao se preocupar com o size de Tree[]

struct no {
	int ini, fim;
	int id;
};

// G[]-> grafo que guarda a arvore inicial
// C[]-> custo de cada aresta
vector <int> G[MAX], C[MAX];
// E[]->Despodiçao dos nos depois da dfs
// L[]->Nivel de cada no arvore inicial
// H[]-> E[H[i]] = i, uma indice do elemento i no vetor E[]
int E[2*MAX], L[2*MAX], H[MAX], Pai[MAX];
int topoE;
int n, q;

no Tree[20*MAX];

void dfs(int p, int veio, int nivel) {
	Pai[p] = veio;
	E[topoE] = p;
	L[topoE++] = nivel;
	bool b = false;
	for (int i = 0; i < G[p].size(); i++)
		if (G[p][i] != veio) {
			dfs(G[p][i], p, nivel+1);
			E[topoE] = p;
			L[topoE++] = nivel;
		}
}

void buildTree(int p, int ini, int fim) {
	Tree[p].ini = ini;
	Tree[p].fim = fim;
	if (ini == fim)
		Tree[p].id = ini;
	else {
		int mid = (ini+fim) >> 1;
		buildTree(2*p, ini, mid);
		buildTree(2*p+1, mid+1, fim);

		if (L[Tree[2*p].id] < L[Tree[2*p+1].id])
			Tree[p].id = Tree[2*p].id;
		else
			Tree[p].id = Tree[2*p+1].id;
	}
}

// Retorna o indice i de E[], tal que E[i] = LCA de x e y;
int query(int p, int x, int y) {
	if (x <= Tree[p].ini && Tree[p].fim <= y)
		return Tree[p].id;
	if ((Tree[p].ini <= x && x <= Tree[p].fim) || (Tree[p].ini <= y && y <= Tree[p].fim)) {
		int id1 = query(2*p, x, y);
		int id2 = query(2*p+1, x, y);
		if (id1 == -1 && id2 == -1) return -1;
		if (id1 == -1) return id2;
		if (id2 == -1) return id1;
		if (L[id1] < L[id2]) return id1;
		return id2;
	}
	return -1;
}

pair <int, int> edge[MAX], aux;
map <pair<int,int>, int> mapa;
int resp[MAX];
bool flag[MAX];

int busca(int id) {
	if (flag[id] == true) return 0;
	flag[id] = true;

	int cont = 0;
	for (int i = 0; i < G[id].size(); i++) if (G[id][i] != Pai[id]) {
		aux = make_pair(min(id, G[id][i]), max(id, G[id][i]));
		mapa[aux] += busca(G[id][i]);
		cont += mapa[aux];
	}
	return cont;
}

int main() {
	int x, y, n;
	scanf("%d", &n);

	for (int i = 0; i < n-1; i++) {
		scanf("%d %d", &x, &y);
		x--, y--;
		edge[i] = make_pair(min(x,y), max(x,y));
		mapa[edge[i]] = 0;

		G[x].push_back(y);
		G[y].push_back(x);
	}
	topoE = 0;
	dfs(0, -1, 1);
	Pai[0] = 0;

	for (int i = 0; i < topoE; i++)
		H[E[i]] = i;

	buildTree(1, 0, topoE-1);
	//dfs_custo(0, -1, 0);
	scanf("%d", &q);
	while(q--) {
		scanf("%d %d", &x, &y);
		x--, y--;
		if (H[x] > H[y]) swap(x, y); //Nunca esquecer de dar o swap se necessario
		int lca = E[query(1, H[x], H[y])];// Começa a query sempre do 1
		//printf("x=%d xp=%d y=%d yp=%d lca=%d\n", x, Pai[x], y, Pai[y], lca);
		int tmp = 0;
		if (x != lca) {
			aux = make_pair(min(x, Pai[x]), max(x, Pai[x]));
			mapa[aux]++;
			tmp++;
		}
		if (y != lca) {
			aux = make_pair(min(y, Pai[y]), max(y, Pai[y]));
			mapa[aux]++;
			tmp++;
		}
		if (Pai[lca] != lca) {
			aux = make_pair(min(lca, Pai[lca]), max(lca, Pai[lca]));
			mapa[aux]-=tmp;
		}
	}
	/*printf("\n");
	for (int i = 0; i < n; i++) {
		flag[i] = false;
		for (int j = 0; j < G[i].size(); j++) {
			aux = make_pair(min(i, G[i][j]), max(i, G[i][j]));
			printf("aux(%d %d, %d)  ", aux.first, aux.second, mapa[aux]);
			C[i].push_back(mapa[aux]);
			//C[G[i][j]].push_back(mapa[aux]);
		}
		printf("\n");
	}
	for (int i = 0; i < n; i++) {
		printf("%d: ", i);
		for (int j = 0; j < G[i].size(); j++) printf("%d ", G[i][j]);
		printf("\n");
	}printf("\n");
	for (int i = 0; i < n; i++) {
		printf("%d: ", i);
		for (int j = 0; j < C[i].size(); j++) printf("%d ", C[i][j]);
		printf("\n");
	}*/
	//printf("retorno = %d\n", busca(0));
	busca(0);
	for (int i = 0; i < n-1; i++) {
		if (i != 0) printf(" ");
		printf("%d", mapa[edge[i]]);
	}
	printf("\n");
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<vector>
#include<string.h>
#include <map>

using namespace std;

#define MAX 100100//Maxima entrada, nao se preocupar com o size de Tree[]

struct no {
	int ini, fim;
	int id;
};

// G[]-> grafo que guarda a arvore inicial
// C[]-> custo de cada aresta
vector <int> G[MAX], C[MAX];
// E[]->Despodiçao dos nos depois da dfs
// L[]->Nivel de cada no arvore inicial
// H[]-> E[H[i]] = i, uma indice do elemento i no vetor E[]
int E[2*MAX], L[2*MAX], H[MAX], Pai[MAX];
int topoE;
int n, q;

no Tree[20*MAX];

void dfs(int p, int veio, int nivel) {
	Pai[p] = veio;
	E[topoE] = p;
	L[topoE++] = nivel;
	bool b = false;
	for (int i = 0; i < G[p].size(); i++)
		if (G[p][i] != veio) {
			dfs(G[p][i], p, nivel+1);
			E[topoE] = p;
			L[topoE++] = nivel;
		}
}

void buildTree(int p, int ini, int fim) {
	Tree[p].ini = ini;
	Tree[p].fim = fim;
	if (ini == fim)
		Tree[p].id = ini;
	else {
		int mid = (ini+fim) >> 1;
		buildTree(2*p, ini, mid);
		buildTree(2*p+1, mid+1, fim);

		if (L[Tree[2*p].id] < L[Tree[2*p+1].id])
			Tree[p].id = Tree[2*p].id;
		else
			Tree[p].id = Tree[2*p+1].id;
	}
}

// Retorna o indice i de E[], tal que E[i] = LCA de x e y;
int query(int p, int x, int y) {
	if (x <= Tree[p].ini && Tree[p].fim <= y)
		return Tree[p].id;
	if ((Tree[p].ini <= x && x <= Tree[p].fim) || (Tree[p].ini <= y && y <= Tree[p].fim)) {
		int id1 = query(2*p, x, y);
		int id2 = query(2*p+1, x, y);
		if (id1 == -1 && id2 == -1) return -1;
		if (id1 == -1) return id2;
		if (id2 == -1) return id1;
		if (L[id1] < L[id2]) return id1;
		return id2;
	}
	return -1;
}

pair <int, int> edge[MAX], aux;
map <pair<int,int>, int> mapa;
int resp[MAX];
bool flag[MAX];

int busca(int id) {
	if (flag[id] == true) return 0;
	flag[id] = true;

	int cont = 0;
	for (int i = 0; i < G[id].size(); i++) if (G[id][i] != Pai[id]) {
		aux = make_pair(min(id, G[id][i]), max(id, G[id][i]));
		mapa[aux] += busca(G[id][i]);
		cont += mapa[aux];
	}
	return cont;
}

int main() {
	int x, y, n;
	scanf("%d", &n);

	for (int i = 0; i < n-1; i++) {
		scanf("%d %d", &x, &y);
		x--, y--;
		edge[i] = make_pair(min(x,y), max(x,y));
		mapa[edge[i]] = 0;

		G[x].push_back(y);
		G[y].push_back(x);
	}
	topoE = 0;
	dfs(0, -1, 1);
	Pai[0] = 0;

	for (int i = 0; i < topoE; i++)
		H[E[i]] = i;

	buildTree(1, 0, topoE-1);
	//dfs_custo(0, -1, 0);
	scanf("%d", &q);
	while(q--) {
		scanf("%d %d", &x, &y);
		x--, y--;
		if (H[x] > H[y]) swap(x, y); //Nunca esquecer de dar o swap se necessario
		int lca = E[query(1, H[x], H[y])];// Começa a query sempre do 1
		//printf("x=%d xp=%d y=%d yp=%d lca=%d\n", x, Pai[x], y, Pai[y], lca);
		if (x != lca) {
			aux = make_pair(min(x, Pai[x]), max(x, Pai[x]));
			mapa[aux]++;
		}
		if (y != lca) {
			aux = make_pair(min(y, Pai[y]), max(y, Pai[y]));
			mapa[aux]++;
		}
		if (Pai[lca] != lca) {
			aux = make_pair(min(lca, Pai[lca]), max(lca, Pai[lca]));
			mapa[aux]-=2;
		}
	}
	/*printf("\n");
	for (int i = 0; i < n; i++) {
		flag[i] = false;
		for (int j = 0; j < G[i].size(); j++) {
			aux = make_pair(min(i, G[i][j]), max(i, G[i][j]));
			printf("aux(%d %d, %d)  ", aux.first, aux.second, mapa[aux]);
			C[i].push_back(mapa[aux]);
			//C[G[i][j]].push_back(mapa[aux]);
		}
		printf("\n");
	}
	for (int i = 0; i < n; i++) {
		printf("%d: ", i);
		for (int j = 0; j < G[i].size(); j++) printf("%d ", G[i][j]);
		printf("\n");
	}printf("\n");
	for (int i = 0; i < n; i++) {
		printf("%d: ", i);
		for (int j = 0; j < C[i].size(); j++) printf("%d ", C[i][j]);
		printf("\n");
	}*/
	//printf("retorno = %d\n", busca(0));
	busca(0);
	for (int i = 0; i < n-1; i++) {
		if (i != 0) printf(" ");
		printf("%d", mapa[edge[i]]);
	}
	printf("\n");
	return 0;
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cassert>

using namespace std;

const int max_n=100010;
const int P=17;

int n,k;

struct adjlel
{
	int nbr;
	int eno;
	adjlel(){}
	adjlel(int tnbr, int teno){nbr=tnbr; eno=teno;}
};
vector<adjlel> adjl[max_n];

int tm=0;
bool visited[max_n]={0};
int st[max_n], ft[max_n];
int eref[max_n];
int anc[max_n][P];

void DFS(int vt)
{
	visited[vt]=true;
	++tm;
	st[vt]=tm;

	int tvt,p;
	int vtnbr,enbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr; enbr=adjl[vt][i].eno;
		if(!visited[vtnbr])
		{
			eref[vtnbr]=enbr;
			anc[vtnbr][0]=vt;
			tvt=vt; p=0;
			while(tvt!=-1)
			{
				anc[vtnbr][p+1]=anc[tvt][p];
				tvt=anc[tvt][p];
				++p;
			}
			DFS(vtnbr);
		}
	}

	++tm;
	ft[vt]=tm;
}

//visited used again
int nh[max_n]={0}, nl[max_n]={0};
int NH[max_n]={0}, NL[max_n]={0};
int res[max_n-1];

bool ancof(int u, int v)
{
	return (st[u]<st[v] and ft[v]<ft[u]);
}

int lcanc(int u, int v, int p)
{
	//cout<<"^^ "<<u<<" "<<v<<" "<<p<<endl;
	if(p==-1)
	{
		return anc[u][0];
	}
	else
	{
		if(anc[u][p]==(-1) or ancof(anc[u][p],v))
			return lcanc(u,v,p-1);
		else
			return lcanc(anc[u][p],v,p-1);
	}
}

void DFS2(int vt)
{
	visited[vt]=true;
	NH[vt]=nh[vt]; NL[vt]=nl[vt];

	int vtnbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr;
		if(not visited[vtnbr])
		{
			DFS2(vtnbr);
			NH[vt]+=NH[vtnbr];
			NL[vt]+=NL[vtnbr];
		}
	}

	if(vt!=0)
		res[eref[vt]]=NH[vt]-NL[vt];
}

void processpair(int a, int b)
{
	if(ancof(a,b))
	{
		++nh[b];
		++nl[a];
	}
	else if(ancof(b,a))
	{
		++nh[a];
		++nl[b];
	}
	else
	{
		nl[lcanc(a,b,P-1)]+=2;
		++nh[a]; ++nh[b];
	}
}

int main()
{
	scanf("%d",&n);

	int u,v;
	for(int i=0; i<n-1; ++i)
	{
		scanf("%d %d",&u,&v);
		--u; --v;
		adjl[u].push_back(adjlel(v,i));
		adjl[v].push_back(adjlel(u,i));
	}

	eref[0]=-1;
	for(int i=0; i<n; ++i)
		for(int p=0; p<P; ++p)
			anc[i][p]=-1;

	DFS(0);

	/*for(int i=0; i<n; ++i)
	{
		cout<<i<<" : "<<st[i]<<" "<<ft[i]<<" "<<eref[i]<<" "<<anc[i][0]<<endl;
		cout<<i<<" : "<<endl;
		for(int j=0; j<6; ++j)
			cout<<anc[i][j]<<" ";
		cout<<endl;
	}*/

	scanf("%d",&k);

	int a,b;
	for(int i=0; i<k; ++i)
	{
		scanf("%d %d",&a,&b);
		--a; --b;
		if(a!=b)
			processpair(a,b);
	}

	//cout<<lcanc(1,2,P-1)<<" "<<lcanc(1,4,P-1)<<endl;

	fill(visited,visited+n,false);

	DFS2(0);

	/*for(int i=0; i<n; ++i)
		cout<<i<<" "<<nh[i]<<" "<<nl[i]<<" "<<NH[i]<<" "<<NL[i]<<endl;*/
	//cout<<lcanc(9,3,P-1)<<" "<<lcanc(12,8,P-1)<<" "<<lcanc(3,8,P-1)<<" "<<lcanc(1,8,P-1)<<" "<<lcanc(5,6,P-1)<<endl;

	//for(int i=2; i<n; ++i)
		//printf("%d : %d %d\n",i+1,lcanc(i,10,P-1),lcanc(10,i,P-1));

	for(int i=0; i<n-1; ++i)
		printf("%d ",res[i]);
	printf("\n");
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cassert>

using namespace std;

const int max_n=100010;
const int P=17;

int n,k;

struct adjlel
{
	int nbr;
	int eno;
	adjlel(){}
	adjlel(int tnbr, int teno){nbr=tnbr; eno=teno;}
};
vector<adjlel> adjl[max_n];

int tm=0;
bool visited[max_n]={0};
int st[max_n], ft[max_n];
int eref[max_n];
int anc[max_n][P];

void DFS(int vt)
{
	visited[vt]=true;
	++tm;
	st[vt]=tm;

	int tvt,p;
	int vtnbr,enbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr; enbr=adjl[vt][i].eno;
		if(!visited[vtnbr])
		{
			eref[vtnbr]=enbr;
			anc[vtnbr][0]=vt;
			tvt=vt; p=0;
			while(tvt!=-1)
			{
				anc[vtnbr][p+1]=anc[tvt][p];
				tvt=anc[tvt][p];
				++p;
			}
			DFS(vtnbr);
		}
	}

	++tm;
	ft[vt]=tm;
}

//visited used again
int nh[max_n]={0}, nl[max_n]={0};
int NH[max_n]={0}, NL[max_n]={0};
int res[max_n-1];

bool ancof(int u, int v)
{
	return (st[u]<st[v] and ft[v]<ft[u]);
}

int lcanc(int u, int v, int p)
{
	//cout<<"^^ "<<u<<" "<<v<<" "<<p<<endl;
	if(p==-1)
	{
		return anc[u][0];
	}
	else
	{
		if(anc[u][p]==(-1) or ancof(anc[u][p],v))
			return lcanc(u,v,p-1);
		else
			return lcanc(anc[u][p],v,p-1);
	}
}

void DFS2(int vt)
{
	visited[vt]=true;
	NH[vt]=nh[vt]; NL[vt]=nl[vt];

	int vtnbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr;
		if(not visited[vtnbr])
		{
			DFS2(vtnbr);
			NH[vt]+=NH[vtnbr];
			NL[vt]+=NL[vtnbr];
		}
	}

	if(vt!=0)
		res[eref[vt]]=NH[vt]-NL[vt];
}

void processpair(int a, int b)
{
	if(ancof(a,b))
	{
		++nh[b];
		++nl[a];
	}
	else if(ancof(b,a))
	{
		++nh[a];
		++nl[b];
	}
	else
	{
		nl[lcanc(a,b,P-1)]+=2;
		++nh[a]; ++nh[b];
	}
}

int main()
{
	scanf("%d",&n);

	int u,v;
	for(int i=0; i<n-1; ++i)
	{
		scanf("%d %d",&u,&v);
		--u; --v;
		adjl[u].push_back(adjlel(v,i));
		adjl[v].push_back(adjlel(u,i));
	}

	eref[0]=-1;
	for(int i=0; i<n; ++i)
		for(int p=0; p<P; ++p)
			anc[i][p]=-1;

	DFS(0);

	/*for(int i=0; i<n; ++i)
	{
		cout<<i<<" : "<<st[i]<<" "<<ft[i]<<" "<<eref[i]<<" "<<anc[i][0]<<endl;
		cout<<i<<" : "<<endl;
		for(int j=0; j<6; ++j)
			cout<<anc[i][j]<<" ";
		cout<<endl;
	}*/

	scanf("%d",&k);

	int a,b;
	for(int i=0; i<k; ++i)
	{
		scanf("%d %d",&a,&b);
		--a; --b;
		processpair(a,b);
	}

	//cout<<lcanc(1,2,P-1)<<" "<<lcanc(1,4,P-1)<<endl;

	fill(visited,visited+n,false);

	DFS2(0);

	/*for(int i=0; i<n; ++i)
		cout<<i<<" "<<nh[i]<<" "<<nl[i]<<" "<<NH[i]<<" "<<NL[i]<<endl;*/

	for(int i=0; i<n-1; ++i)
		printf("%d ",res[i]);
	printf("\n");
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cassert>

using namespace std;

const int max_n=100010;
const int P=17;

int n,k;

struct adjlel
{
	int nbr;
	int eno;
	adjlel(){}
	adjlel(int tnbr, int teno){nbr=tnbr; eno=teno;}
};
vector<adjlel> adjl[max_n];

int tm=0;
bool visited[max_n]={0};
int st[max_n], ft[max_n];
int eref[max_n];
int anc[max_n][P];

void DFS(int vt)
{
	visited[vt]=true;
	++tm;
	st[vt]=tm;

	int tvt,p;
	int vtnbr,enbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr; enbr=adjl[vt][i].eno;
		if(!visited[vtnbr])
		{
			eref[vtnbr]=enbr;
			anc[vtnbr][0]=vt;
			tvt=vt; p=0;
			while(tvt!=-1)
			{
				anc[vtnbr][p+1]=anc[tvt][p];
				tvt=anc[tvt][p];
				++p;
			}
			DFS(vtnbr);
		}
	}

	++tm;
	ft[vt]=tm;
}

//visited used again
int nh[max_n]={0}, nl[max_n]={0};
int NH[max_n]={0}, NL[max_n]={0};
int res[max_n-1];

bool ancof(int u, int v)
{
	return (st[u]<st[v] and ft[v]<ft[u]);
}

int lcanc(int u, int v, int p)
{
	//cout<<"^^ "<<u<<" "<<v<<" "<<p<<endl;
	if(p==-1)
	{
		return anc[u][0];
	}
	else
	{
		if(anc[u][p]==(-1) or ancof(anc[u][p],v))
			return lcanc(u,v,p-1);
		else
			return lcanc(anc[u][p],v,p-1);
	}
}

void DFS2(int vt)
{
	visited[vt]=true;
	NH[vt]=nh[vt]; NL[vt]=nl[vt];

	int vtnbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr;
		if(not visited[vtnbr])
		{
			DFS2(vtnbr);
			NH[vt]+=NH[vtnbr];
			NL[vt]+=NL[vtnbr];
		}
	}

	if(vt!=0)
		res[eref[vt]]=NH[vt]-NL[vt];
}

void processpair(int a, int b)
{
	if(ancof(a,b))
	{
		++nh[b];
		++nl[a];
	}
	else if(ancof(b,a))
	{
		++nh[a];
		++nl[b];
	}
	else
	{
		nl[lcanc(a,b,P-1)]+=2;
		++nh[a]; ++nh[b];
	}
}

int main()
{
	scanf("%d",&n);

	int u,v;
	for(int i=0; i<n-1; ++i)
	{
		scanf("%d %d",&u,&v);
		--u; --v;
		adjl[u].push_back(adjlel(v,i));
		adjl[v].push_back(adjlel(u,i));
	}

	eref[0]=-1;
	for(int i=0; i<n; ++i)
		for(int p=0; p<P; ++p)
			anc[i][p]=-1;

	DFS(0);

	/*for(int i=0; i<n; ++i)
	{
		cout<<i<<" : "<<st[i]<<" "<<ft[i]<<" "<<eref[i]<<" "<<anc[i][0]<<endl;
		cout<<i<<" : "<<endl;
		for(int j=0; j<6; ++j)
			cout<<anc[i][j]<<" ";
		cout<<endl;
	}*/

	scanf("%d",&k);

	int a,b;
	for(int i=0; i<k; ++i)
	{
		scanf("%d %d",&a,&b);
		--a; --b;
		processpair(a,b);
	}

	//cout<<lcanc(1,2,P-1)<<" "<<lcanc(1,4,P-1)<<endl;

	fill(visited,visited+n,false);

	DFS2(0);

	/*for(int i=0; i<n; ++i)
		cout<<i<<" "<<nh[i]<<" "<<nl[i]<<" "<<NH[i]<<" "<<NL[i]<<endl;*/
	//cout<<lcanc(9,3,P-1)<<" "<<lcanc(12,8,P-1)<<" "<<lcanc(3,8,P-1)<<" "<<lcanc(1,8,P-1)<<" "<<lcanc(5,6,P-1)<<endl;

	//for(int i=1; i<n; ++i)
		//printf("%d : %d\n",i+1,lcanc(i,10,P-1));

	for(int i=0; i<n-1; ++i)
		printf("%d ",res[i]);
	printf("\n");
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cassert>

using namespace std;

const int max_n=100010;
const int P=20;

int n,k;

struct adjlel
{
	int nbr;
	int eno;
	adjlel(){}
	adjlel(int tnbr, int teno){nbr=tnbr; eno=teno;}
};
vector<adjlel> adjl[max_n];

int tm=0;
bool visited[max_n]={0};
int st[max_n], ft[max_n];
int eref[max_n];
int anc[max_n][P];

void DFS(int vt)
{
	visited[vt]=true;
	++tm;
	st[vt]=tm;

	int tvt,p;
	int vtnbr,enbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr; enbr=adjl[vt][i].eno;
		if(!visited[vtnbr])
		{
			eref[vtnbr]=enbr;
			anc[vtnbr][0]=vt;
			tvt=vt; p=0;
			while(tvt!=-1)
			{
				anc[vtnbr][p+1]=anc[tvt][p];
				tvt=anc[tvt][p];
				++p;
			}
			DFS(vtnbr);
		}
	}

	++tm;
	ft[vt]=tm;
}

//visited used again
int nh[max_n]={0}, nl[max_n]={0};
int NH[max_n]={0}, NL[max_n]={0};
int res[max_n-1];

bool ancof(int u, int v)
{
	return (st[u]<st[v] and ft[v]<ft[u]);
}

int lcanc(int u, int v, int p)
{
	//cout<<"^^ "<<u<<" "<<v<<" "<<p<<endl;
	if(p==-1)
	{
		return anc[u][0];
	}
	else
	{
		if(anc[u][p]==(-1) or ancof(anc[u][p],v))
			return lcanc(u,v,p-1);
		else
			return lcanc(anc[u][p],v,p-1);
	}
}

void DFS2(int vt)
{
	visited[vt]=true;
	NH[vt]=nh[vt]; NL[vt]=nl[vt];

	int vtnbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr;
		if(not visited[vtnbr])
		{
			DFS2(vtnbr);
			NH[vt]+=NH[vtnbr];
			NL[vt]+=NL[vtnbr];
		}
	}

	if(vt!=0)
		res[eref[vt]]=NH[vt]-NL[vt];
}

void processpair(int a, int b)
{
	if(ancof(a,b))
	{
		++nh[b];
		++nl[a];
	}
	else if(ancof(b,a))
	{
		++nh[a];
		++nl[b];
	}
	else
	{
		nl[lcanc(a,b,P-1)]+=2;
		++nh[a]; ++nh[b];
	}
}

int main()
{
	scanf("%d",&n);

	int u,v;
	for(int i=0; i<n-1; ++i)
	{
		scanf("%d %d",&u,&v);
		--u; --v;
		adjl[u].push_back(adjlel(v,i));
		adjl[v].push_back(adjlel(u,i));
	}

	eref[0]=-1;
	for(int i=0; i<n; ++i)
		for(int p=0; p<P; ++p)
			anc[i][p]=-1;

	DFS(0);

	/*for(int i=0; i<n; ++i)
	{
		cout<<i<<" : "<<st[i]<<" "<<ft[i]<<" "<<eref[i]<<" "<<anc[i][0]<<endl;
		cout<<i<<" : "<<endl;
		for(int j=0; j<6; ++j)
			cout<<anc[i][j]<<" ";
		cout<<endl;
	}*/

	scanf("%d",&k);

	int a,b;
	for(int i=0; i<k; ++i)
	{
		scanf("%d %d",&a,&b);
		--a; --b;
		processpair(a,b);
	}

	//cout<<lcanc(1,2,P-1)<<" "<<lcanc(1,4,P-1)<<endl;

	fill(visited,visited+n,false);

	DFS2(0);

	/*for(int i=0; i<n; ++i)
		cout<<i<<" "<<nh[i]<<" "<<nl[i]<<" "<<NH[i]<<" "<<NL[i]<<endl;*/
	//cout<<lcanc(9,3,P-1)<<" "<<lcanc(12,8,P-1)<<" "<<lcanc(3,8,P-1)<<" "<<lcanc(1,8,P-1)<<" "<<lcanc(5,6,P-1)<<endl;

	//for(int i=2; i<n; ++i)
		//printf("%d : %d %d\n",i+1,lcanc(i,10,P-1),lcanc(10,i,P-1));

	for(int i=0; i<n-1; ++i)
		printf("%d ",res[i]);
	printf("\n");
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cassert>

using namespace std;

const int max_n=100010;
const int P=20;

int n,k;

struct adjlel
{
	int nbr;
	int eno;
	adjlel(){}
	adjlel(int tnbr, int teno){nbr=tnbr; eno=teno;}
};
vector<adjlel> adjl[max_n];

int tm=0;
bool visited[max_n]={0};
int st[max_n], ft[max_n];
int eref[max_n];
int anc[max_n][P];

void DFS(int vt)
{
	visited[vt]=true;
	++tm;
	st[vt]=tm;

	int tvt,p;
	int vtnbr,enbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr; enbr=adjl[vt][i].eno;
		if(!visited[vtnbr])
		{
			eref[vtnbr]=enbr;
			anc[vtnbr][0]=vt;
			tvt=vt; p=0;
			while(tvt!=-1)
			{
				anc[vtnbr][p+1]=anc[tvt][p];
				tvt=anc[tvt][p];
				++p;
			}
			DFS(vtnbr);
		}
	}

	++tm;
	ft[vt]=tm;
}

//visited used again
int nh[max_n]={0}, nl[max_n]={0};
int NH[max_n]={0}, NL[max_n]={0};
int res[max_n-1];

bool ancof(int u, int v)
{
	return (st[u]<st[v] and ft[v]<ft[u]);
}

int lcanc(int u, int v, int p)
{
	//cout<<"^^ "<<u<<" "<<v<<" "<<p<<endl;
	if(p==-1)
	{
		return anc[u][0];
	}
	else
	{
		if(anc[u][p]==(-1) or ancof(anc[u][p],v))
			return lcanc(u,v,p-1);
		else
			return lcanc(anc[u][p],v,p-1);
	}
}

void DFS2(int vt)
{
	visited[vt]=true;
	NH[vt]=nh[vt]; NL[vt]=nl[vt];

	int vtnbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr;
		if(not visited[vtnbr])
		{
			DFS2(vtnbr);
			NH[vt]+=NH[vtnbr];
			NL[vt]+=NL[vtnbr];
		}
	}

	if(vt!=0)
		res[eref[vt]]=NH[vt]-NL[vt];
}

void processpair(int a, int b)
{
	if(ancof(a,b))
	{
		++nh[b];
		++nl[a];
	}
	else if(ancof(b,a))
	{
		++nh[a];
		++nl[b];
	}
	else
	{
		nl[lcanc(a,b,P-1)]+=2;
		++nh[a]; ++nh[b];
	}
}

int main()
{
	scanf("%d",&n);

	int u,v;
	for(int i=0; i<n-1; ++i)
	{
		scanf("%d %d",&u,&v);
		--u; --v;
		adjl[u].push_back(adjlel(v,i));
		adjl[v].push_back(adjlel(u,i));
	}

	eref[0]=-1;
	for(int i=0; i<n; ++i)
		for(int p=0; p<P; ++p)
			anc[i][p]=-1;

	DFS(0);

	/*for(int i=0; i<n; ++i)
	{
		cout<<i<<" : "<<st[i]<<" "<<ft[i]<<" "<<eref[i]<<" "<<anc[i][0]<<endl;
		cout<<i<<" : "<<endl;
		for(int j=0; j<6; ++j)
			cout<<anc[i][j]<<" ";
		cout<<endl;
	}*/

	scanf("%d",&k);

	int a,b;
	for(int i=0; i<k; ++i)
	{
		scanf("%d %d",&a,&b);
		--a; --b;
		processpair(a,b);
	}

	//cout<<lcanc(1,2,P-1)<<" "<<lcanc(1,4,P-1)<<endl;

	fill(visited,visited+n,false);

	DFS2(0);

	/*for(int i=0; i<n; ++i)
		cout<<i<<" "<<nh[i]<<" "<<nl[i]<<" "<<NH[i]<<" "<<NL[i]<<endl;*/
	//cout<<lcanc(9,3,P-1)<<" "<<lcanc(12,8,P-1)<<" "<<lcanc(3,8,P-1)<<" "<<lcanc(1,8,P-1)<<" "<<lcanc(5,6,P-1)<<endl;

	for(int i=2; i<n; ++i)
		printf("%d : %d %d\n",i+1,lcanc(i,10,P-1),lcanc(10,i,P-1));

	for(int i=0; i<n-1; ++i)
		printf("%d ",res[i]);
	printf("\n");
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cassert>

using namespace std;

const int max_n=100010;
const int P=20;

int n,k;

struct adjlel
{
	int nbr;
	int eno;
	adjlel(){}
	adjlel(int tnbr, int teno){nbr=tnbr; eno=teno;}
};
vector<adjlel> adjl[max_n];

int tm=0;
bool visited[max_n]={0};
int st[max_n], ft[max_n];
int eref[max_n];
int anc[max_n][P];

void DFS(int vt)
{
	visited[vt]=true;
	++tm;
	st[vt]=tm;

	int tvt,p;
	int vtnbr,enbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr; enbr=adjl[vt][i].eno;
		if(!visited[vtnbr])
		{
			eref[vtnbr]=enbr;
			anc[vtnbr][0]=vt;
			tvt=vt; p=0;
			while(tvt!=-1)
			{
				anc[vtnbr][p+1]=anc[tvt][p];
				tvt=anc[tvt][p];
				++p;
			}
			DFS(vtnbr);
		}
	}

	++tm;
	ft[vt]=tm;
}

//visited used again
int nh[max_n]={0}, nl[max_n]={0};
int NH[max_n]={0}, NL[max_n]={0};
int res[max_n-1];

bool ancof(int u, int v)
{
	return (st[u]<st[v] and ft[v]<ft[u]);
}

int lcanc(int u, int v, int p)
{
	//cout<<"^^ "<<u<<" "<<v<<" "<<p<<endl;
	if(p==-1)
	{
		return anc[u][0];
	}
	else
	{
		if(anc[u][p]==(-1) or ancof(anc[u][p],v))
			return lcanc(u,v,p-1);
		else
			return lcanc(anc[u][p],v,p-1);
	}
}

void DFS2(int vt)
{
	visited[vt]=true;
	NH[vt]=nh[vt]; NL[vt]=nl[vt];

	int vtnbr;
	for(int i=0; i<adjl[vt].size(); ++i)
	{
		vtnbr=adjl[vt][i].nbr;
		if(not visited[vtnbr])
		{
			DFS2(vtnbr);
			NH[vt]+=NH[vtnbr];
			NL[vt]+=NL[vtnbr];
		}
	}

	if(vt!=0)
		res[eref[vt]]=NH[vt]-NL[vt];
}

void processpair(int a, int b)
{
	if(ancof(a,b))
	{
		++nh[b];
		++nl[a];
	}
	else if(ancof(b,a))
	{
		++nh[a];
		++nl[b];
	}
	else
	{
		nl[lcanc(a,b,P-1)]+=2;
		++nh[a]; ++nh[b];
	}
}

int main()
{
	scanf("%d",&n);

	int u,v;
	for(int i=0; i<n-1; ++i)
	{
		scanf("%d %d",&u,&v);
		--u; --v;
		adjl[u].push_back(adjlel(v,i));
		adjl[v].push_back(adjlel(u,i));
	}

	eref[0]=-1;
	for(int i=0; i<n; ++i)
		for(int p=0; p<P; ++p)
			anc[i][p]=-1;

	DFS(0);

	/*for(int i=0; i<n; ++i)
	{
		cout<<i<<" : "<<st[i]<<" "<<ft[i]<<" "<<eref[i]<<" "<<anc[i][0]<<endl;
		cout<<i<<" : "<<endl;
		for(int j=0; j<6; ++j)
			cout<<anc[i][j]<<" ";
		cout<<endl;
	}*/

	scanf("%d",&k);

	int a,b;
	for(int i=0; i<k; ++i)
	{
		scanf("%d %d",&a,&b);
		--a; --b;
		if(a!=b)
			processpair(a,b);
	}

	//cout<<lcanc(1,2,P-1)<<" "<<lcanc(1,4,P-1)<<endl;

	fill(visited,visited+n,false);

	DFS2(0);

	/*for(int i=0; i<n; ++i)
		cout<<i<<" "<<nh[i]<<" "<<nl[i]<<" "<<NH[i]<<" "<<NL[i]<<endl;*/
	//cout<<lcanc(9,3,P-1)<<" "<<lcanc(12,8,P-1)<<" "<<lcanc(3,8,P-1)<<" "<<lcanc(1,8,P-1)<<" "<<lcanc(5,6,P-1)<<endl;

	//for(int i=2; i<n; ++i)
		//printf("%d : %d %d\n",i+1,lcanc(i,10,P-1),lcanc(10,i,P-1));

	for(int i=0; i<n-1; ++i)
		printf("%d ",res[i]);
	printf("\n");
}


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct edge
{
	int y, next, id;
};

const int maxn = 10010, maxk = 20;
int n, m, num, head[maxn], depth[maxn], f[maxn][maxk], pre[maxn], ans[maxn], s[maxn];
edge e[maxn << 1];

inline void add(int a, int b, int id)
{
	num++;
	e[num].next = head[a];
	head[a] = num;
	e[num].y = b;
	e[num].id = id;
}

void dfs(int k, int deep)
{
	depth[k] = deep;
	for (int temp = head[k]; temp >= 0; temp = e[temp].next)
	{
		int j = e[temp].y;
		if (j != f[k][0])
                {
			pre[j] = e[temp].id;
			f[j][0] = k;
			int i = 0;
			for (int i = 0; f[f[j][i]][i] > 0; i++)
			        f[j][i + 1] =f[f[j][i]][i];
			dfs(j, deep + 1);
		}
	}
}

inline int LCA(int a, int b)
{
	if (depth[a] < depth[b])
		swap(a, b);
	for (int i = 17; depth[a] > depth[b]; i--)
		if (f[a][i] > 0 && depth[f[a][i]] >= depth[b])
			a = f[a][i];
	if (a == b)
	        return a;
	for (int i = 17; f[a][0] != f[b][0]; i--)
	        if (f[a][i] > 0 && f[a][i] != f[b][i])
	        {
			a = f[a][i];
			b = f[b][i];
		}
	return f[a][0];
}

void slove(int k)
{
        for (int temp = head[k]; temp >= 0; temp = e[temp].next)
        {
		int j = e[temp].y;
		if (j != f[k][0])
                {
			slove(j);
			s[k] += s[j];
		}
	}
	if (k > 1) ans[pre[k]] = s[k];
}

int main()
{
	scanf("%d", &n);
	memset(head, -1, sizeof(head));
	num = -1;
	for (int i = 1; i < n; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		add(a, b, i);
		add(b, a, i);
	}
	memset(f, -1, sizeof(f));
	dfs(1, 0);
	scanf("%d", &m);
	memset(ans, 0, sizeof(ans));
	for (int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		int lca = LCA(a, b);
		s[a]++;
		s[b]++;
		s[lca] -= 2;
	}
	slove(1);
	for (int i = 1; i < n; i++)
	        printf("%d ", ans[i]);
	printf("\n");

	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct edge
{
	int y, next, id;
};

const int maxn = 100010, maxk = 20;
int n, m, num, head[maxn], depth[maxn], f[maxn][maxk], pre[maxn], ans[maxn], s[maxn];
edge e[maxn << 1];

inline void add(int a, int b, int id)
{
	num++;
	e[num].next = head[a];
	head[a] = num;
	e[num].y = b;
	e[num].id = id;
}

void dfs(int k, int deep)
{
	depth[k] = deep;
	for (int temp = head[k]; temp >= 0; temp = e[temp].next)
	{
		int j = e[temp].y;
		if (j != f[k][0])
                {
			pre[j] = e[temp].id;
			f[j][0] = k;
			int i = 0;
			for (int i = 0; f[f[j][i]][i] > 0; i++)
			        f[j][i + 1] =f[f[j][i]][i];
			dfs(j, deep + 1);
		}
	}
}

inline int LCA(int a, int b)
{
	if (depth[a] < depth[b])
		swap(a, b);
	for (int i = 17; depth[a] > depth[b]; i--)
		if (f[a][i] > 0 && depth[f[a][i]] >= depth[b])
			a = f[a][i];
	if (a == b)
	        return a;
	for (int i = 17; f[a][0] != f[b][0]; i--)
	        if (f[a][i] > 0 && f[a][i] != f[b][i])
	        {
			a = f[a][i];
			b = f[b][i];
		}
	return f[a][0];
}

void slove(int k)
{
        for (int temp = head[k]; temp >= 0; temp = e[temp].next)
        {
		int j = e[temp].y;
		if (j != f[k][0])
                {
			slove(j);
			s[k] += s[j];
		}
	}
	if (k > 1) ans[pre[k]] = s[k];
}

int main()
{
	scanf("%d", &n);
	memset(head, -1, sizeof(head));
	num = -1;
	for (int i = 1; i < n; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		add(a, b, i);
		add(b, a, i);
	}
	memset(f, -1, sizeof(f));
	dfs(1, 0);
	scanf("%d", &m);
	memset(ans, 0, sizeof(ans));
	for (int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		int lca = LCA(a, b);
		s[a]++;
		s[b]++;
		s[lca] -= 2;
	}
	slove(1);
	for (int i = 1; i < n; i++)
	        printf("%d ", ans[i]);
	printf("\n");

	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <iomanip>

#define lli long long int
#define sc scanf
#define pr printf
#define pb push_back
#define p_b pop_back
#define mp make_pair
#define fi first
#define se second
#define fin freopen( "input.txt", "r", stdin );
#define fout freopen( "output.txt", "w", stdout );
#define dist( x, xx, y, yy ) sqrt( (x - y) * (x - y) + (xx - yy) * (xx - yy) )

const int N = 101101;

using namespace std;

int n, k, ans[N], p[N][20], dep[N], tin[N], tout[N], tim, d[N], lem = 0;
vector < pair < int, int > > v[N];
vector < int > g[N];
pair < int, int > li[N];

void dfs( int x, int pre, int gg = 0 )
{
    tin[x] = ++tim;
    dep[x] = dep[pre] + 1;
    g[dep[x]].pb(x);
    li[x] = mp(pre, gg);
    p[x][0] = pre;
    for( int j = 1; j < 20; j++ ){
        p[x][j] = p[p[x][j - 1]][j - 1];
    }
    for( int i = 0; i < v[x].size(); i++ ){
        if( v[x][i].fi == pre )continue;
        dfs(v[x][i].fi, x, v[x][i].se);
    }
    tout[x] = ++tim;
}

bool isp( int x, int y )
{
    return tin[x] < tin[y] && tout[x] > tout[y];
}

int P( int x, int y )
{
    if( isp(x, y) )return x;
    if( isp(y, x) )return y;
    for( int i = 19; i >= 0; i-- ){
        if( !isp(p[x][i], y) ){
            x = p[x][i];
        }
    }
    return p[x][0];
}

void get_dfs( int x, int pre )
{
    for( int i = 0; i < v[x].size(); i++ ){
        if( v[x][i].fi == pre )continue;
        get_dfs( v[x][i].fi, x );
        ans[v[x][i].se] = d[v[x][i].fi];
        d[x] += d[v[x][i].fi];
    }
}

int main()
{
    int x, y, i, j, h;
    sc( "%d", &n );
    for( i = 1; i < n; i++ ){
        sc( "%d%d", &x, &y );
        v[x].pb(mp(y, i));
        v[y].pb(mp(x, i));
    }
    dfs(1, 1);
    sc( "%d", &k );
    for( i = 1; i <= k; i++ ){
        sc( "%d%d", &x, &y );
        d[x]++;
        d[y]++;
        d[P(x, y)] -= 2;
    }
    get_dfs(1, 1);
    for( i = 1; i < n; i++ )pr( "%d ", ans[i] );
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <iomanip>

#define lli long long int
#define sc scanf
#define pr printf
#define pb push_back
#define p_b pop_back
#define mp make_pair
#define fi first
#define se second
#define fin freopen( "input.txt", "r", stdin );
#define fout freopen( "output.txt", "w", stdout );
#define dist( x, xx, y, yy ) sqrt( (x - y) * (x - y) + (xx - yy) * (xx - yy) )

const int N = 100001;

using namespace std;

int n, k, ans[N], p[N][20], dep[N], tin[N], tout[N], tim, d[N], lem = 0;
vector < pair < int, int > > v[N];
vector < int > g[N];
pair < int, int > li[N];

void dfs( int x, int pre = 0, int gg = 0 )
{
    if( !pre )pre = x;
    tin[x] = ++tim;
    dep[x] = dep[pre] + 1;
    g[dep[x]].pb(x);
    li[x] = mp(pre, gg);
    p[x][0] = pre;
    for( int j = 1; j < 20; j++ ){
        p[x][j] = p[p[x][j - 1]][j - 1];
    }
    for( int i = 0; i < v[x].size(); i++ ){
        if( v[x][i].fi == pre )continue;
        dfs(v[x][i].fi, x, v[x][i].se);
    }
    tout[x] = ++tim;
}

bool isp( int x, int y )
{
    return tin[x] < tin[y] && tout[x] > tout[y];
}

int P( int x, int y )
{
    if( isp(x, y) )return x;
    if( isp(y, x) )return y;
    for( int i = 19; i >= 0; i-- ){
        if( !isp(p[x][i], y) ){
            x = p[x][i];
        }
    }
    return p[x][0];
}

int main()
{
    int x, y, i, j, h;
    sc( "%d", &n );
    for( i = 1; i < n; i++ ){
        sc( "%d%d", &x, &y );
        v[x].pb(mp(y, i));
        v[y].pb(mp(x, i));
    }
    dfs(1);
    sc( "%d", &k );
    for( i = 1; i <= k; i++ ){
        sc( "%d%d", &x, &y );
        d[x]++;
        d[y]++;
        d[P(x, y)] -= 2;
    }
    for( i = n; i >= 1; i-- ){
        for( j = 0; j < g[i].size(); j++ ){
            d[li[g[i][j]].fi] += d[g[i][j]];
            ans[li[g[i][j]].se] += d[g[i][j]];
        }
    }
    for( i = 1; i < n; i++ )pr( "%d ", ans[i] );
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <iomanip>

#define lli long long int
#define sc scanf
#define pr printf
#define pb push_back
#define p_b pop_back
#define mp make_pair
#define fi first
#define se second
#define fin freopen( "input.txt", "r", stdin );
#define fout freopen( "output.txt", "w", stdout );
#define dist( x, xx, y, yy ) sqrt( (x - y) * (x - y) + (xx - yy) * (xx - yy) )

const int N = 100001;

using namespace std;

int n, k, ans[N], p[N][20], dep[N], tin[N], tout[N], tim, d[N], lem = 0;
vector < pair < int, int > > v[N];
vector < int > g[N];
pair < int, int > li[N];

void dfs( int x, int pre = 0, int gg = 0 )
{
    if( !pre )pre = x;
    tin[x] = ++tim;
    dep[x] = dep[pre] + 1;
    g[dep[x]].pb(x);
    li[x] = mp(pre, gg);
    p[x][0] = pre;
    for( int j = 1; j < 20; j++ ){
        p[x][j] = p[p[x][j - 1]][j - 1];
    }
    for( int i = 0; i < v[x].size(); i++ ){
        if( v[x][i].fi == pre )continue;
        dfs(v[x][i].fi, x, v[x][i].se);
    }
    tout[x] = ++tim;
}

bool isp( int x, int y )
{
    return tin[x] <= tin[y] && tout[x] >= tout[y];
}

int P( int x, int y )
{
    if( isp(x, y) )return x;
    if( isp(y, x) )return y;
    for( int i = 19; i >= 0; i-- ){
        if( !isp(p[x][i], y) ){
            x = p[x][i];
        }
    }
    return p[x][0];
}

int main()
{
    int x, y, i, j, h;
    sc( "%d", &n );
    for( i = 1; i < n; i++ ){
        sc( "%d%d", &x, &y );
        v[x].pb(mp(y, i));
        v[y].pb(mp(x, i));
    }
    dfs(1);
    sc( "%d", &k );
    for( i = 1; i <= k; i++ ){
        sc( "%d%d", &x, &y );
        d[x]++;
        d[y]++;
        d[P(x, y)] -= 2;
    }
    for( i = n; i >= 1; i-- ){
        for( j = 0; j < g[i].size(); j++ ){
            d[li[g[i][j]].fi] += d[g[i][j]];
            ans[li[g[i][j]].se] += d[g[i][j]];
        }
    }
    for( i = 1; i < n; i++ )pr( "%d ", ans[i] );
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <iomanip>

#define lli long long int
#define sc scanf
#define pr printf
#define pb push_back
#define p_b pop_back
#define mp make_pair
#define fi first
#define se second
#define fin freopen( "input.txt", "r", stdin );
#define fout freopen( "output.txt", "w", stdout );
#define dist( x, xx, y, yy ) sqrt( (x - y) * (x - y) + (xx - yy) * (xx - yy) )

const int N = 101101;

using namespace std;

int n, k, ans[N], p[N][20], dep[N], tin[N], tout[N], tim, d[N], lem = 0;
vector < pair < int, int > > v[N];
vector < int > g[N];
pair < int, int > li[N];

void dfs( int x, int pre = 0, int gg = 0 )
{
    if( !pre )pre = x;
    tin[x] = ++tim;
    dep[x] = dep[pre] + 1;
    g[dep[x]].pb(x);
    li[x] = mp(pre, gg);
    p[x][0] = pre;
    for( int j = 1; j < 20; j++ ){
        p[x][j] = p[p[x][j - 1]][j - 1];
    }
    for( int i = 0; i < v[x].size(); i++ ){
        if( v[x][i].fi == pre )continue;
        dfs(v[x][i].fi, x, v[x][i].se);
    }
    tout[x] = ++tim;
}

bool isp( int x, int y )
{
    return tin[x] < tin[y] && tout[x] > tout[y];
}

int P( int x, int y )
{
    if( isp(x, y) )return x;
    if( isp(y, x) )return y;
    for( int i = 19; i >= 0; i-- ){
        if( !isp(p[x][i], y) ){
            x = p[x][i];
        }
    }
    return p[x][0];
}

int main()
{
    int x, y, i, j, h;
    sc( "%d", &n );
    for( i = 1; i < n; i++ ){
        sc( "%d%d", &x, &y );
        v[x].pb(mp(y, i));
        v[y].pb(mp(x, i));
    }
    dfs(1);
    sc( "%d", &k );
    for( i = 1; i <= k; i++ ){
        sc( "%d%d", &x, &y );
        d[x]++;
        d[y]++;
        d[P(x, y)] -= 2;
    }
    for( i = n; i >= 1; i-- ){
        for( j = 0; j < g[i].size(); j++ ){
            ans[li[g[i][j]].se] += d[g[i][j]];
            d[li[g[i][j]].fi] += d[g[i][j]];
        }
    }
    for( i = 1; i < n; i++ )pr( "%d ", ans[i] );
}


#include <bits/stdc++.h>
using namespace std;
#define  ll  long long int
#define max3(a, b, c) max(a, b) > max(b, c) ? max(a, b) : max(b, c)
#define min3(a, b, c) min(a, b) < min(b, c) ? min(a, b) : min(b, c)
#define digit(c) (c - '0')
#define pb push_back
#define mp make_pair
#define fi first+
#define se second
#define maxx 10000000000000000
#define all(X) X.begin(), X.end()
#define loop(i,n) for ( i=0; i<ll(n); i++ )
#define fr(i,x,y) for ( i=x; i<=y; i++ )
#define in(x) scanf("%I64d",&x);
#define in2(x,y) scanf("%I64d%I64d",&x,&y);

#define REP1(i,a,b) for ( ll i=(a); i<=ll(b); i++ )
#define FOR(it,c) for ( auto it=(c).begin(); it!=(c).end(); it++ )
#define mp make_pair
#define ex  exit(0)
#define LSOne(S) (S & (-S))
#define INF INT_MAX //Infinity
#define cont continue
#define nl cout<<endl
#define modd 1000000007
vector< pair<ll,ll> > ans;
list<ll> li[1000002];
vector<ll> v[1000002];
ll dp[1000002][50];
ll lev[1000002];
ll dest[1000002];
ll source[1000002];
map<ll, map<ll,ll> > mom;
ll vis[1000003];
ll dfs2(ll a)
{
    vis[a]=1;
    ll i,j,t,sum;
    sum=0;
    for(i=0;i<v[a].size();i++)
    {
        t=v[a][i];
        if(vis[t]==0)
        {
            j=dfs2(t);
            sum+=j;
            mom[t][a]+=j;
            mom[a][t]+=j;
        }
    }

    sum+=source[a]-dest[a];
    return sum;
}

ll dfs(ll start,ll par,ll le)
{

    lev[start]=le;
    list<ll>:: iterator it;
    for(it=li[start].begin(); it!=li[start].end(); it++)
    {
        if(*it!=par)
        {
            dp[*it][0]=start;
            lev[*it]=le+1;
            dfs(*it,start,le+1);
        }
    }
}

ll binary_rais(ll a,ll b)// return lca of a,b
{

    //  always we conseider that lev a> lev b so swap else
    if(lev[a]<lev[b]) swap(a,b);

    ll lg;

    /// maximum jump that can be alloweable to make both a and
    // b at same level  will be the depth of the node a
    for(lg=1; (1<<lg)<=lev[a]; lg++);

    //
    lg--;

    // this will make both at same level
    //  we can write any number as the power of 2
    //  so by binary raise we can reach to any node
    for(ll i=lg; i>=0; i--)
    {
        if(lev[a]-(1<<i)>=lev[b])
        {
            a=dp[a][i];//   moving a upward
        }
    }

    //  now a and b are at same level

    //now we always try to  to shift a and be at a poll just below the lca
    //  but if both a and b are in the same line than while shifing leven we reach
    //  both a and become same

    if(a==b) return a;

    else
    {
        for(ll i=lg; i>=0; i--)
        {
            if(dp[a][i]!=-1 && dp[a][i]!=dp[b][i])//  moving botha and b up
            {
                a=dp[a][i];
                b=dp[b][i];
            }
        }
        //  since we atmax shift a and b
        //  just below there lca
        //  lca will be the parent of a or parent of b

        return dp[a][0];
    }
}

int main()
{

ll m,n,i,j;
    cin>>n;
    m=n-1;

    for(i=1; i<=m; i++)
    {
        ll a,b;
        cin>>a>>b;
        li[a].push_back(b);
        li[b].push_back(a);
        ans.pb(mp(a,b));
        v[a].pb(b);
        v[b].pb(a);
    }

    memset(dp,-1,sizeof dp);
    //cout<<dp[1][200];
// we are consedering 1 as the root of all nodes
// so its parent is non so its pow(2,0) the parent is 0;

    dp[1][0]=0;
    dfs(1,-1,1);

    ll max_h=30;//  or lon(n)
    //  maximum height
    for(i=1; i<=max_h; i++)
    {
        for(j=1; j<=n; j++)
        {
            if(dp[j][i-1]!=-1)
                dp[j][i]=dp[dp[j][i-1]][i-1];//
        }
    }

    ll q,t;
    cin>>q;
    while(q--)
    {
        ll a,b;
        cin>>a>>b;
        if(lev[a]>lev[b])
          swap(a,b);
        t=binary_rais(a,b);
        if(t==a)
        {
            dest[a]++;
            source[b]++;
        }
        else
        {
            dest[t]+=2;
            source[a]++;
            source[b]++;
        }
    }

    dfs2(1);

    for(i=0;i<ans.size();i++)
    {
        ll a,b;
        a=ans[i].first;
        b=ans[i].second;
        cout<<mom[a][b]<<endl;
    }
}


#include <bits/stdc++.h>
using namespace std;
#define  ll  long long int
#define max3(a, b, c) max(a, b) > max(b, c) ? max(a, b) : max(b, c)
#define min3(a, b, c) min(a, b) < min(b, c) ? min(a, b) : min(b, c)
#define digit(c) (c - '0')
#define pb push_back
#define mp make_pair
#define fi first+
#define se second
#define maxx 10000000000000000
#define all(X) X.begin(), X.end()
#define loop(i,n) for ( i=0; i<ll(n); i++ )
#define fr(i,x,y) for ( i=x; i<=y; i++ )
#define in(x) scanf("%I64d",&x);
#define in2(x,y) scanf("%I64d%I64d",&x,&y);

#define REP1(i,a,b) for ( ll i=(a); i<=ll(b); i++ )
#define FOR(it,c) for ( auto it=(c).begin(); it!=(c).end(); it++ )
#define mp make_pair
#define ex  exit(0)
#define LSOne(S) (S & (-S))
#define INF INT_MAX //Infinity
#define cont continue
#define nl cout<<endl
#define modd 1000000007
vector< pair<ll,ll> > ans;
list<ll> li[100002];
vector<ll> v[100002];
ll dp[100002][50];
ll lev[100002];
ll dest[100002];
ll source[100002];
map<ll, map<ll,ll> > mom;
ll vis[100002];
ll dfs2(ll a)
{
    vis[a]=1;
    ll i,j,t,sum;
    sum=0;
    for(i=0;i<v[a].size();i++)
    {
        t=v[a][i];
        if(vis[t]==0)
        {
            j=dfs2(t);
            sum+=j;
            mom[t][a]+=j;
            mom[a][t]+=j;
        }
    }

    sum+=source[a]-dest[a];
    return sum;
}

ll dfs(ll start,ll par,ll le)
{

    lev[start]=le;
    list<ll>:: iterator it;
    for(it=li[start].begin(); it!=li[start].end(); it++)
    {
        if(*it!=par)
        {
            dp[*it][0]=start;
            lev[*it]=le+1;
            dfs(*it,start,le+1);
        }
    }
}

ll binary_rais(ll a,ll b)// return lca of a,b
{

    //  always we conseider that lev a> lev b so swap else
    if(lev[a]<lev[b]) swap(a,b);

    ll lg;

    /// maximum jump that can be alloweable to make both a and
    // b at same level  will be the depth of the node a
    for(lg=1; (1<<lg)<=lev[a]; lg++);

    //
    lg--;

    // this will make both at same level
    //  we can write any number as the power of 2
    //  so by binary raise we can reach to any node
    for(ll i=lg; i>=0; i--)
    {
        if(lev[a]-(1<<i)>=lev[b])
        {
            a=dp[a][i];//   moving a upward
        }
    }

    //  now a and b are at same level

    //now we always try to  to shift a and be at a poll just below the lca
    //  but if both a and b are in the same line than while shifing leven we reach
    //  both a and become same

    if(a==b) return a;

    else
    {
        for(ll i=lg; i>=0; i--)
        {
            if(dp[a][i]!=-1 && dp[a][i]!=dp[b][i])//  moving botha and b up
            {
                a=dp[a][i];
                b=dp[b][i];
            }
        }
        //  since we atmax shift a and b
        //  just below there lca
        //  lca will be the parent of a or parent of b

        return dp[a][0];
    }
}

int main()
{

ll m,n,i,j;
    cin>>n;
    m=n-1;

    for(i=1; i<=m; i++)
    {
        ll a,b;
        cin>>a>>b;
        li[a].push_back(b);
        li[b].push_back(a);
        ans.pb(mp(a,b));
        v[a].pb(b);
        v[b].pb(a);
    }

    memset(dp,-1,sizeof dp);
    //cout<<dp[1][200];
// we are consedering 1 as the root of all nodes
// so its parent is non so its pow(2,0) the parent is 0;

    dp[1][0]=0;
    dfs(1,-1,1);

    ll max_h=30;//  or lon(n)
    //  maximum height
    for(i=1; i<=max_h; i++)
    {
        for(j=1; j<=n; j++)
        {
            if(dp[j][i-1]!=-1)
                dp[j][i]=dp[dp[j][i-1]][i-1];//
        }
    }

    ll q,t;
    cin>>q;
    while(q--)
    {
        ll a,b;
        cin>>a>>b;
        if(lev[a]>lev[b])
          swap(a,b);
        t=binary_rais(a,b);
        if(t==a)
        {
            dest[a]++;
            source[b]++;
        }
        else
        {
            dest[t]+=2;
            source[a]++;
            source[b]++;
        }
    }

    dfs2(1);

    for(i=0;i<ans.size();i++)
    {
        ll a,b;
        a=ans[i].first;
        b=ans[i].second;
        cout<<mom[a][b]<<endl;
    }
}


#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

const int N = 100 * 1000 + 10;
vector <int> graph[N];
vector <int> p[N];
int dp[20][N], lg, h[N], par[N], num[N], ans[N];
bool mark[N];

void dfs(int v)
{
	mark[v] = true;
	for (int i = 0; i < (int) graph[v].size(); i++)
	{
		int u = graph[v][i];
		if (!mark[u])
		{
			par[u] = v;
			h[u] = h[v] + 1;
			dfs(u);
		}
	}
}

int get_par(int v, int k)
{
	for (int i = lg; i >= 0; i--)
		if (k >= (1 << i))
		{
			v = dp[i][v];
			k -= (1 << i);
		}
	return v;
}

int lca(int v, int u)
{
	if (h[v] < h[u])
		swap(v, u);
	v = get_par(v, h[v] - h[u]);
	if (v == u)
		return v;
	for (int i = 18; i >= 0; i--)
	{
		if (dp[i][v] != dp[i][u])
		{
			v = dp[i][v];
			u = dp[i][u];
		}
	}
	return dp[0][v];
}

void dfs2(int v, int e)
{
	mark[v] = true;
	if (e != -1)
		ans[e] += num[v];
	for (int i = 0; i < (int) graph[v].size(); i++)
	{
		int u = graph[v][i];
		if (!mark[u])
		{
			dfs2(u, p[v][i]);
			if (e != -1)
				ans[e] += num[u];
		}
	}
}

int main()
{
	int n;
	cin >> n;
	lg = log2(n) + 1;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		graph[a].push_back(b);
		p[a].push_back(i);
		graph[b].push_back(a);
		p[b].push_back(i);
	}
	dfs(0);
	dp[0][0] = 0;
	for (int i = 1; i < n; i++)
		dp[0][i] = par[i];
	for (int i = 1; i < lg; i++)
		for (int j = 0; j < n; j++)
			dp[i][j] = dp[i - 1][dp[i - 1][j]];
	int q;
	cin >> q;
	for (int i = 0; i < q; i++)
	{
		int v, u;
		cin >> v >> u;
		v--;
		u--;
		num[lca(v, u)] -= 2;
		num[u]++;
		num[v]++;
	}
	for (int i = 0; i < n; i++)
		mark[i] = false;
	dfs2(0, -1);
	for (int i = 0; i < n - 1; i++)
		cout << ans[i] << " ";
	cout << endl;
	return 0;
}


#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

const int N = 100 * 1000 + 10;
vector <int> graph[N];
vector <int> p[N];
int dp[20][N], lg, h[N], num[N], ans[N];
bool mark[N];

void dfs(int v)
{
	mark[v] = true;
	for (int i = 0; i < (int) graph[v].size(); i++)
	{
		int u = graph[v][i];
		if (!mark[u])
		{
			dp[0][u] = v;
			h[u] = h[v] + 1;
			dfs(u);
		}
	}
}

int get_par(int v, int k)
{
	for (int i = lg; i >= 0; i--)
		if (k & (1 << i))
			v = dp[i][v];
	return v;
}

int lca(int v, int u)
{
	if (h[v] < h[u])
		swap(v, u);
	v = get_par(v, h[v] - h[u]);
	if (v == u)
		return v;
	for (int i = 18; i >= 0; i--)
	{
		if (dp[i][v] != dp[i][u])
		{
			v = dp[i][v];
			u = dp[i][u];
		}
	}
	return dp[0][v];
}

void dfs2(int v, int e)
{
	mark[v] = true;
	if (e != -1)
		ans[e] += num[v];
	for (int i = 0; i < (int) graph[v].size(); i++)
	{
		int u = graph[v][i];
		if (!mark[u])
		{
			dfs2(u, p[v][i]);
			if (e != -1)
				ans[e] += ans[p[v][i]];
		}
	}
}

int main()
{
	int n;
	cin >> n;
	lg = log2(n) + 1;
	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		graph[a].push_back(b);
		p[a].push_back(i);
		graph[b].push_back(a);
		p[b].push_back(i);
	}
	dfs(0);
	dp[0][0] = 0;
	for (int i = 1; i < lg; i++)
		for (int j = 0; j < n; j++)
			dp[i][j] = dp[i - 1][dp[i - 1][j]];
	int q;
	cin >> q;
	for (int i = 0; i < q; i++)
	{
		int v, u;
		cin >> v >> u;
		v--;
		u--;
		num[lca(v, u)] -= 2;
		num[u]++;
		num[v]++;
	}
	for (int i = 0; i < n; i++)
		mark[i] = false;
	dfs2(0, -1);
	for (int i = 0; i < n - 1; i++)
		cout << ans[i] << " ";
	cout << endl;
	return 0;
}