#include <bits/stdc++.h>

using namespace std;
int a[100], b[100];
int na, nb;

int maxp(int i, int j) {
    if (i >= na || j >= nb) return 0;
    if (abs(a[i] - b[j]) <= 1) {
        ++i;
        ++j;
        return 1 + maxp(i, j);
    } else {
        if (a[i] < b[j]) return maxp(i + 1, j);
        return maxp(i, j + 1);
    }
}

int main() {
    cin >> na;
    for (int i = 0; i < na; ++i) {
        cin >> a[i];
    }
    cin >> nb;
    for (int i = 0; i < nb; ++i) {
        cin >> b[i];
    }
    sort(a, a + na);
    sort(b, b + nb);
    int ans = maxp(0, 0);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int a[100], b[100];
int na, nb;

int maxp(int i, int j) {
    if (i >= na || j >= nb) return 0;
    if (abs(a[i] - b[j]) >= 1) {
        ++i;
        ++j;
        return 1 + maxp(i, j);
    } else {
        if (a[i] < b[j]) return maxp(i + 1, j);
        return maxp(i, j + 1);
    }
}

int main() {
    cin >> na;
    for (int i = 0; i < na; ++i) {
        cin >> a[i];
    }
    cin >> nb;
    for (int i = 0; i < nb; ++i) {
        cin >> b[i];
    }
    sort(a, a + na);
    sort(b, b + nb);
    int ans = maxp(0, 0);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int a[100], b[100];
int na, nb;

int maxp(int i, int j) {
    if (i >= na || j >= nb) return 0;
    if (abs(a[i] - b[j]) >= 1) {
        ++i;
        ++j;
        return 1 + maxp(i, j);
    } else {
        if (a[i] < a[j]) return maxp(i + 1, j);
        return maxp(i, j + 1);
    }
}

int main() {
    cin >> na;
    for (int i = 0; i < na; ++i) {
        cin >> a[i];
    }
    cin >> nb;
    for (int i = 0; i < nb; ++i) {
        cin >> b[i];
    }
    sort(a, a + na);
    sort(b, b + nb);
    int ans = maxp(0, 0);
    cout << ans << "\n";
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

typedef long long LL;

int n, m;
int boy[101];
int grl[101];
int tbl[101][101][101][101];

int dyn(int x, int y, int a, int b) {
  int &r = tbl[x][y][a][b];
  if (r == -1) {

    if (!a || !b || !x || !y) return r = 0;

    int r1 = -1;
    if (abs(boy[x] - grl[y]) <= 1) {
      r1 = dyn(x - 1, y - 1, a - 1, b - 1) + 1;
    }

    int r2 = dyn(x - 1, y, a - 1, b);
    int r3 = dyn(x, y - 1, a, b - 1);
    int r4 = max(r2, r3);
    r = max(r1, r4);
  }
  return r;
}

int main() {
  ios_base::sync_with_stdio(0);
  cin >> n;
  for (int i = 1; i <= n; ++i) cin >> boy[i];
  cin >> m;
  for (int i = 1; i <= m; ++i) cin >> grl[i];
  sort(boy + 1, boy + n + 1);
  sort(grl + 1, grl + m + 1);

  memset(tbl, -1, sizeof tbl);
  cout << dyn(n, m, n, m) << endl;

  return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<ctime>

using namespace std;

template <typename T>

inline T read()
{
	T x=0,f=1;char c=getchar();
	while(!isdigit(c))
	{if(c=='-') f=-f;c=getchar();}
	while(isdigit(c))
	{x=(x<<3)+(x<<1)+(c-48);c=getchar();}
	return x*f;
}

#define lint long long int
#define ulint unsigned lint

const int inf=1e9+1e7;
const int MAXN=5e3+1e2;

struct node{
	int nxt,to;
};

struct dott{
	int u,v,w;
};

dott ask[MAXN];
dott ASK[MAXN];
node edge[MAXN<<1];
int Map[MAXN][MAXN];
int head[MAXN];
int hson[MAXN];
int dep[MAXN];
int stk[MAXN];
int son[MAXN];
int fa[MAXN];
int Fa[MAXN];

int n,m,s,tot=1,pos=0,cnt=0;

bool flag;

void addedge(int u,int v)
{

	edge[++tot]=(node){head[u],v};
	head[u]=tot;

	return;

}

int dfs1(int u,int depth)
{

	dep[u]=depth;
	son[u]=1;

	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(fa[u]==v) continue;
		else fa[v]=u;
		son[u]+=dfs1(v,depth+1);
		if(hson[u]==-1||son[v]>son[hson[u]])
			hson[u]=v;
	}

	return son[u];

}

void dfs2(int u)
{

	stk[++pos]=u;

	if(hson[u]==-1)
	{
		while(pos) Fa[stk[pos--]]=stk[1];
		return;
	}

	dfs2(hson[u]);

	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(v!=hson[u]&&v!=fa[u])
			dfs2(v);
	}

	return;

}

int lca(int u,int v)
{

	while(Fa[u]!=Fa[v])
	{
		if(dep[Fa[u]]>dep[Fa[v]])
			u=fa[Fa[u]];
		else v=fa[Fa[v]];
	}

	if(dep[u]>dep[v])  return v;
	else return u;

}

void dfs3(int u,int w,int v)
{

	Map[u][fa[u]]=Map[fa[u]][u]=max(Map[u][fa[u]],w);

	if(u!=v) dfs3(fa[u],w,v);

	return;

}

void dfs4(int u,int w,int v)
{

	if(Map[u][fa[u]]==w) flag=true;

	if(flag) return;

	if(u!=v) dfs4(fa[u],w,v);

	return;

}

int main(void)
{

	// freopen("testdata.in","r",stdin);
	// freopen("testdata.out","w",stdout);

	memset(hson,-1,sizeof(hson));

	scanf("%d",&n);

	s=1;

	for(int i=1,u,v;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		ASK[i]=(dott){u,v,0};
		addedge(u,v);
		addedge(v,u);
	}

	fa[s]=s;

	dfs1(s,1);

	dfs2(s);

	scanf("%d\n",&m);

	for(int i=1;i<=m;i++)
	{
		int u=read<int>();
		int v=read<int>();
		int w=read<int>();
		ask[i]=(dott){u,v,w};
		int LCA=lca(u,v);
		dfs3(u,w,LCA);
		dfs3(v,w,LCA);
	}

	bool vis=false;

	for(int i=1;i<=m;i++)
	{
		int u=ask[i].u;
		int v=ask[i].v;
		int w=ask[i].w;
		int LCA=lca(u,v);
		flag=false;
		dfs4(u,w,LCA);
		dfs4(v,w,LCA);
		if(!flag){puts("-1");vis=true;break;}
	}

	if(!vis)
	{
		for(int i=1;i<n;i++)
		if(Map[ASK[i].u][ASK[i].v]==0) printf("1 ");
		else printf("%d ",Map[ASK[i].u][ASK[i].v]);
	}

	return 0;

}


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<ctime>

using namespace std;

template <typename T>

inline T read()
{
	T x=0,f=1;char c=getchar();
	while(!isdigit(c))
	{if(c=='-') f=-f;c=getchar();}
	while(isdigit(c))
	{x=(x<<3)+(x<<1)+(c-48);c=getchar();}
	return x*f;
}

#define lint long long int
#define ulint unsigned lint

const int inf=1e9+1e7;
const int MAXN=5e3+1e2;

struct node{
	int nxt,to;
};

struct dott{
	int u,v,w;
};

dott ask[MAXN];
dott ASK[MAXN];
node edge[MAXN<<1];
int Map[MAXN][MAXN];
int head[MAXN];
int hson[MAXN];
int dep[MAXN];
int stk[MAXN];
int son[MAXN];
int fa[MAXN];
int Fa[MAXN];

int n,m,s,tot=1,pos=0,cnt=0;

bool flag;

void addedge(int u,int v)
{

	edge[++tot]=(node){head[u],v};
	head[u]=tot;

	return;

}

int dfs1(int u,int depth)
{

	dep[u]=depth;
	son[u]=1;

	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(fa[u]==v) continue;
		else fa[v]=u;
		son[u]+=dfs1(v,depth+1);
		if(hson[u]==-1||son[v]>son[hson[u]])
			hson[u]=v;
	}

	return son[u];

}

void dfs2(int u)
{

	stk[++pos]=u;

	if(hson[u]==-1)
	{
		while(pos) Fa[stk[pos--]]=stk[1];
		return;
	}

	dfs2(hson[u]);

	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(v!=hson[u]&&v!=fa[u])
			dfs2(v);
	}

	return;

}

int lca(int u,int v)
{

	while(Fa[u]!=Fa[v])
	{
		if(dep[Fa[u]]>dep[Fa[v]])
			u=fa[Fa[u]];
		else v=fa[Fa[v]];
	}

	if(dep[u]>dep[v])  return v;
	else return u;

}

void dfs3(int u,int w,int v)
{

	if(u!=v) Map[u][fa[u]]=Map[fa[u]][u]=max(Map[u][fa[u]],w);

	if(u!=v) dfs3(fa[u],w,v);

	return;

}

void dfs4(int u,int w,int v)
{

	if(Map[u][fa[u]]==w) flag=true;

	if(flag) return;

	if(u!=v) dfs4(fa[u],w,v);

	return;

}

int main(void)
{

	// freopen("testdata.in","r",stdin);
	// freopen("testdata.out","w",stdout);

	memset(hson,-1,sizeof(hson));

	scanf("%d",&n);

	s=1;

	for(int i=1,u,v;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		ASK[i]=(dott){u,v,0};
		addedge(u,v);
		addedge(v,u);
	}

	fa[s]=s;

	dfs1(s,1);

	dfs2(s);

	scanf("%d",&m);

	for(int i=1;i<=m;i++)
	{
		int u=read<int>();
		int v=read<int>();
		int w=read<int>();
		ask[i]=(dott){u,v,w};
		int LCA=lca(u,v);
		dfs3(u,w,LCA);
		dfs3(v,w,LCA);
	}

	bool vis=false;

	for(int i=1;i<=m;i++)
	{
		int u=ask[i].u;
		int v=ask[i].v;
		int w=ask[i].w;
		int LCA=lca(u,v);
		flag=false;
		dfs4(u,w,LCA);
		dfs4(v,w,LCA);
		if(!flag){puts("-1");vis=true;break;}
	}

	if(!vis)
	{
		for(int i=1;i<n;i++)
		if(Map[ASK[i].u][ASK[i].v]==0) printf("1 ");
		else printf("%d ",Map[ASK[i].u][ASK[i].v]);
	}

	return 0;

}


#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<ctime>

using namespace std;

template <typename T>

inline T read()
{
	T x=0,f=1;char c=getchar();
	while(!isdigit(c))
	{if(c=='-') f=-f;c=getchar();}
	while(isdigit(c))
	{x=(x<<3)+(x<<1)+(c-48);c=getchar();}
	return x*f;
}

#define lint long long int
#define ulint unsigned lint

const int inf=1e9+1e7;
const int MAXN=5e3+1e2;

struct node{
	int nxt,to;
};

struct dott{
	int u,v,w;
};

dott ask[MAXN];
dott ASK[MAXN];
node edge[MAXN<<1];
int Map[MAXN][MAXN];
int head[MAXN];
int hson[MAXN];
int dep[MAXN];
int stk[MAXN];
int son[MAXN];
int fa[MAXN];
int Fa[MAXN];

int n,m,s,tot=1,pos=0,cnt=0;

bool flag;

void addedge(int u,int v)
{

	edge[++tot]=(node){head[u],v};
	head[u]=tot;

	return;

}

int dfs1(int u,int depth)
{

	dep[u]=depth;
	son[u]=1;

	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(fa[u]==v) continue;
		else fa[v]=u;
		son[u]+=dfs1(v,depth+1);
		if(hson[u]==-1||son[v]>son[hson[u]])
			hson[u]=v;
	}

	return son[u];

}

void dfs2(int u)
{

	stk[++pos]=u;

	if(hson[u]==-1)
	{
		while(pos) Fa[stk[pos--]]=stk[1];
		return;
	}

	dfs2(hson[u]);

	for(int i=head[u];i;i=edge[i].nxt)
	{
		int v=edge[i].to;
		if(v!=hson[u]&&v!=fa[u])
			dfs2(v);
	}

	return;

}

int lca(int u,int v)
{

	while(Fa[u]!=Fa[v])
	{
		if(dep[Fa[u]]>dep[Fa[v]])
			u=fa[Fa[u]];
		else v=fa[Fa[v]];
	}

	if(dep[u]>dep[v])  return v;
	else return u;

}

void dfs3(int u,int w,int v)
{

	Map[u][fa[u]]=Map[fa[u]][u]=max(Map[u][fa[u]],w);

	if(u!=v) dfs3(fa[u],w,v);

	return;

}

void dfs4(int u,int w,int v)
{

	if(Map[u][fa[u]]==w) flag=true;

	if(flag) return;

	if(u!=v) dfs4(fa[u],w,v);

	return;

}

int main(void)
{

	// freopen("testdata.in","r",stdin);
	// freopen("testdata.out","w",stdout);

	memset(hson,-1,sizeof(hson));

	scanf("%d",&n);

	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			Map[i][j]=inf;

	s=1;

	for(int i=1,u,v;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		ASK[i]=(dott){u,v,0};
		addedge(u,v);
		addedge(v,u);
	}

	fa[s]=s;

	dfs1(s,1);

	dfs2(s);

	scanf("%d\n",&m);

	for(int i=1;i<=m;i++)
	{
		int u=read<int>();
		int v=read<int>();
		int w=read<int>();
		ask[i]=(dott){u,v,w};
		int LCA=lca(u,v);
		dfs3(u,w,LCA);
		dfs3(v,w,LCA);
	}

	bool vis=false;

	for(int i=1;i<=m;i++)
	{
		int u=ask[i].u;
		int v=ask[i].v;
		int w=ask[i].w;
		int LCA=lca(u,v);
		flag=false;
		dfs4(u,w,LCA);
		dfs4(v,w,LCA);
		if(!flag){puts("-1");vis=true;break;}
	}

	if(!vis) for(int i=1;i<n;i++) printf("%d ",Map[ASK[i].u][ASK[i].v]);

	return 0;

}


#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fst first
#define snd second
using namespace std;

typedef long long ll;
typedef double db;
typedef long double ldb;

const int inf=1e9+10;
const int maxn=5e3+10;

int n,m,vl[maxn];
vector <pair<int,int> > g[maxn];
vector <int> v[maxn],t[maxn];
int a[maxn],b[maxn],c[maxn];

bool dfs(int x,int fa,int ed,int val,int id){
	if(x==ed) return true;
	for(int i=0;i<g[x].size();i++){
		if(g[x][i].fst==fa) continue;
		if(dfs(g[x][i].fst,x,ed,val,id)){
			v[g[x][i].snd].pb(val);
			t[id].pb(g[x][i].snd);
			return true;
		}
	}
	return false;
}

int main(){
	cin>>n;
	for(int i=0;i<n-1;i++){
		int u,v;
		cin>>u>>v;
		u--; v--;
		g[u].pb(mp(v,i));
		g[v].pb(mp(u,i));
	}
	cin>>m;
	for(int i=0;i<m;i++){
		cin>>a[i]>>b[i]>>c[i];
		a[i]--; b[i]--;
		dfs(a[i],-1,b[i],c[i],i);
	}
	for(int i=0;i<n-1;i++){
		for(int j=0;j<v[i].size();j++)
			vl[i]=max(v[i][j],vl[i]);
		if(v[i].size()==0) vl[i]=1;
	}
	for(int i=0;i<m;i++){
		int mn=1e6;
		for(int j=0;j<t[i].size();j++){
			mn=min(vl[t[i][j]],mn);
		}
		if(mn!=c[i]){
			printf("-1\n");
			return 0;
		}
	}
	for(int i=0;i<n-1;i++) printf("%d ",vl[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5e3+100;
vector<pair<int,int> >G[N];
vector<int>pat[N],val[N];
int ans[N];
bool dfs(int st,int ed,int fa,int vv,int id)
{
	if(st==ed) return 1;
	for(int i=0;i<G[st].size();i++)
	{
		int v=G[st][i].first,idx=G[st][i].second;
		if(v==fa) continue;
		if(dfs(v,ed,st,vv,id))
		{
			val[idx].push_back(vv); //经过这条路的值
			pat[id].push_back(idx);//每条路经过的边
			return 1;
		}
	}
	return 0;
}
int w[N];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		G[x].push_back(make_pair(y,i));
		G[y].push_back(make_pair(x,i));
	}
	int m;
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y;
		cin>>x>>y>>w[i];
		dfs(x,y,-1,w[i],i);
	}
	for(int i=1;i<n;i++)
	{
		if(val[i].size())
		for(int j=0;j<val[i].size();j++)
		ans[i]=max(ans[i],val[i][j]);
		else ans[i]=1;
	}
	cout<<pat[1].size()<<endl;
	for(int i=1;i<=m;i++)
	{
		int mn=1e9;
		for(int j=0;j<pat[i].size();j++)
		 mn=min(mn,ans[pat[i][j]]);
		if(mn!=w[i])
		{
			puts("-1");
			return 0;
		}
	}
	for(int i=1;i<n;i++)
	 cout<<ans[i]<<' ';
	cout<<endl;
	return 0;
}


#include <bits/stdc++.h>

constexpr int maxn = 5e3 + 5;

std::vector<std::pair<int,int> > G[maxn];
std::vector<std::tuple<int,int,int> > edge;
int Fa[maxn],dep[maxn],id[maxn],col[maxn],res[maxn],n,m;

void dfs(int u,int fa)
{
	dep[u]=dep[fa]+1;Fa[u]=fa;
	for(auto &it:G[u])
	{
		if(it.first==fa)continue;
		id[it.first]=it.second;
		dfs(it.first,u);
	}
}

int main()
{
#ifdef LOCAL
	freopen("input.in","r",stdin);
#endif
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
		int u,v;scanf("%d%d",&u,&v);
		G[u].emplace_back(v,i);
		G[v].emplace_back(u,i);
	}
	dfs(1,0);
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		int u,v,w;scanf("%d%d%d",&u,&v,&w);
		edge.emplace_back(w,u,v);
	}
	//sort(edge.begin(),edge.end());
	for(auto &it:edge)
	{
		int u,v,w;std::tie(w,u,v)=it;
		while(u!=v)
		{
			if(dep[u]<dep[v]) std::swap(u,v);
			col[u]=std::max(col[u],w);
			u=Fa[u];
		}
	}
	for(auto &it:edge)
	{
		int tmp=1e9;int u,v,w;std::tie(w,u,v)=it;
		while(u!=v)
		{
			if(dep[u]<dep[v]) std::swap(u,v);
			tmp=std::min(tmp,col[u]);
			u=Fa[u];
		}
		if(tmp!=w) puts("-1"),exit(0);
	}
	for(int i=2;i<=n;i++)
		if(col[i]) res[id[i]]=col[i];
		else res[id[i]]=1e6;
	for(int i=2;i<=n;i++) printf("%d ",res[i]);
	return 0;
}


#include <bits/stdc++.h>

constexpr int maxn = 5e3 + 5;

std::vector<std::pair<int,int> > G[maxn];
std::vector<std::tuple<int,int,int> > edge;
int Fa[maxn],dep[maxn],id[maxn],col[maxn],res[maxn],n,m;

void dfs(int u,int fa)
{
	dep[u]=dep[fa]+1;Fa[u]=fa;
	for(auto &it:G[u])
	{
		if(it.first==fa)continue;
		id[it.first]=it.second;
		dfs(it.first,u);
	}
}

int main()
{
#ifdef LOCAL
	freopen("input.in","r",stdin);
#endif
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
		int u,v;scanf("%d%d",&u,&v);
		G[u].emplace_back(v,i);
		G[v].emplace_back(u,i);
	}
	dfs(1,0);
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		int u,v,w;scanf("%d%d%d",&u,&v,&w);
		edge.emplace_back(w,u,v);
	}
	sort(edge.begin(),edge.end());
	for(auto &it:edge)
	{
		int u,v,w;std::tie(w,u,v)=it;
		while(u!=v)
		{
			if(dep[u]<dep[v]) std::swap(u,v);
			col[u]=max(col[u],w);
			u=Fa[u];
		}
	}
	for(auto &it:edge)
	{
		int tmp=1e9;int u,v,w;std::tie(w,u,v)=it;
		while(u!=v)
		{
			if(dep[u]<dep[v]) std::swap(u,v);
			tmp=std::min(tmp,col[u]);
			u=Fa[u];
		}
		if(tmp!=w) puts("-1"),exit(0);
	}
	for(int i=2;i<=n;i++)
		if(col[i]) res[id[i]]=col[i];
		else res[id[i]]=1e6;
	for(int i=2;i<=n;i++) printf("%d ",res[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5e3+100;
vector<pair<int,int> >G[N];
vector<int>pat[N],val[N];
int ans[N];
bool dfs(int st,int ed,int fa,int vv,int id)
{
	if(st==ed) return 1;
	for(int i=0;i<G[st].size();i++)
	{
		int v=G[st][i].first,idx=G[st][i].second;
		if(v==fa) continue;
		if(dfs(v,ed,st,vv,id))
		{
			val[idx].push_back(vv); //经过这条路的值
			pat[id].push_back(idx);//每条路经过的边
			return 1;
		}
	}
	return 0;
}
int w[N];
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		G[x].push_back(make_pair(y,i));
		G[y].push_back(make_pair(x,i));
	}
	int m;
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y;
		cin>>x>>y>>w[i];
		dfs(x,y,-1,w[i],i);
	}
	for(int i=1;i<n;i++)
	{
		if(val[i].size())
		for(int j=0;j<val[i].size();j++)
		ans[i]=max(ans[i],val[i][j]);
		else ans[i]=1;
	}
	for(int i=1;i<=m;i++)
	{
		int mn=1e9;
		for(int j=0;j<pat[i].size();j++)
		 mn=min(mn,ans[pat[i][j]]);
		if(mn!=w[i])
		{
			puts("-1");
			return 0;
		}
	}
	for(int i=1;i<n;i++)
	 cout<<ans[i]<<' ';
	cout<<endl;
	return 0;
}


#include <bits/stdc++.h>

constexpr int maxn = 5e3 + 5;

std::vector<std::pair<int,int> > G[maxn];
std::vector<std::tuple<int,int,int> > edge;
int Fa[maxn],dep[maxn],id[maxn],col[maxn],res[maxn],n,m;

void dfs(int u,int fa)
{
	dep[u]=dep[fa]+1;Fa[u]=fa;
	for(auto &it:G[u])
	{
		if(it.first==fa)continue;
		id[it.first]=it.second;
		dfs(it.first,u);
	}
}

int main()
{
#ifdef LOCAL
	freopen("input.in","r",stdin);
#endif
	scanf("%d",&n);
	for(int i=2;i<=n;i++)
	{
		int u,v;scanf("%d%d",&u,&v);
		G[u].emplace_back(v,i);
		G[v].emplace_back(u,i);
	}
	dfs(1,0);
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		int u,v,w;scanf("%d%d%d",&u,&v,&w);
		edge.emplace_back(w,u,v);
	}
	sort(edge.begin(),edge.end());
	for(auto &it:edge)
	{
		int u,v,w;std::tie(w,u,v)=it;
		while(u!=v)
		{
			if(dep[u]<dep[v]) std::swap(u,v);
			col[u]=std::max(col[u],w);
			u=Fa[u];
		}
	}
	for(auto &it:edge)
	{
		int tmp=1e9;int u,v,w;std::tie(w,u,v)=it;
		while(u!=v)
		{
			if(dep[u]<dep[v]) std::swap(u,v);
			tmp=std::min(tmp,col[u]);
			u=Fa[u];
		}
		if(tmp!=w) puts("-1"),exit(0);
	}
	for(int i=2;i<=n;i++)
		if(col[i]) res[id[i]]=col[i];
		else res[id[i]]=1e6;
	for(int i=2;i<=n;i++) printf("%d ",res[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int INF=999999999;
struct Edge{
	int to,nxt;
}edge[10010];
int n,m,tot,root;
int head[5010];
int x[5010],y[5010],fa[5010][5010],ans[5010][5010];
int u[5010],v[5010],d[5010];
inline void addedge(int u,int v){
    edge[++tot].to=v,edge[tot].nxt=head[u],head[u]=tot;
}

inline void dfs(int u,int f){
    fa[root][u]=f;
    for(int i=head[u],v;i;i=edge[i].nxt){
        v=edge[i].to;
        if(v!=f)dfs(v,u);
    }
}

int main(){
	cout<<INF;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d %d",&x[i],&y[i]);
        addedge(x[i],y[i]),addedge(y[i],x[i]);
    }
    for(int i=1;i<=n;i++)root=i,dfs(i,0);
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%d %d %d",&u[i],&v[i],&d[i]);
        int a=u[i],b=v[i];
        int fb=fa[a][b];
        while(fb!=a){
            ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
            b=fb;
            fb=fa[a][fb];
        }
        ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
    }
    bool judge=1;
    for(int i=0;i<m&&judge;i++){
        int a=u[i],b=v[i];
        int fb=fa[a][b];
        int MIN=INF;
        while(fb!=a){
            MIN=min(ans[fb][b],MIN);
            b=fb;
            fb=fa[a][fb];
        }
        MIN=min(ans[fb][b],MIN);
        if(MIN!=d[i])
            judge=0;
    }
    if(judge){
        for(int i=1;i<n;i++){
            if(!ans[x[i]][y[i]])ans[x[i]][y[i]]=1;
            printf("%d ",ans[x[i]][y[i]]);
        }
    }
    else printf("-1\n");
    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <cmath>
#include <set>
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 1e6
#define pb push_back
using namespace std;
typedef long long ll;
typedef double db;
const int N=5e3+5;
struct node{int v,i;};
vector<node>tr[N];
int val[N],f[N],d[N],cnt[N],ans[N];
void dfs(int u,int fa)
{
    d[u]=d[fa]+1;
    f[u]=fa;
    for(int i=0;i<tr[u].size();i++)
    {
        int v=tr[u][i].v;
        if(v==fa) continue;
        dfs(v,u);
        cnt[v]=tr[u][i].i;
    }
    val[u]=INF;
}
bool work(int x,int y,int w)
{
    int minn=INF;
    if(d[x]<d[y]) swap(x,y);
    while(d[x]!=d[y])
    {
        if(val[x]==INF) val[x]=w;
        minn=min(minn,val[x]);
        x=f[x];
    }
    while(x!=y)
    {
        if(val[x]==INF) val[x]=w;
        minn=min(minn,val[x]);
        x=f[x];
        if(val[y]==INF) val[y]=w;
        minn=min(minn,val[y]);
        y=f[y];
    }
    return minn==w;
}
struct ask
{
    int a,b,w;
    bool operator < (const ask A) const
    {return w<A.w;}
};
priority_queue<ask>q;
int main()
{
    int n,m;
    cin>>n;
    for(int i=1,u,v;i<n;i++)
    {
        cin>>u>>v;
        tr[u].pb({v,i});
        tr[v].pb({u,i});
    }
    dfs(1,0);
    cin>>m;
    for(int i=0,a,b,w;i<m;i++)
    {
        cin>>a>>b>>w;
        q.push({a,b,w});
    }
    while(!q.empty())
    {
        ask tmp=q.top();
        q.pop();
        if(!work(tmp.a,tmp.b,tmp.w))
        {
            puts("-1");
            return 0;
        }
    }
    for(int i=2;i<=n;i++)
        ans[cnt[i]]=val[i];
    for(int i=1;i<n;i++)
        cout<<ans[i]<<" ";
    //system("pause");
}


#include<bits/stdc++.h>
using namespace std;
const int INF=1111111111;
struct Edge{
	int to,nxt;
}edge[10010];
int n,m,tot,root;
int head[5010];
int x[5010],y[5010],fa[5010][5010],ans[5010][5010];
int u[5010],v[5010],d[5010];
inline void addedge(int u,int v){
    edge[++tot].to=v,edge[tot].nxt=head[u],head[u]=tot;
}

inline void dfs(int u,int f){
    fa[root][u]=f;
    for(int i=head[u],v;i;i=edge[i].nxt){
        v=edge[i].to;
        if(v!=f)dfs(v,u);
    }
}

int main(){
	cout<<INF;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d %d",&x[i],&y[i]);
        addedge(x[i],y[i]),addedge(y[i],x[i]);
    }
    for(int i=1;i<=n;i++)root=i,dfs(i,0);
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%d %d %d",&u[i],&v[i],&d[i]);
        int a=u[i],b=v[i];
        int fb=fa[a][b];
        while(fb!=a){
            ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
            b=fb;
            fb=fa[a][fb];
        }
        ans[fb][b]=ans[b][fb]=max(ans[fb][b],d[i]);
    }
    bool judge=1;
    for(int i=0;i<m&&judge;i++){
        int a=u[i],b=v[i];
        int fb=fa[a][b];
        int MIN=INF;
        while(fb!=a){
            MIN=min(ans[fb][b],MIN);
            b=fb;
            fb=fa[a][fb];
        }
        MIN=min(ans[fb][b],MIN);
        if(MIN!=d[i])
            judge=0;
    }
    if(judge){
        for(int i=1;i<n;i++){
            if(!ans[x[i]][y[i]])ans[x[i]][y[i]]=1;
            printf("%d ",ans[x[i]][y[i]]);
        }
    }
    else printf("-1\n");
    return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>

using namespace std;
#define ll long long
#define pii pair<int, int>

const int MAXN = 5010;
const int MAXD = 13;
const int inf = 2e9 + 1e8;

int N, M;
vector<int> graph[MAXN];
int depth[MAXN], par[MAXN], lca[MAXN][MAXD];
int ans[MAXN];
map<pii, int> pos;
pair<pii, int> queries[MAXN];

void dfs(int cur, int p, int d) {
	depth[cur] = d;
	for (int node : graph[cur]) {
		if (node != p) {
			par[node] = cur;
			dfs(node, cur, d + 1);
		}
	}
	return;
}
void precomp() {
	par[0] = -1;
	dfs(0, -1, 0);
	for (int i = 0; i < MAXD; i++) {
		for (int j = 0; j < N; j++) {
			lca[j][i] = -1;
		}
	}
	for (int i = 0; i < N; i++) {
		lca[i][0] = par[i];
	}
	for (int i = 1; i < MAXD; i++) {
		for (int j = 0; j < N; j++) {
			if (lca[j][i - 1] != -1)
				lca[j][i] = lca[lca[j][i - 1]][i - 1];
		}
	}

	return;
}
int find_lca(int u, int v) {
	int x = u, y = v;
	if (depth[y] > depth[x]) {
		swap(x, y);
	}
	int dist = depth[x] - depth[y];
	while (dist > 0) {
		int incr = log2(dist);
		dist -= (1 << incr);
		x = lca[x][incr];
	}
	if (x == y)	return x;

	for (int i = MAXD - 1; i >= 0; i--) {
		if (lca[x][i] != lca[y][i]) {
			x = lca[x][i];
			y = lca[y][i];
		}
	}
	return par[x];
}

bool asc(pair<pii, int> i, pair<pii, int> j) {
	return i.second < j.second;
}

int main() {
	ios_base::sync_with_stdio(false);	cin.tie(false);
	cin >> N;
	for (int i = 0; i < N - 1; i++)	ans[i] = 1e6;
	for (int i = 0; i < N - 1; i++) {
		int a, b;	cin >> a >> b;
		a--;	b--;
		graph[a].push_back(b);
		graph[b].push_back(a);
		int mn = min(a, b), mx = max(a, b);
		pos[{mn, mx}] = i;
	}
	cin >> M;
	precomp();
	for (int i = 0; i < M; i++) {
		int a, b;	cin >> a >> b;
		a--;	b--;
		int v;	cin >> v;
		queries[i] = { {a, b}, v };
	}
	sort(queries, queries + M, asc);

	for (int i = 0; i < M; i++) {
		int a = queries[i].first.first, b = queries[i].first.second, v = queries[i].second;
		int lca = find_lca(a, b);
		int prev;
		prev = a;
		while (a != lca) {
			a = par[a];
			int mn = min(a, prev), mx = max(a, prev);
			ans[pos[{mn, mx}]] = v;
			prev = a;
		}
		prev = b;
		while (b != lca) {
			b = par[b];
			int mn = min(b, prev), mx = max(b, prev);
			ans[pos[{mn, mx}]] = v;
			prev = b;
		}
	}
	for (int i = 0; i < M; i++) {
		int a = queries[i].first.first, b = queries[i].first.second, v = queries[i].second;
		int lca = find_lca(a, b);
		int min_node = inf;
		int prev;
		prev = a;
		while (a != lca) {
			a = par[a];
			int mn = min(a, prev), mx = max(a, prev);
			min_node = min(min_node, ans[pos[{mn, mx}]]);
			prev = a;
		}
		prev = b;
		while (b != lca) {
			b = par[b];
			int mn = min(b, prev), mx = max(b, prev);
			min_node = min(min_node, ans[pos[{mn, mx}]]);
			prev = b;
		}
		if (min_node != v) {
			cout << "-1" << endl;
			return 0;
		}
	}
	for (int i = 0; i < N - 1; i++) {
		cout << ans[i] << ' ';
	}
	cout << endl;

	return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>

using namespace std;
#define ll long long
#define pii pair<int, int>

const int MAXN = 5010;
const int MAXD = 13;
const int inf = 2e9 + 1e8;

int N, M;
vector<int> graph[MAXN];
int depth[MAXN], par[MAXN], lca[MAXN][MAXD];
int ans[MAXN];
map<pii, int> pos;
pair<pii, int> queries[MAXN];

void dfs(int cur, int p, int d) {
	depth[cur] = d;
	for (int node : graph[cur]) {
		if (node != p) {
			par[node] = cur;
			dfs(node, cur, d + 1);
		}
	}
	return;
}
void precomp() {
	par[0] = -1;
	dfs(0, -1, 0);
	for (int i = 0; i < MAXD; i++) {
		for (int j = 0; j < N; j++) {
			lca[j][i] = -1;
		}
	}
	for (int i = 0; i < N; i++) {
		lca[i][0] = par[i];
	}
	for (int i = 1; i < MAXD; i++) {
		for (int j = 0; j < N; j++) {
			if (lca[j][i - 1] != -1)
				lca[j][i] = lca[lca[j][i - 1]][i - 1];
		}
	}

	return;
}
int find_lca(int u, int v) {
	int x = u, y = v;
	if (depth[y] > depth[x]) {
		swap(x, y);
	}
	int dist = depth[x] - depth[y];
	while (dist > 0) {
		int incr = log2(dist);
		dist -= (1 << incr);
		x = lca[x][incr];
	}
	if (x == y)	return x;

	for (int i = MAXD - 1; i >= 0; i--) {
		if (lca[x][i] != lca[y][i]) {
			x = lca[x][i];
			y = lca[y][i];
		}
	}
	return par[x];
}

bool asc(pair<pii, int> i, pair<pii, int> j) {
	return i.second < j.second;
}

int main() {
	ios_base::sync_with_stdio(false);	cin.tie(false);
	cin >> N;
	for (int i = 0; i < N - 1; i++)	ans[i] = 1e6;
	for (int i = 0; i < N - 1; i++) {
		int a, b;	cin >> a >> b;
		a--;	b--;
		graph[a].push_back(b);
		graph[b].push_back(a);
		pos[{a, b}] = i;
		pos[{b, a}] = i;
	}
	cin >> M;
	precomp();
	for (int i = 0; i < M; i++) {
		int a, b;	cin >> a >> b;
		a--;	b--;
		int v;	cin >> v;
		queries[i] = { {a, b}, v };
	}
	sort(queries, queries + M, asc);

	for (int i = 0; i < M; i++) {
		int a = queries[i].first.first, b = queries[i].first.second, v = queries[i].second;
		int lca = find_lca(a, b);
		int prev;
		prev = a;
		while (a != lca) {
			a = par[a];
			ans[pos[{prev, a}]] = v;
			prev = a;
		}
		prev = b;
		while (b != lca) {
			b = par[b];
			ans[pos[{prev, b}]] = v;
			prev = b;
		}
	}
	for (int i = 0; i < M; i++) {
		int a = queries[i].first.first, b = queries[i].first.second, v = queries[i].second;
		int lca = find_lca(a, b);
		int min_node = inf;
		int prev;
		prev = a;
		while (a != lca) {
			a = par[a];
			min_node = min(min_node, ans[pos[{prev, a}]]);
			prev = a;
		}
		prev = b;
		while (b != lca) {
			b = par[b];
			min_node = min(min_node, ans[pos[{prev, b}]]);
			prev = b;
		}
		if (min_node != v) {
			cout << "-1" << endl;
			return 0;
		}
	}
	for (int i = 0; i < N - 1; i++) {
		cout << ans[i] << ' ';
	}
	cout << endl;

	return 0;
}


#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>

using namespace std;
#define ll long long
#define pii pair<int, int>

const int MAXN = 5010;
const int MAXD = 13;
const int inf = 2e9 + 1e8;

int N, M;
vector<int> graph[MAXN];
int depth[MAXN], par[MAXN], lca[MAXN][MAXD];
int ans[MAXN];
int pos[MAXN*MAXN];
pair<pii, int> queries[MAXN];

void dfs(int cur, int p, int d) {
	depth[cur] = d;
	for (int node : graph[cur]) {
		if (node != p) {
			par[node] = cur;
			dfs(node, cur, d + 1);
		}
	}
	return;
}
void precomp() {
	par[0] = -1;
	dfs(0, -1, 0);
	for (int i = 0; i < MAXD; i++) {
		for (int j = 0; j < N; j++) {
			lca[j][i] = -1;
		}
	}
	for (int i = 0; i < N; i++) {
		lca[i][0] = par[i];
	}
	for (int i = 1; i < MAXD; i++) {
		for (int j = 0; j < N; j++) {
			if (lca[j][i - 1] != -1)
				lca[j][i] = lca[lca[j][i - 1]][i - 1];
		}
	}

	return;
}
int find_lca(int u, int v) {
	int x = u, y = v;
	if (depth[y] > depth[x]) {
		swap(x, y);
	}
	int dist = depth[x] - depth[y];
	while (dist > 0) {
		int incr = log2(dist);
		dist -= (1 << incr);
		x = lca[x][incr];
	}
	if (x == y)	return x;

	for (int i = MAXD - 1; i >= 0; i--) {
		if (lca[x][i] != lca[y][i]) {
			x = lca[x][i];
			y = lca[y][i];
		}
	}
	return par[x];
}

bool asc(pair<pii, int> i, pair<pii, int> j) {
	return i.second < j.second;
}

int main() {
	ios_base::sync_with_stdio(false);	cin.tie(false);
	cin >> N;
	for (int i = 0; i < N - 1; i++)	ans[i] = 1e6;
	int p = N - 1;
	for (int i = 0; i < N - 1; i++) {
		int a, b;	cin >> a >> b;
		a--;	b--;
		graph[a].push_back(b);
		graph[b].push_back(a);
		int mn = min(a, b), mx = max(a, b);
		pos[mn*p + mx] = i;
	}
	cin >> M;
	precomp();
	for (int i = 0; i < M; i++) {
		int a, b;	cin >> a >> b;
		a--;	b--;
		int v;	cin >> v;
		queries[i] = { {a, b}, v };
	}
	sort(queries, queries + M, asc);

	for (int i = 0; i < M; i++) {
		int a = queries[i].first.first, b = queries[i].first.second, v = queries[i].second;
		int lca = find_lca(a, b);
		int prev;
		prev = a;
		while (a != lca) {
			a = par[a];
			int mn = min(a, prev), mx = max(a, prev);
			ans[pos[mn*p + mx]] = v;
			prev = a;
		}
		prev = b;
		while (b != lca) {
			b = par[b];
			int mn = min(b, prev), mx = max(b, prev);
			ans[pos[mn*p + mx]] = v;
			prev = b;
		}
	}
	for (int i = 0; i < M; i++) {
		int a = queries[i].first.first, b = queries[i].first.second, v = queries[i].second;
		int lca = find_lca(a, b);
		int min_node = inf;
		int prev;
		prev = a;
		while (a != lca) {
			a = par[a];
			int mn = min(a, prev), mx = max(a, prev);
			min_node = min(min_node, ans[pos[mn*p + mx]]);
			prev = a;
		}
		prev = b;
		while (b != lca) {
			b = par[b];
			int mn = min(b, prev), mx = max(b, prev);
			min_node = min(min_node, ans[pos[mn*p + mx]]);
			prev = b;
		}
		if (min_node != v) {
			cout << "-1" << endl;
			return 0;
		}
	}
	for (int i = 0; i < N - 1; i++) {
		cout << ans[i] << ' ';
	}
	cout << endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int last[N*2],to[2*N],t[N],d[N],fa[N],v[N],id[N],si[N];
void dfs(int x)
{
	for (int i=t[x];i;i=last[i])
	if (to[i]!=fa[x])
	{
		fa[to[i]]=x;
		si[to[i]]=id[i];
		d[to[i]]=d[x]+1;
		dfs(to[i]);
	}
}
bool check(int x,int y,int z)
{
	bool flag=0;
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		if (v[si[x]]<z&&v[si[x]]!=0)
			return false;
		if (v[si[x]]==0||v[si[x]]==z)
		{
			flag=1;
			v[si[x]]=z;
		}
		x=fa[x];
	}
	while (x!=y)
	{
		if (v[si[x]]<z&&v[si[x]]!=0)
			return false;
		if (v[si[x]]==0||v[si[x]]==z)
		{
			flag=1;
			v[si[x]]=z;
		}
		if (v[si[y]]<z&&v[si[y]]!=0)
			return false;
		if (v[si[y]]==0||v[si[y]]==z)
		{
			flag=1;
			v[si[y]]=z;
		}
		x=fa[x]; y=fa[y];
	}
	if (flag==0)
		return false;
	else
		return true;
}
int main()
{
	int n,num=0,m;
	cin>>n;
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		last[++num]=t[x];
		t[x]=num;
		to[num]=y;
		id[num]=i;
		last[++num]=t[y];
		t[y]=num;
		to[num]=x;
		id[num]=i;
	}
	dfs(1);
	cin>>m;
	for (int i=0;i<m;i++)
	{
		int x,y,v;
		cin>>x>>y>>v;
		if (!check(x,y,v))
		{
			cout<<-1;
			return 0;
		}
	}
	for (int i=1;i<n;i++)
		cout<<v[i]<<" ";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5010,inf=0x3f3f3f3f;
int last[N*2],to[2*N],t[N],d[N],fa[N],v[N],id[N*2],si[N];
struct node
{
	int x,y,v;
}a[N];
void dfs(int x)
{
	for (int i=t[x];i;i=last[i])
	if (to[i]!=fa[x])
	{
		fa[to[i]]=x;
		si[to[i]]=id[i];
		d[to[i]]=d[x]+1;
		dfs(to[i]);
	}
}
void deal(int x,int y,int z)
{
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		v[si[x]]=max(v[si[x]],z);
		x=fa[x];
	}
	while (x!=y)
	{
		v[si[x]]=max(v[si[x]],z);
        v[si[y]]=max(v[si[y]],z);
		x=fa[x]; y=fa[y];
	}
}
bool check(int x,int y,int z)
{
	int Min=inf;
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		Min=min(Min,v[si[x]]);
		x=fa[x];
	}
	while (x!=y)
	{
		Min=min(v[si[x]],Min);
        Min=min(v[si[y]],Min);
		x=fa[x]; y=fa[y];
	}
	return Min==z;
}
int main()
{
	int n,num=0,m;
	cin>>n;
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		last[++num]=t[x];
		t[x]=num;
		to[num]=y;
		id[num]=i;
		last[++num]=t[y];
		t[y]=num;
		to[num]=x;
		id[num]=i;
	}
	dfs(1);
	cin>>m;
	for (int i=0;i<m;i++)
		cin>>a[i].x>>a[i].y>>a[i].v;
	for (int i=0;i<m;i++)
		deal(a[i].x,a[i].y,a[i].v);
	for (int i=0;i<m;i++)
		if (!check(a[i].x,a[i].y,a[i].v))
		{
			cout<<-1;
			return 0;
		}
	for (int i=1;i<n;i++)
		if (v[i]==0)
			cout<<1<<" ";
		else
			cout<<v[i]<<" ";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int f[5005],Min[5005],ans[5005][5005],x[5005],y[5005];
int find(int k)
{
	if (f[k]==k) return k;
	return f[k]=find(f[k]);
}
bool merge(int dx,int dy,int v)
{
	int fx=find(dx),fy=find(dy);
	if (fx!=fy)
	{
		Min[fy]=min(min(Min[fx],Min[fy]),v);
		f[fx]=fy;
	}
	else
		if (Min[fy]>v)
			return 0;
	ans[fx][fy]=Min[fy];
	ans[fy][fx]=Min[fy];
	return 1;
}
int main()
{
	int n,m;
	cin>>n;
	for (int i=0;i<n-1;i++)
	{
		cin>>x[i]>>y[i];
	}
	for (int i=1;i<=n;i++)
	{
		Min[i]=INT_MAX;
		f[i]=i;
	}
	cin>>m;
	for (int i=0;i<m;i++)
	{
		int dx,dy,v;
		cin>>dx>>dy>>v;
		if (!merge(dx,dy,v))
		{
			cout<<-1;
			return 0;
		}
	}
	for (int i=0;i<n-1;i++)
		cout<<ans[x[i]][y[i]]<<" ";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int f[5005],Min[5005],ans[5005][5005],x[5005],y[5005];
int find(int k)
{
	if (f[k]==k) return k;
	return f[k]=find(f[k]);
}
bool merge(int dx,int dy,int v)
{
	int fx=find(dx),fy=find(dy);
	if (fx!=fy)
	{
		Min[fy]=min(min(Min[fx],Min[fy]),v);
		f[fx]=fy;
	}
	else
		if (Min[fy]>v)
			return 0;
	ans[fx][fy]=Min[fy];
	ans[fy][fx]=Min[fy];
	return 1;
}
int main()
{
	int n,m;
	cin>>n;
	for (int i=0;i<n-1;i++)
	{
		cin>>x[i]>>y[i];
	}
	for (int i=1;i<=n;i++)
	{
		Min[i]=INT_MAX;
		f[i]=i;
	}
	cin>>m;
	for (int i=0;i<m;i++)
	{
		int dx,dy,v;
		cin>>dx>>dy>>v;
		if (!merge(dx,dy,v))
		{
			cout<<-1;
			return 0;
		}
	}
	for (int i=0;i<n-1;i++)
		cout<<ans[x[i]][y[i]]<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5010,inf=0x3f3f3f3f;
int last[N*2],to[2*N],t[N],d[N],fa[N],v[N],id[N],si[N];
struct node
{
	int x,y,v;
}a[N];
void dfs(int x)
{
	for (int i=t[x];i;i=last[i])
	if (to[i]!=fa[x])
	{
		fa[to[i]]=x;
		si[to[i]]=id[i];
		d[to[i]]=d[x]+1;
		dfs(to[i]);
	}
}
void deal(int x,int y,int z)
{
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		v[si[x]]=max(v[si[x]],z);
		x=fa[x];
	}
	while (x!=y)
	{
		v[si[x]]=max(v[si[x]],z);
        v[si[y]]=max(v[si[y]],z);
		x=fa[x]; y=fa[y];
	}
}
bool check(int x,int y,int z)
{
	int Min=inf;
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		Min=min(Min,v[si[x]]);
		x=fa[x];
	}
	while (x!=y)
	{
		Min=min(v[si[x]],Min);
        Min=min(v[si[y]],Min);
		x=fa[x]; y=fa[y];
	}
	return Min==z;
}
int main()
{
	int n,num=0,m;
	cin>>n;
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		last[++num]=t[x];
		t[x]=num;
		to[num]=y;
		id[num]=i;
		last[++num]=t[y];
		t[y]=num;
		to[num]=x;
		id[num]=i;
	}
	dfs(1);
	cin>>m;
	for (int i=0;i<m;i++)
		cin>>a[i].x>>a[i].y>>a[i].v;
	for (int i=0;i<m;i++)
		deal(a[i].x,a[i].y,a[i].v);
	for (int i=0;i<m;i++)
		if (!check(a[i].x,a[i].y,a[i].v))
		{
			cout<<-1;
			return 0;
		}
	for (int i=1;i<n;i++)
		if (v[i]==0)
			cout<<1<<" ";
		else
			cout<<v[i]<<" ";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5010;
int last[N*2],to[2*N],t[N],d[N],fa[N],v[N],id[N],si[N];
void dfs(int x)
{
	for (int i=t[x];i;i=last[i])
	if (to[i]!=fa[x])
	{
		fa[to[i]]=x;
		si[to[i]]=id[i];
		d[to[i]]=d[x]+1;
		dfs(to[i]);
	}
}
bool check(int x,int y,int z)
{
	bool flag=0;
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		if (v[si[x]]<z&&v[si[x]]!=0)
			return false;
		if (v[si[x]]==0||v[si[x]]==z)
		{
			flag=1;
			v[si[x]]=z;
		}
		x=fa[x];
	}
	while (x!=y)
	{
		if (v[si[x]]<z&&v[si[x]]!=0)
			return false;
		if (v[si[x]]==0||v[si[x]]==z)
		{
			flag=1;
			v[si[x]]=z;
		}
		if (v[si[y]]<z&&v[si[y]]!=0)
			return false;
		if (v[si[y]]==0||v[si[y]]==z)
		{
			flag=1;
			v[si[y]]=z;
		}
		x=fa[x]; y=fa[y];
	}
	if (flag==0)
		return false;
	else
		return true;
}
int main()
{
	int n,num=0,m;
	cin>>n;
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		last[++num]=t[x];
		t[x]=num;
		to[num]=y;
		id[num]=i;
		last[++num]=t[y];
		t[y]=num;
		to[num]=x;
		id[num]=i;
	}
	dfs(1);
	cin>>m;
	for (int i=0;i<m;i++)
	{
		int x,y,v;
		cin>>x>>y>>v;
		if (!check(x,y,v))
		{
			cout<<-1;
			return 0;
		}
	}
	for (int i=1;i<n;i++)
		cout << (v[i] == 0 ? 1 : v[i]) << " ";
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=5010,inf=0x3f3f3f3f;
int last[N*2],to[2*N],t[N],d[N],fa[N],v[N],id[N],si[N];
struct node
{
	int x,y,v;
}a[N];
void dfs(int x)
{
	for (int i=t[x];i;i=last[i])
	if (to[i]!=fa[x])
	{
		fa[to[i]]=x;
		si[to[i]]=id[i];
		d[to[i]]=d[x]+1;
		dfs(to[i]);
	}
}
void deal(int x,int y,int z)
{
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		v[si[x]]=max(v[si[x]],z);
		x=fa[x];
	}
	while (x!=y)
	{
		v[si[x]]=max(v[si[x]],z);
        v[si[y]]=max(v[si[y]],z);
		x=fa[x]; y=fa[y];
	}
}
bool check(int x,int y,int z)
{
	int Min=inf;
	if (d[x]<d[y])
		swap(x,y);
	while (d[x]>d[y])
	{
		Min=min(Min,v[si[x]]);
		x=fa[x];
	}
	while (x!=y)
	{
		Min=min(v[si[x]],Min);
        Min=min(v[si[y]],Min);
		x=fa[x]; y=fa[y];
	}
	return Min==z;
}
int main()
{
	int n,num=0,m;
	cin>>n;
	for (int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		last[++num]=t[x];
		t[x]=num;
		to[num]=y;
		id[num]=i;
		last[++num]=t[y];
		t[y]=num;
		to[num]=x;
		id[num]=i;
	}
	dfs(1);
	cin>>m;
	for (int i=0;i<m;i++)
		cin>>a[i].x>>a[i].y>>a[i].v;
	for (int i=0;i<m;i++)
		deal(a[i].x,a[i].y,a[i].v);
	for (int i=0;i<m;i++)
		check(a[i].x,a[i].y,a[i].v);
	for (int i=1;i<n;i++)
		if (v[i]==0)
			cout<<1<<" ";
		else
			cout<<v[i]<<" ";
	return 0;
}


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

using namespace std;

int n, m;
vector<int> temp[5010];
int parent[5010];
map<pair<int, int>, int> num;

void make_tree(int cur)
{
    for (int next : temp[cur])
    {
        if (parent[next] != 0)
            continue;
        parent[next] = cur;
        make_tree(next);
    }
}

int lca(int s, int e)
{
    int visited[5010] = {0};
    while (s != 1)
    {
        visited[s] = 1;
        s = parent[s];
    }
    visited[1] = 1;
    while (true)
    {
        if (visited[e])
            return e;
        e = parent[e];
    }
}

bool check(int s, int e, int x)
{
    int ancestor = lca(s, e);
    int minn = 1e9;
    while (s != ancestor)
    {
        int next_s = parent[s];
        minn = min(minn, num[{s, next_s}]);
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        minn = min(minn, num[{e, next_e}]);
        e = next_e;
    }
    if (minn != x)
        return false;
    return true;
}

void update(int s, int e, int x)
{
    int ancestor = lca(s, e);
    while (s != ancestor)
    {
        int next_s = parent[s];
        num[{s, next_s}] = x;
        num[{next_s, s}] = x;
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        num[{e, next_e}] = x;
        num[{next_e, e}] = x;
        e = next_e;
    }
}

int main()
{
    pair<int, int> imsi[5011];
    cin >> n;
    for (int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        imsi[i].first = a;
        imsi[i].second = b;
        temp[a].push_back(b);
        temp[b].push_back(a);
    }
    parent[1] = 1;
    make_tree(1);

    cin >> m;
    vector<pair<int, pair<int, int>>> v;
    for (int i = 0; i < m; i++)
    {
        int s, e, x;
        cin >> s >> e >> x;
        v.push_back({x, {s, e}});
    }
    sort(v.begin(), v.end());
    for (auto vv : v)
        update(vv.second.first, vv.second.second, vv.first);
    for (auto vv : v)
        if (check(vv.second.first, vv.second.second, vv.first) == false)
        {
            cout << "-1";
            exit(0);
        }
    for (int i = 0; i < n - 1; i++)
    {
        if (num[{imsi[i].first, imsi[i].second}] == 0)
            cout << 1 << ' ';
        else
            cout << num[{imsi[i].first, imsi[i].second}] << ' ';
    }
}


#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <algorithm>

using namespace std;

int n, m;
vector<int> temp[5010];
int parent[5010];
int num[5010][5010];

void make_tree(int cur)
{
    for (int next : temp[cur])
    {
        if (parent[next] != 0)
            continue;
        parent[next] = cur;
        make_tree(next);
    }
}

int lca(int s, int e)
{
    int visited[5010] = {0};
    while (s != 1)
    {
        visited[s] = 1;
        s = parent[s];
    }
    visited[1] = 1;
    while (true)
    {
        if (visited[e])
            return e;
        e = parent[e];
    }
}

bool check(int s, int e, int x)
{
    int ancestor = lca(s, e);
    int minn = 1e9;
    while (s != ancestor)
    {
        int next_s = parent[s];
        minn = min(minn, num[s][next_s]);
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        minn = min(minn, num[e][next_e]);
        e = next_e;
    }
    if (minn != x)
        return false;
    return true;
}

void update(int s, int e, int x)
{
    int ancestor = lca(s, e);
    while (s != ancestor)
    {
        int next_s = parent[s];
        num[s][next_s] = x;
        num[next_s][s] = x;
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        num[e][next_e] = x;
        num[next_e][e] = x;
        e = next_e;
    }
}

int main()
{
    pair<int, int> imsi[5011];
    cin >> n;
    for (int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        imsi[i].first = a;
        imsi[i].second = b;
        temp[a].push_back(b);
        temp[b].push_back(a);
    }
    parent[1] = 1;
    make_tree(1);

    cin >> m;
    vector<pair<int, pair<int, int>>> v;
    for (int i = 0; i < m; i++)
    {
        int s, e, x;
        cin >> s >> e >> x;
        v.push_back({x, {s, e}});
    }
    sort(v.begin(), v.end());
    for (auto vv : v)
        update(vv.second.first, vv.second.second, vv.first);
    for (auto vv : v)
        if (check(vv.second.first, vv.second.second, vv.first) == false)
        {
            cout << "-1";
            exit(0);
        }
    for (int i = 0; i < n - 1; i++)
    {
        if (num[imsi[i].first][imsi[i].second] == 0)
            cout << 1 << ' ';
        else
            cout << num[imsi[i].first][imsi[i].second] << ' ';
    }
}


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

using namespace std;

int n, m;
vector<int> temp[5010];
int parent[5010];
map<pair<int, int>, int> num;

void make_tree(int cur)
{
    for (int next : temp[cur])
    {
        if (parent[next] != 0)
            continue;
        parent[next] = cur;
        make_tree(next);
    }
}

int lca(int s, int e)
{
    int visited[5010] = {0};
    while (s != 1)
    {
        visited[s] = 1;
        s = parent[s];
    }
    visited[1] = 1;
    while (true)
    {
        if (visited[e])
            return e;
        e = parent[e];
    }
}

bool check(int s, int e, int x)
{
    int ancestor = lca(s, e);
    int minn = 1e9;
    while (s != ancestor)
    {
        int next_s = parent[s];
        minn = min(minn, num[{s, next_s}]);
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        minn = min(minn, num[{e, next_e}]);
        e = next_e;
    }
    if (minn != x)
        return false;
    return true;
}

void update(int s, int e, int x)
{
    int ancestor = lca(s, e);
    while (s != ancestor)
    {
        int next_s = parent[s];
        num[{s, next_s}] = x;
        num[{next_s, s}] = x;
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        num[{e, next_e}] = x;
        num[{next_e, e}] = x;
        e = next_e;
    }
}

int main()
{
    pair<int, int> imsi[5011];
    cin >> n;
    for (int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        imsi[i].first = a;
        imsi[i].second = b;
        temp[a].push_back(b);
        temp[b].push_back(a);
    }
    parent[1] = 1;
    make_tree(1);

    cin >> m;
    vector<pair<int, pair<int, int>>> v;
    for (int i = 0; i < m; i++)
    {
        int s, e, x;
        cin >> s >> e >> x;
        v.push_back({x, {s, e}});
    }
    sort(v.begin(), v.end());
    for (auto vv : v)
        update(vv.second.first, vv.second.second, vv.first);
    for (auto vv : v)
        if (check(vv.second.first, vv.second.second, vv.first) == false)
        {
            cout << "-1";
            exit(0);
        }
    for (int i = 0; i < n - 1; i++)
    {
        if (num[{imsi[i].first, imsi[i].second}] == 0)
            cout << 1 << ' ';
        cout << num[{imsi[i].first, imsi[i].second}] << ' ';
    }
}


#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>
#include <algorithm>

using namespace std;

int n, m;
vector<int> temp[5010];
int parent[5010];
unordered_map<pair<int, int>, int> num;

void make_tree(int cur)
{
    for (int next : temp[cur])
    {
        if (parent[next] != 0)
            continue;
        parent[next] = cur;
        make_tree(next);
    }
}

int lca(int s, int e)
{
    int visited[5010] = {0};
    while (s != 1)
    {
        visited[s] = 1;
        s = parent[s];
    }
    visited[1] = 1;
    while (true)
    {
        if (visited[e])
            return e;
        e = parent[e];
    }
}

bool check(int s, int e, int x)
{
    int ancestor = lca(s, e);
    int minn = 1e9;
    while (s != ancestor)
    {
        int next_s = parent[s];
        minn = min(minn, num[{s, next_s}]);
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        minn = min(minn, num[{e, next_e}]);
        e = next_e;
    }
    if (minn != x)
        return false;
    return true;
}

void update(int s, int e, int x)
{
    int ancestor = lca(s, e);
    while (s != ancestor)
    {
        int next_s = parent[s];
        num[{s, next_s}] = x;
        num[{next_s, s}] = x;
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        num[{e, next_e}] = x;
        num[{next_e, e}] = x;
        e = next_e;
    }
}

int main()
{
    pair<int, int> imsi[5011];
    cin >> n;
    for (int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        imsi[i].first = a;
        imsi[i].second = b;
        temp[a].push_back(b);
        temp[b].push_back(a);
    }
    parent[1] = 1;
    make_tree(1);

    cin >> m;
    vector<pair<int, pair<int, int>>> v;
    for (int i = 0; i < m; i++)
    {
        int s, e, x;
        cin >> s >> e >> x;
        v.push_back({x, {s, e}});
    }
    sort(v.begin(), v.end());
    for (auto vv : v)
        update(vv.second.first, vv.second.second, vv.first);
    for (auto vv : v)
        if (check(vv.second.first, vv.second.second, vv.first) == false)
        {
            cout << "-1";
            exit(0);
        }
    for (int i = 0; i < n - 1; i++)
    {
        if (num[{imsi[i].first, imsi[i].second}] == 0)
            cout << 1 << ' ';
        else
            cout << num[{imsi[i].first, imsi[i].second}] << ' ';
    }
}


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

using namespace std;

int n, m;
vector<int> temp[5010];
int parent[5010];
map<pair<int, int>, int> num;

void make_tree(int cur)
{
    for (int next : temp[cur])
    {
        if (parent[next] != 0)
            continue;
        parent[next] = cur;
        make_tree(next);
    }
}

int lca(int s, int e)
{
    int visited[5010] = {0};
    while (s != 1)
    {
        visited[s] = 1;
        s = parent[s];
    }
    visited[1] = 1;
    while (true)
    {
        if (visited[e])
            return e;
        e = parent[e];
    }
}

bool check(int s, int e, int x)
{
    int ancestor = lca(s, e);
    int minn = 1e9;
    while (s != ancestor)
    {
        int next_s = parent[s];
        minn = min(minn, num[{s, next_s}]);
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        minn = min(minn, num[{e, next_e}]);
        e = next_e;
    }
    if (minn != x)
        return false;
    return true;
}

void update(int s, int e, int x)
{
    int ancestor = lca(s, e);
    while (s != ancestor)
    {
        int next_s = parent[s];
        num[{s, next_s}] = x;
        num[{next_s, s}] = x;
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        num[{e, next_e}] = x;
        num[{next_e, e}] = x;
        e = next_e;
    }
}

int main()
{
    pair<int, int> imsi[5011];
    cin >> n;
    for (int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        imsi[i].first = a;
        imsi[i].second = b;
        temp[a].push_back(b);
        temp[b].push_back(a);
    }
    parent[1] = 1;
    make_tree(1);

    cin >> m;
    vector<pair<int, pair<int, int>>> v;
    for (int i = 0; i < m; i++)
    {
        int s, e, x;
        cin >> s >> e >> x;
        v.push_back({x, {s, e}});
    }
    sort(v.begin(), v.end());
    for (auto vv : v)
        update(vv.second.first, vv.second.second, vv.first);
    for (auto vv : v)
        if (check(vv.second.first, vv.second.second, vv.first) == false)
        {
            cout << "-1";
            exit(0);
        }
    for (int i = 0; i < n - 1; i++)
    {
        cout << num[{imsi[i].first, imsi[i].second}] << ' ';
    }
}


#include <iostream>
#include <vector>
#include <string>
#include <map>

using namespace std;

int n, m;
vector<int> temp[5010];
int parent[5010];
map<pair<int, int>, int> num;

void make_tree(int cur)
{
    for (int next : temp[cur])
    {
        if (parent[next] != 0)
            continue;
        parent[next] = cur;
        make_tree(next);
    }
}

int lca(int s, int e)
{
    int visited[5010] = {0};
    while (s != 1)
    {
        visited[s] = 1;
        s = parent[s];
    }
    visited[1] = 1;
    while (true)
    {
        if (visited[e])
            return e;
        e = parent[e];
    }
}

bool check(int s, int e, int x)
{
    int ancestor = lca(s, e);
    int minn = 1e9;
    while (s != ancestor)
    {
        int next_s = parent[s];
        minn = min(minn, num[{s, next_s}]);
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        minn = min(minn, num[{e, next_e}]);
        e = next_e;
    }
    if (minn != x)
        return false;
    return true;
}

void update(int s, int e, int x)
{
    int ancestor = lca(s, e);
    while (s != ancestor)
    {
        int next_s = parent[s];
        num[{s, next_s}] = x;
        num[{next_s, s}] = x;
        s = next_s;
    }
    while (e != ancestor)
    {
        int next_e = parent[e];
        num[{e, next_e}] = x;
        num[{next_e, e}] = x;
        e = next_e;
    }
}

int main()
{
    pair<int, int> imsi[5011];
    cin >> n;
    for (int i = 0; i < n - 1; i++)
    {
        int a, b;
        cin >> a >> b;
        imsi[i].first = a;
        imsi[i].second = b;
        temp[a].push_back(b);
        temp[b].push_back(a);
    }
    parent[1] = 1;
    make_tree(1);

    cin >> m;
    vector<pair<int, pair<int, int>>> v;
    for (int i = 0; i < m; i++)
    {
        int s, e, x;
        cin >> s >> e >> x;
        v.push_back({x, {s, e}});
    }
    sort(v.begin(), v.end());
    for (auto vv : v)
        update(vv.second.first, vv.second.second, vv.first);
    for (auto vv : v)
        if (check(vv.second.first, vv.second.second, vv.first) == false)
        {
            cout << "-1";
            exit(0);
        }
    for (int i = 0; i < n - 1; i++)
    {
        cout << num[{imsi[i].first, imsi[i].second}] << ' ';
    }
}


#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 5000 + 5;
vector<pair<int,int>> edges[maxn];
int a[maxn], b[maxn], g[maxn], deep[maxn], parent[maxn], f[maxn], paredge[maxn];

void dfs(int u, int p = -1){
    int v, idx;
    for(auto x : edges[u]){
        v = x.first;
        if(v == p)continue;
        idx = x.second;
        parent[v] = u;
        deep[v] = deep[u] + 1;
        paredge[v] = idx;
        dfs(v, u);
    }
}

int main(){
    int n, u, v;
    cin >> n;
    memset(deep, 0, sizeof deep);
    for(int i = 0; i < n - 1; ++ i){
        cin >> u >> v;
        edges[u].push_back({v, i});
        edges[v].push_back({u, i});
    }
    dfs(1);
    int m;
    cin >> m;
    for(int i = 0; i < m; ++i){
        cin >> a[i] >> b[i] >> g[i];
        u = a[i];
        v = b[i];
        while (u != v)
        {
            if(deep[u] < deep[v])
                swap(u, v);
            f[paredge[u]] = max(g[i],f[paredge[u]]);
            u = parent[u];
        }
    }
    for(int i = 0; i < m; ++i){
        u = a[i];
        v = b[i];
        int minval= 1e9;
        while (u != v)
        {
            if(deep[u] < deep[v])
                swap(u, v);
            minval = min(minval,f[paredge[u]]);
            u = parent[u];
        }
        if(minval != g[i])
        {
            cout << -1;
            return 0;
        }
    }
    for(int i= 0; i < n - 1; ++i)
        cout << f[i] << " ";
    return 0;

}

 /*
vector<pair<int,int> > t[maxn];
int par[maxn], paredge[maxn], h[maxn];
int a[maxn], b[maxn], g[maxn];
int f[maxn];

void dfs(int v, int p = -1){
	for (auto edge : t[v]){
		int u = edge.first, idx = edge.second;
		if (u == p)
			continue;
		h[u] = h[v] + 1;
		paredge[u] = idx;
		par[u] = v;
		dfs(u, v);
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	for (int i = 0; i < n - 1; i++){
		int v, u;
		cin >> v >> u;
		t[v].push_back({u, i});
		t[u].push_back({v, i});
	}
	par[1] = -1;
	dfs(1);
	int q;
	cin >> q;
	for (int i = 0; i < q; i++){
		cin >> a[i] >> b[i] >> g[i];
		int v = a[i], u = b[i];
		while (v != u){
			if (h[v] < h[u])
				swap(v, u);
			int idx = paredge[v];
			f[idx] = max(f[idx], g[i]);
			v = par[v];
		}
	}

	for (int i = 0; i < q; i++){
		int v = a[i], u = b[i], x = 1e9;
		while (v != u){
			if (h[v] < h[u])
				swap(v, u);
			int idx = paredge[v];
			x = min(x, f[idx]);
			v = par[v];
		}
		if (x != g[i])
			return cout << -1 << '\n', 0;
	}
	for (int i = 0; i < n - 1; i++)
		cout << max(1, f[i]) << " ";
	cout << '\n';
}
*/


#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
#include <cstring>
using namespace std;
typedef long long ll;

const int maxn = 5000 + 5;
vector<pair<int,int>> edges[maxn];
int a[maxn], b[maxn], g[maxn], deep[maxn], parent[maxn], f[maxn], paredge[maxn];

void dfs(int u, int p = -1){
    int v, idx;
    for(auto x : edges[u]){
        v = x.first;
        if(v == p)continue;
        idx = x.second;
        parent[v] = u;
        deep[v] = deep[u] + 1;
        paredge[v] = idx;
        dfs(v, u);
    }
}

int main(){
    int n, u, v;
    cin >> n;
    memset(deep, 0, sizeof deep);
    for(int i = 0; i < n - 1; ++ i){
        cin >> u >> v;
        edges[u].push_back({v, i});
        edges[v].push_back({u, i});
    }
    dfs(1);
    int m;
    cin >> m;
    for(int i = 0; i < m; ++i){
        cin >> a[i] >> b[i] >> g[i];
        u = a[i];
        v = b[i];
        while (u != v)
        {
            if(deep[u] < deep[v])
                swap(u, v);
            f[paredge[u]] = max(g[i],f[paredge[u]]);
            u = parent[u];
        }
    }
    for(int i = 0; i < m; ++i){
        u = a[i];
        v = b[i];
        int minval= 1e9;
        while (u != v)
        {
            if(deep[u] < deep[v])
                swap(u, v);
            minval = min(minval,f[paredge[u]]);
            u = parent[u];
        }
        if(minval != g[i])
        {
            cout << -1;
            return 0;
        }
    }
    for(int i= 0; i < n - 1; ++i)
        cout << (f[i] == 0 ? 1000000 : f[i]) << " ";
    return 0;

}

/*
vector<pair<int,int> > t[maxn];
int par[maxn], paredge[maxn], h[maxn];
int a[maxn], b[maxn], g[maxn];
int f[maxn];

void dfs(int v, int p = -1){
	for (auto edge : t[v]){
		int u = edge.first, idx = edge.second;
		if (u == p)
			continue;
		h[u] = h[v] + 1;
		paredge[u] = idx;
		par[u] = v;
		dfs(u, v);
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	for (int i = 0; i < n - 1; i++){
		int v, u;
		cin >> v >> u;
		t[v].push_back({u, i});
		t[u].push_back({v, i});
	}
	par[1] = -1;
	dfs(1);
	int q;
	cin >> q;
	for (int i = 0; i < q; i++){
		cin >> a[i] >> b[i] >> g[i];
		int v = a[i], u = b[i];
		while (v != u){
			if (h[v] < h[u])
				swap(v, u);
			int idx = paredge[v];
			f[idx] = max(f[idx], g[i]);
			v = par[v];
		}
	}

	for (int i = 0; i < q; i++){
		int v = a[i], u = b[i], x = 1e9;
		while (v != u){
			if (h[v] < h[u])
				swap(v, u);
			int idx = paredge[v];
			x = min(x, f[idx]);
			v = par[v];
		}
		if (x != g[i])
			return cout << -1 << '\n', 0;
	}
	for (int i = 0; i < n - 1; i++)
		cout << max(1, f[i]) << " ";
	cout << '\n';
}
*/


#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
#include <cstring>
using namespace std;
typedef long long ll;

const int maxn = 5000 + 5;
vector<pair<int,int>> edges[maxn];
int a[maxn], b[maxn], g[maxn], deep[maxn], parent[maxn], f[maxn], paredge[maxn];

void dfs(int u, int p = -1){
    int v, idx;
    for(auto x : edges[u]){
        v = x.first;
        if(v == p)continue;
        idx = x.second;
        parent[v] = u;
        deep[v] = deep[u] + 1;
        paredge[v] = idx;
        dfs(v, u);
    }
}

int main(){
    int n, u, v;
    cin >> n;
    memset(deep, 0, sizeof deep);
    for(int i = 0; i < n - 1; ++ i){
        cin >> u >> v;
        edges[u].push_back({v, i});
        edges[v].push_back({u, i});
    }
    dfs(1);
    int m;
    cin >> m;
    for(int i = 0; i < m; ++i){
        cin >> a[i] >> b[i] >> g[i];
        u = a[i];
        v = b[i];
        while (u != v)
        {
            if(deep[u] < deep[v])
                swap(u, v);
            f[paredge[u]] = max(g[i],f[paredge[u]]);
            u = parent[u];
        }
    }
    for(int i = 0; i < m; ++i){
        u = a[i];
        v = b[i];
        int minval= 1e9;
        while (u != v)
        {
            if(deep[u] < deep[v])
                swap(u, v);
            minval = min(minval,f[paredge[u]]);
            u = parent[u];
        }
        if(minval != g[i])
        {
            cout << -1;
            return 0;
        }
    }
    for(int i= 0; i < n - 1; ++i)
        cout << (f[i] == 0 ? 1e6 : f[i]) << " ";
    return 0;

}

/*
vector<pair<int,int> > t[maxn];
int par[maxn], paredge[maxn], h[maxn];
int a[maxn], b[maxn], g[maxn];
int f[maxn];

void dfs(int v, int p = -1){
	for (auto edge : t[v]){
		int u = edge.first, idx = edge.second;
		if (u == p)
			continue;
		h[u] = h[v] + 1;
		paredge[u] = idx;
		par[u] = v;
		dfs(u, v);
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	for (int i = 0; i < n - 1; i++){
		int v, u;
		cin >> v >> u;
		t[v].push_back({u, i});
		t[u].push_back({v, i});
	}
	par[1] = -1;
	dfs(1);
	int q;
	cin >> q;
	for (int i = 0; i < q; i++){
		cin >> a[i] >> b[i] >> g[i];
		int v = a[i], u = b[i];
		while (v != u){
			if (h[v] < h[u])
				swap(v, u);
			int idx = paredge[v];
			f[idx] = max(f[idx], g[i]);
			v = par[v];
		}
	}

	for (int i = 0; i < q; i++){
		int v = a[i], u = b[i], x = 1e9;
		while (v != u){
			if (h[v] < h[u])
				swap(v, u);
			int idx = paredge[v];
			x = min(x, f[idx]);
			v = par[v];
		}
		if (x != g[i])
			return cout << -1 << '\n', 0;
	}
	for (int i = 0; i < n - 1; i++)
		cout << max(1, f[i]) << " ";
	cout << '\n';
}
*/


#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=5005;
int head[N],n,m,cnt,p[N],d[N],f[N],res[N];
struct Node1{int nxt,to,id;}edges[N*2];
struct Node2{int a,b,g;}q[N];
void addedge(int u,int v,int w){edges[++cnt]=Node1{head[u],v,w},head[u]=cnt;}
void dfs(int u)
{
    for(int i=head[u];~i;i=edges[i].nxt)
    {
        int v=edges[i].to;
        if(p[u]==v)continue;
        p[v]=u,d[v]=d[u]+1,f[v]=edges[i].id,dfs(v);
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v,i),addedge(v,u,i);
    }
    dfs(1);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].g);
    sort(q+1,q+1+m,[&](Node2 x,Node2 y){return x.g>y.g;});
    int g=1;
    for(int i=1;i<=m;i++)
    {
        int x=q[i].a,y=q[i].b,h=0;
        if(d[x]<d[y])swap(x,y);
        while(d[x]!=d[y])
		{
            if(!res[f[x]]||res[f[x]]==q[i].g)res[f[x]]=q[i].g,h=1;
			x=p[x];
		}
        while(x!=y)
        {
            if(!res[f[x]]||res[f[x]]==q[i].g)res[f[x]]=q[i].g,h=1;
            if(!res[f[y]]||res[f[y]]==q[i].g)res[f[y]]=q[i].g,h=1;
            x=p[x],y=p[y];
        }
        if(!h)g=0;
    }
    if(!g)puts("-1");
    else for(int i=1;i<n;i++)printf("%d ",res[i]?res[i]:1000000);
	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=5005;
int head[N],n,m,cnt,p[N],d[N],f[N],res[N];
struct Node1{int nxt,to,id;}edges[N*2];
struct Node2{int a,b,g;}q[N];
void addedge(int u,int v,int w){edges[++cnt]=Node1{head[u],v,w},head[u]=cnt;}
void dfs(int u)
{
    for(int i=head[u];~i;i=edges[i].nxt)
    {
        int v=edges[i].to;
        if(p[u]==v)continue;
        p[v]=u,d[v]=d[u]+1,f[v]=edges[i].id,dfs(v);
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v,i),addedge(v,u,i);
    }
    dfs(1);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].g);
    sort(q+1,q+1+m,[&](Node2 x,Node2 y){return x.g>y.g;});
    int g=1;
    for(int i=1;i<=m;i++)
    {
        int x=q[i].a,y=q[i].b,h=0;
        if(d[x]<d[y])swap(x,y);
        while(d[x]!=d[y])
		{
            if(!res[f[x]])res[f[x]]=q[i].g,h=1;
			x=p[x];
		}
        while(x!=y)
        {
            if(!res[f[x]])res[f[x]]=q[i].g,h=1;
            if(!res[f[y]])res[f[y]]=q[i].g,h=1;
            x=p[x],y=p[y];
        }
        if(!h)g=0;
    }
    if(!g)puts("-1");
    else for(int i=1;i<n;i++)printf("%d ",res[i]?res[i]:1000000);
	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=2e5+10;
int n,a[N];
map<int,int>length;
int solve(int l,int r)
{
    if(l>r)return r;
    printf("? %d %d\n",l,r),fflush(stdout);
    int x,f;
    scanf("%d%d",&x,&f);
    if(length[x])
	{
		int ll=r-f+1,rr=ll+length[x]-1;
		for(int i=ll;i<=rr;i++)a[i]=x;
		length[x]=0,solve(l,ll-1);
		return rr;
	}
	else
	{
		length[x]=f;
		int p=l;
		while(length[x])p=solve(p,p+f-1)+1;
		return solve(p,r);
	}
}
int main()
{
    scanf("%d",&n);
    solve(1,n);
    printf("! ");
    for(int i=1;i<=n;i++)printf("%d ",a[i]);
    puts("");
	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int N=5005;
int head[N],n,m,cnt,p[N],d[N],f[N],res[N];
struct Node1{int nxt,to,id;}edges[N*2];
struct Node2{int a,b,g;}q[N];
void addedge(int u,int v,int w){edges[++cnt]=Node1{head[u],v,w},head[u]=cnt;}
void dfs(int u)
{
    for(int i=head[u];~i;i=edges[i].nxt)
    {
        int v=edges[i].to;
        if(p[u]==v)continue;
        p[v]=u,d[v]=d[u]+1,f[v]=edges[i].id,dfs(v);
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v,i),addedge(v,u,i);
    }
    dfs(1);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)scanf("%d%d%d",&q[i].a,&q[i].b,&q[i].g);
    sort(q+1,q+1+m,[&](Node2 x,Node2 y){return x.g>y.g;});
    int g=1;
    for(int i=1;i<=m;i++)
    {
        int x=q[i].a,y=q[i].b,h=0;
        if(d[x]<d[y])swap(x,y);
        while(d[x]!=d[y])
		{
            if(!res[f[x]]||res[f[x]]==q[i].g)res[f[x]]=q[i].g,h=1;
			x=p[x];
		}
        while(x!=y)
        {
            if(!res[f[x]]||res[f[x]]==q[i].g)res[f[x]]=q[i].g,h=1;
            if(!res[f[y]]||res[f[y]]==q[i].g)res[f[y]]=q[i].g,h=1;
            x=p[x],y=p[y];
        }
        if(!h)g=0;
    }
    if(!g)puts("-1");
    else for(int i=1;i<n;i++)printf("%d ",res[i]?res[i]:1);
	return 0;
}


/*
Nahid Hossain
Jahangirnagar University
Roll:54
*/
#include<bits/stdc++.h>
#define ll          long long int
#define db          double
#define pf          printf
#define sf          scanf
#define ff          first
#define ss          second
#define clr         clear()
#define sz          size()
#define pb          push_back
#define mk          make_pair
#define pi          acos(-1)
#define inf         2000000000000000000
#define mod         1000000007
#define ull         unsigned long long int
#define f(i,k,n)    for(i=k;i<n;i++)
#define fr(i,n,k)   for(i=n;i>=k;i--)
#define ent(a)      scanf("%lld",&a)
#define ent2(a,b)   scanf("%lld%lld",&a,&b)
#define ent3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define mem(a)      memset(a,0,sizeof(a))
#define vec(v,s)    vector<ll>v[s]
#define arr(a,s)    ll a[s];
#define bitone(x)   __builtin_popcount(x)
//#define check(n,pos) (n&(1<<pos))
//#define set(n,pos)  (n|(1<<pos))
//knight and king//
int dr[]= {2,2,-2,-2,1,-1,1,-1};
int dc[]= {1,-1,1,-1,2,2,-2,-2};
int dr1[]= {0,0,1,1,1,-1,-1,-1};
int dc1[]= {1,-1,1,0,-1,0,1,-1};
int dr2[]= {0,0,1,-1};
int dc2[]= {1,-1,0,0};
////////////////////////////
using namespace std;
#define ma 5005

vector<pair<ll,ll> > adj[ma];

ll a[ma],b[ma];
ll dfs(ll u,ll par,ll x)
{
    ll i,j;
    if(u==x)return 1;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs(p,u,x);
        if(r==1)
        {
            a[p1]++;
            return 1;
        }
    }
    return 0;

}

vector<ll>v1;

ll dfs1(ll u,ll par,ll x)
{
    if(u==x)return 1;
    ll i;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs1(p,u,x);
        if(r==1)
        {
            v1.pb(p1);
            return 1;
        }
    }
    return 0;
}

int main()
{
    ll n,i,j,u,v,q,x,y,c;
    while(cin>>n)
    {
        for(i=1;i<n;i++)
        {
            cin>>u>>v;
            adj[u].pb(mk(v,i));
            adj[v].pb(mk(u,i));
        }

        cin>>q;

        vector<pair<ll,pair<ll,ll> > >v;
        map<pair<ll,ll>,ll >mp;

        bool f=0;
        for(i=1;i<=q;i++)
        {
            cin>>x>>y>>c;
            if(mp[{x,y}]!=0)
                {
                    if(mp[{x,y}]!=c)f=1;
                    continue;
                }
                mp[{x,y}]=c;
            dfs(x,-1,y);
            v.pb(mk(c,mk(x,y)));
        }

        for(i=1;i<n;i++)b[i]=1000000;

        sort(v.begin(),v.end());

        for(i=0;i<v.sz;i++)
        {
            ll x=v[i].ss.ff;
            ll y=v[i].ss.ss;
            ll c=v[i].ff;
            v1.clr;
            dfs1(x,-1,y);
            ll min1=inf;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                min1=min(min1,b[r]);
                a[r]--;
            }
            if(min1==c)continue;
            if(min1<c)
            {
                f=1;
                break;
            }
            bool f1=0;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                if(a[r]==0)
                {
                    f1=1;
                    b[r]=c;
                    break;
                }
            }
            if(f1==0)
            {
                f=1;
                break;
            }
        }

        if(f==1)
        {
            cout<<"-1"<<endl;
            continue;
        }

        for(i=1;i<n;i++)cout<<b[i]<<" ";
        cout<<endl;

    }
    return 0;
}


/*
Nahid Hossain
Jahangirnagar University
Roll:54
*/
#include<bits/stdc++.h>
#define ll          long long int
#define db          double
#define pf          printf
#define sf          scanf
#define ff          first
#define ss          second
#define clr         clear()
#define sz          size()
#define pb          push_back
#define mk          make_pair
#define pi          acos(-1)
#define inf         2000000000000000000
#define mod         1000000007
#define ull         unsigned long long int
#define f(i,k,n)    for(i=k;i<n;i++)
#define fr(i,n,k)   for(i=n;i>=k;i--)
#define ent(a)      scanf("%lld",&a)
#define ent2(a,b)   scanf("%lld%lld",&a,&b)
#define ent3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define mem(a)      memset(a,0,sizeof(a))
#define vec(v,s)    vector<ll>v[s]
#define arr(a,s)    ll a[s];
#define bitone(x)   __builtin_popcount(x)
//#define check(n,pos) (n&(1<<pos))
//#define set(n,pos)  (n|(1<<pos))
//knight and king//
int dr[]= {2,2,-2,-2,1,-1,1,-1};
int dc[]= {1,-1,1,-1,2,2,-2,-2};
int dr1[]= {0,0,1,1,1,-1,-1,-1};
int dc1[]= {1,-1,1,0,-1,0,1,-1};
int dr2[]= {0,0,1,-1};
int dc2[]= {1,-1,0,0};
////////////////////////////
using namespace std;
#define ma 5005

vector<pair<ll,ll> > adj[ma];

ll a[ma],b[ma];
ll dfs(ll u,ll par,ll x)
{
    ll i,j;
    if(u==x)return 1;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs(p,u,x);
        if(r==1)
        {
            a[p1]++;
            return 1;
        }
    }
    return 0;

}

vector<ll>v1;

ll dfs1(ll u,ll par,ll x)
{
    if(u==x)return 1;
    ll i;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs1(p,u,x);
        if(r==1)
        {
            v1.pb(p1);
            return 1;
        }
    }
    return 0;
}

ll mark[ma];
int main()
{
    ll n,i,j,u,v,q,x,y,c;
    while(cin>>n)
    {
        for(i=1;i<n;i++)
        {
            cin>>u>>v;
            adj[u].pb(mk(v,i));
            adj[v].pb(mk(u,i));
        }

        cin>>q;

        vector<pair<ll,pair<ll,ll> > >v;
        map<pair<ll,ll>,ll >mp;

        bool f=0;
        for(i=1;i<=q;i++)
        {
            cin>>x>>y>>c;
            dfs(x,-1,y);
            v.pb(mk(c,mk(x,y)));
        }

        for(i=1;i<n;i++)b[i]=1000000;

        sort(v.begin(),v.end());
        for(i=0;i<v.sz;i++)
        {
            mem(mark);
            ll c=v[i].ff;
            for(j=i;j<v.sz;j++)
            {
                if(v[j].ff!=v[i].ff)break;
                ll x=v[j].ss.ff;
                ll y=v[j].ss.ss;
                v1.clr;
                dfs1(x,-1,y);
                for(ll j1=0;j1<v1.sz;j1++)
                {
                    ll r=v1[j1];
                    mark[r]=1;
                    a[r]--;
                }
            }
            i=j-1;

            for(j=1;j<n;j++)
            {
                if(mark[j]==0)continue;
                if(a[j]==0)b[j]=c;
            }
        }
        for(i=0;i<v.sz;i++)
        {
            ll x=v[i].ss.ff;
            ll y=v[i].ss.ss;
            ll c=v[i].ff;
            v1.clr;
            dfs1(x,-1,y);
            ll min1=inf;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                min1=min(min1,b[r]);

            }
            if(min1!=c)
            {
                f=1;
                break;
            }
        }
        if(f==1)
        {
            cout<<"-1"<<endl;
            continue;
        }

        for(i=1;i<n;i++)cout<<b[i]<<" ";
        cout<<endl;

    }
    return 0;
}


/*
Nahid Hossain
Jahangirnagar University
Roll:54
*/
#include<bits/stdc++.h>
#define ll          long long int
#define db          double
#define pf          printf
#define sf          scanf
#define ff          first
#define ss          second
#define clr         clear()
#define sz          size()
#define pb          push_back
#define mk          make_pair
#define pi          acos(-1)
#define inf         2000000000000000000
#define mod         1000000007
#define ull         unsigned long long int
#define f(i,k,n)    for(i=k;i<n;i++)
#define fr(i,n,k)   for(i=n;i>=k;i--)
#define ent(a)      scanf("%lld",&a)
#define ent2(a,b)   scanf("%lld%lld",&a,&b)
#define ent3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define mem(a)      memset(a,0,sizeof(a))
#define vec(v,s)    vector<ll>v[s]
#define arr(a,s)    ll a[s];
#define bitone(x)   __builtin_popcount(x)
//#define check(n,pos) (n&(1<<pos))
//#define set(n,pos)  (n|(1<<pos))
//knight and king//
int dr[]= {2,2,-2,-2,1,-1,1,-1};
int dc[]= {1,-1,1,-1,2,2,-2,-2};
int dr1[]= {0,0,1,1,1,-1,-1,-1};
int dc1[]= {1,-1,1,0,-1,0,1,-1};
int dr2[]= {0,0,1,-1};
int dc2[]= {1,-1,0,0};
////////////////////////////
using namespace std;
#define ma 5005

vector<pair<ll,ll> > adj[ma];

ll a[ma],b[ma];
ll dfs(ll u,ll par,ll x)
{
    ll i,j;
    if(u==x)return 1;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs(p,u,x);
        if(r==1)
        {
            a[p1]++;
            return 1;
        }
    }
    return 0;

}

vector<ll>v1;

ll dfs1(ll u,ll par,ll x)
{
    if(u==x)return 1;
    ll i;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs1(p,u,x);
        if(r==1)
        {
            v1.pb(p1);
            return 1;
        }
    }
    return 0;
}

int main()
{
    ll n,i,j,u,v,q,x,y,c;
    while(cin>>n)
    {
        for(i=1;i<n;i++)
        {
            cin>>u>>v;
            adj[u].pb(mk(v,i));
            adj[v].pb(mk(u,i));
        }

        cin>>q;

        vector<pair<ll,pair<ll,ll> > >v;
        map<pair<ll,ll>,ll >mp;

        bool f=0;
        for(i=1;i<=q;i++)
        {
            cin>>x>>y>>c;
            dfs(x,-1,y);
            v.pb(mk(c,mk(x,y)));
        }

        for(i=1;i<n;i++)b[i]=1000000;

        sort(v.begin(),v.end());
        for(i=0;i<v.sz;i++)
        {
            ll x=v[i].ss.ff;
            ll y=v[i].ss.ss;
            ll c=v[i].ff;
            v1.clr;
            dfs1(x,-1,y);
            ll min1=inf;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                min1=min(min1,b[r]);
                a[r]--;
            }
            if(min1==c)continue;
            if(min1<c)
            {
                f=1;
                break;
            }
            min1=inf,q;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                if(a[r]<min1)
                {
                    min1=a[r];
                    q=r;
                }
            }
            b[q]=c;
        }

        if(f==1)
        {
            cout<<"-1"<<endl;
            continue;
        }

        for(i=1;i<n;i++)cout<<b[i]<<" ";
        cout<<endl;

    }
    return 0;
}


/*
Nahid Hossain
Jahangirnagar University
Roll:54
*/
#include<bits/stdc++.h>
#define ll          long long int
#define db          double
#define pf          printf
#define sf          scanf
#define ff          first
#define ss          second
#define clr         clear()
#define sz          size()
#define pb          push_back
#define mk          make_pair
#define pi          acos(-1)
#define inf         2000000000000000000
#define mod         1000000007
#define ull         unsigned long long int
#define f(i,k,n)    for(i=k;i<n;i++)
#define fr(i,n,k)   for(i=n;i>=k;i--)
#define ent(a)      scanf("%lld",&a)
#define ent2(a,b)   scanf("%lld%lld",&a,&b)
#define ent3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define mem(a)      memset(a,0,sizeof(a))
#define vec(v,s)    vector<ll>v[s]
#define arr(a,s)    ll a[s];
#define bitone(x)   __builtin_popcount(x)
//#define check(n,pos) (n&(1<<pos))
//#define set(n,pos)  (n|(1<<pos))
//knight and king//
int dr[]= {2,2,-2,-2,1,-1,1,-1};
int dc[]= {1,-1,1,-1,2,2,-2,-2};
int dr1[]= {0,0,1,1,1,-1,-1,-1};
int dc1[]= {1,-1,1,0,-1,0,1,-1};
int dr2[]= {0,0,1,-1};
int dc2[]= {1,-1,0,0};
////////////////////////////
using namespace std;
#define ma 5005

vector<pair<ll,ll> > adj[ma];

ll a[ma],b[ma];
ll dfs(ll u,ll par,ll x)
{
    ll i,j;
    if(u==x)return 1;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs(p,u,x);
        if(r==1)
        {
            a[p1]++;
            return 1;
        }
    }
    return 0;

}

vector<ll>v1;

ll dfs1(ll u,ll par,ll x)
{
    if(u==x)return 1;
    ll i;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs1(p,u,x);
        if(r==1)
        {
            v1.pb(p1);
            return 1;
        }
    }
    return 0;
}

int main()
{
    ll n,i,j,u,v,q,x,y,c;
    while(cin>>n)
    {
        for(i=1;i<n;i++)
        {
            cin>>u>>v;
            adj[u].pb(mk(v,i));
            adj[v].pb(mk(u,i));
        }

        cin>>q;

        vector<pair<ll,pair<ll,ll> > >v;
        map<pair<ll,ll>,ll >mp;

        bool f=0;
        for(i=1;i<=q;i++)
        {
            cin>>x>>y>>c;
            if(mp[{x,y}]!=0)
                {
                    if(mp[{x,y}]!=c)f=1;
                    continue;
                }
                mp[{x,y}]=c;
            dfs(x,-1,y);
            v.pb(mk(c,mk(x,y)));
        }

        for(i=1;i<n;i++)b[i]=1000000;

        sort(v.begin(),v.end());
        for(i=0;i<v.sz;i++)
        {
            ll x=v[i].ss.ff;
            ll y=v[i].ss.ss;
            ll c=v[i].ff;
            v1.clr;
            dfs1(x,-1,y);
            ll min1=inf;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                min1=min(min1,b[r]);
                a[r]--;
            }
            if(min1==c)continue;
            if(min1<c)
            {
                f=1;
                break;
            }
            min1=inf,q;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                if(a[r]<min1)
                {
                    min1=a[r];
                    q=r;
                }
            }
            b[q]=c;
        }

        if(f==1)
        {
            cout<<"-1"<<endl;
            continue;
        }

        for(i=1;i<n;i++)cout<<b[i]<<" ";
        cout<<endl;

    }
    return 0;
}


/*
Nahid Hossain
Jahangirnagar University
Roll:54
*/
#include<bits/stdc++.h>
#define ll          long long int
#define db          double
#define pf          printf
#define sf          scanf
#define ff          first
#define ss          second
#define clr         clear()
#define sz          size()
#define pb          push_back
#define mk          make_pair
#define pi          acos(-1)
#define inf         2000000000000000000
#define mod         1000000007
#define ull         unsigned long long int
#define f(i,k,n)    for(i=k;i<n;i++)
#define fr(i,n,k)   for(i=n;i>=k;i--)
#define ent(a)      scanf("%lld",&a)
#define ent2(a,b)   scanf("%lld%lld",&a,&b)
#define ent3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define mem(a)      memset(a,0,sizeof(a))
#define vec(v,s)    vector<ll>v[s]
#define arr(a,s)    ll a[s];
#define bitone(x)   __builtin_popcount(x)
//#define check(n,pos) (n&(1<<pos))
//#define set(n,pos)  (n|(1<<pos))
//knight and king//
int dr[]= {2,2,-2,-2,1,-1,1,-1};
int dc[]= {1,-1,1,-1,2,2,-2,-2};
int dr1[]= {0,0,1,1,1,-1,-1,-1};
int dc1[]= {1,-1,1,0,-1,0,1,-1};
int dr2[]= {0,0,1,-1};
int dc2[]= {1,-1,0,0};
////////////////////////////
using namespace std;
#define ma 5005

vector<pair<ll,ll> > adj[ma];

ll a[ma],b[ma];
ll dfs(ll u,ll par,ll x)
{
    ll i,j;
    if(u==x)return 1;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs(p,u,x);
        if(r==1)
        {
            a[p1]++;
            return 1;
        }
    }
    return 0;

}

vector<ll>v1;

ll dfs1(ll u,ll par,ll x)
{
    if(u==x)return 1;
    ll i;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs1(p,u,x);
        if(r==1)
        {
            v1.pb(p1);
            return 1;
        }
    }
    return 0;
}

int main()
{
    ll n,i,j,u,v,q,x,y,c;
    while(cin>>n)
    {
        for(i=1;i<n;i++)
        {
            cin>>u>>v;
            adj[u].pb(mk(v,i));
            adj[v].pb(mk(u,i));
        }

        cin>>q;

        vector<pair<ll,pair<ll,ll> > >v;
        for(i=1;i<=q;i++)
        {
            cin>>x>>y>>c;
            dfs(x,-1,y);
            v.pb(mk(c,mk(x,y)));
        }

        for(i=1;i<n;i++)b[i]=1000000;

        sort(v.begin(),v.end());

        bool f=0;

        for(i=0;i<v.sz;i++)
        {
            ll x=v[i].ss.ff;
            ll y=v[i].ss.ss;
            ll c=v[i].ff;
            v1.clr;
            dfs1(x,-1,y);
            ll min1=inf;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                min1=min(min1,b[r]);
                a[r]--;
            }
            if(min1==c)continue;
            if(min1<c)
            {
                f=1;
                break;
            }
            bool f1=0;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                if(a[r]==0)
                {
                    f1=1;
                    b[r]=c;
                    break;
                }
            }
            if(f1==0)
            {
                f=1;
                break;
            }
        }

        if(f==1)
        {
            cout<<"-1"<<endl;
            continue;
        }

        for(i=1;i<n;i++)cout<<b[i]<<" ";
        cout<<endl;

    }
    return 0;
}


/*
Nahid Hossain
Jahangirnagar University
Roll:54
*/
#include<bits/stdc++.h>
#define ll          long long int
#define db          double
#define pf          printf
#define sf          scanf
#define ff          first
#define ss          second
#define clr         clear()
#define sz          size()
#define pb          push_back
#define mk          make_pair
#define pi          acos(-1)
#define inf         2000000000000000000
#define mod         1000000007
#define ull         unsigned long long int
#define f(i,k,n)    for(i=k;i<n;i++)
#define fr(i,n,k)   for(i=n;i>=k;i--)
#define ent(a)      scanf("%lld",&a)
#define ent2(a,b)   scanf("%lld%lld",&a,&b)
#define ent3(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define mem(a)      memset(a,0,sizeof(a))
#define vec(v,s)    vector<ll>v[s]
#define arr(a,s)    ll a[s];
#define bitone(x)   __builtin_popcount(x)
//#define check(n,pos) (n&(1<<pos))
//#define set(n,pos)  (n|(1<<pos))
//knight and king//
int dr[]= {2,2,-2,-2,1,-1,1,-1};
int dc[]= {1,-1,1,-1,2,2,-2,-2};
int dr1[]= {0,0,1,1,1,-1,-1,-1};
int dc1[]= {1,-1,1,0,-1,0,1,-1};
int dr2[]= {0,0,1,-1};
int dc2[]= {1,-1,0,0};
////////////////////////////
using namespace std;
#define ma 5005

vector<pair<ll,ll> > adj[ma];

ll a[ma],b[ma];
ll dfs(ll u,ll par,ll x)
{
    ll i,j;
    if(u==x)return 1;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs(p,u,x);
        if(r==1)
        {
            a[p1]++;
            return 1;
        }
    }
    return 0;

}

vector<ll>v1;

ll dfs1(ll u,ll par,ll x)
{
    if(u==x)return 1;
    ll i;
    for(i=0;i<adj[u].sz;i++)
    {
        ll p=adj[u][i].ff;
        ll p1=adj[u][i].ss;
        if(p==par)continue;
        ll r=dfs1(p,u,x);
        if(r==1)
        {
            v1.pb(p1);
            return 1;
        }
    }
    return 0;
}

int main()
{
    ll n,i,j,u,v,q,x,y,c;
    while(cin>>n)
    {
        for(i=1;i<n;i++)
        {
            cin>>u>>v;
            adj[u].pb(mk(v,i));
            adj[v].pb(mk(u,i));
        }

        cin>>q;

        vector<pair<ll,pair<ll,ll> > >v;
        for(i=1;i<=q;i++)
        {
            cin>>x>>y>>c;
            dfs(x,-1,y);
            v.pb(mk(c,mk(x,y)));
        }

        for(i=1;i<n;i++)b[i]=1000000;

        sort(v.begin(),v.end());

        bool f=0;

        for(i=0;i<v.sz;i++)
        {
            ll x=v[i].ss.ff;
            ll y=v[i].ss.ss;
            ll c=v[i].ff;
            v1.clr;
            dfs1(x,-1,y);
            ll min1=inf;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                min1=min(min1,b[r]);
                a[r]--;
            }
            if(min1==c)continue;
            bool f1=0;
            for(j=0;j<v1.sz;j++)
            {
                ll r=v1[j];
                if(a[r]==0)
                {
                    f1=1;
                    b[r]=c;
                    break;
                }
            }
            if(f1==0)
            {
                f=1;
                break;
            }
        }

        if(f==1)
        {
            cout<<"-1"<<endl;
            continue;
        }

        for(i=1;i<n;i++)cout<<b[i]<<" ";
        cout<<endl;

    }
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <random>
#include <unordered_map>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
using namespace std;
const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 1e18;
const double INFD = 1e30;
const double EPS = 1e-6;
const double PI = 3.14159265;
const ll MOD = 20101009;
const int MAXN = 5005;
int n, m, k;

int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};
int dr2[8] = {1, 1, 1, -1, -1, -1, 0, 0};
int dc2[8] = {1, 0, -1, 1, 0, -1, 1, -1};
int CASE = 1;

struct Query {
    int a, b, s;
};
vector<int> G[MAXN];
vector<Query> Qs;
vector<Query> edges;
int parent[MAXN], dep[MAXN], val[MAXN];

void dfs(int u, int p) {
    val[u] = 1;
    for (auto v : G[u]) {
        if (v == p) continue;
        parent[v] = p, dep[v] = dep[u] + 1;
        dfs(v, u);
    }
}

void apply(int u, int v, int s) {
    if (dep[u] < dep[v]) swap(u, v);
    while (dep[u] > dep[v]) val[u] = max(val[u], s), u = parent[u];
    while (u != v) {
        val[u] = max(val[u], s), val[v] = max(val[v], s);
        u = parent[u], v = parent[v];
    }
}

int query(int u, int v) {
    if (dep[u] < dep[v]) swap(u, v);
    int maxx = INF2;
    while (dep[u] > dep[v]) maxx = min(maxx, val[u]), u = parent[u];
    while (u != v) {
        maxx = min(maxx, val[u]), maxx = min(maxx, val[v]);
        u = parent[u], v = parent[v];
    }
    return maxx;
}
int main() {
#ifdef LOCALLL
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].push_back(v), G[v].push_back(u);
        edges.push_back({u, v});
    }
    dfs(1, 1);
    scanf("%d", &m);
    while (m--) {
        int a, b, s;
        scanf("%d%d%d", &a, &b, &s);
        apply(a, b, s), Qs.push_back({a, b, s});
    }
    for (auto& q : Qs) {
        if (query(q.a, q.b) != q.s) {
            printf("-1");
            return 0;
        }
    }
    for (auto& e : edges) {
        printf("%d ", val[dep[e.a] > dep[e.b] ? e.a : e.b]);
    }
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <random>
#include <unordered_map>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
using namespace std;
const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 1e18;
const double INFD = 1e30;
const double EPS = 1e-6;
const double PI = 3.14159265;
const ll MOD = 20101009;
const int MAXN = 5005;
int n, m, k;

int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};
int dr2[8] = {1, 1, 1, -1, -1, -1, 0, 0};
int dc2[8] = {1, 0, -1, 1, 0, -1, 1, -1};
int CASE = 1;

struct Query {
    int a, b, s;
};
vector<int> G[MAXN];
vector<Query> Qs;
vector<Query> edges;
int parent[MAXN], dep[MAXN], val[MAXN];

void dfs(int u, int p) {
    val[u] = 1;
    for (auto v : G[u]) {
        if (v == p) continue;
        parent[v] = p, dep[v] = dep[u] + 1;
        dfs(v, u);
    }
}

void apply(int u, int v, int s) {
    if (dep[u] < dep[v]) swap(u, v);
    while (dep[u] > dep[v]) val[u] = max(val[u], s), u = parent[u];
    while (u != v) {
        val[u] = max(val[u], s), val[v] = max(val[v], s);
        u = parent[u], v = parent[v];
    }
}

int query(int u, int v) {
    if (dep[u] < dep[v]) swap(u, v);
    int maxx = INF2;
    while (dep[u] > dep[v]) maxx = min(maxx, val[u]), u = parent[u];
    while (u != v) {
        val[u] = maxx = min(maxx, val[u]), val[v] = maxx = min(maxx, val[v]);
        u = parent[u], v = parent[v];
    }
    return maxx;
}
int main() {
#ifdef LOCALLL
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].push_back(v), G[v].push_back(u);
        edges.push_back({u, v});
    }
    dfs(1, 1);
    scanf("%d", &m);
    while (m--) {
        int a, b, s;
        scanf("%d%d%d", &a, &b, &s);
        apply(a, b, s), Qs.push_back({a, b, s});
    }
    for (auto& q : Qs) {
        if (query(q.a, q.b) != q.s) {
            printf("-1");
            return 0;
        }
    }
    for (auto& e : edges) {
        printf("%d ", val[dep[e.a] > dep[e.b] ? e.a : e.b]);
    }
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <random>
#include <unordered_map>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
using namespace std;
const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 1e18;
const double INFD = 1e30;
const double EPS = 1e-6;
const double PI = 3.14159265;
const ll MOD = 20101009;
const int MAXN = 5005;
int n, m, k;

int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};
int dr2[8] = {1, 1, 1, -1, -1, -1, 0, 0};
int dc2[8] = {1, 0, -1, 1, 0, -1, 1, -1};
int CASE = 1;

struct Query {
    int a, b, s;
};
vector<int> G[MAXN];
vector<Query> Qs;
vector<Query> edges;
int parent[MAXN], dep[MAXN], val[MAXN];
int son[MAXN], sz[MAXN], dfn[MAXN], top[MAXN], DFN;

#define ls nodes[p << 1]
#define rs nodes[p << 1 | 1]
#define self nodes[p]
struct SegTree {
    struct Node {
        int tag, minn;
    };
    Node nodes[MAXN << 2];
    void modify(int l, int r, int p, int t) {
        self.tag = max(self.tag, t);
        self.minn = max(self.minn, t);
    }
    void push_down(int l, int r, int p) {
        if (self.tag) {
            int mid = (l + r) / 2;
            modify(l, mid, p << 1, self.tag),
                modify(mid + 1, r, p << 1 | 1, self.tag);
            self.tag = 0;
        }
    }
    void push_up(int p) { self.minn = min(ls.minn, rs.minn); }
    void update(int x, int y, int l, int r, int p, int v) {
        if (x <= l && y >= r) {
            self.tag = max(self.tag, v);
            self.minn = max(self.minn, v);
            return;
        }
        push_down(l, r, p);
        int mid = (l + r) / 2;
        if (x <= mid) update(x, y, l, mid, p << 1, v);
        if (y > mid) update(x, y, mid + 1, r, p << 1 | 1, v);
        push_up(p);
    }
    int query(int x, int y, int l, int r, int p) {
        if (x <= l && y >= r) return self.minn;
        int mid = (l + r) / 2, res = INF2;
        push_down(l, r, p);
        if (x <= mid) res = min(res, query(x, y, l, mid, p << 1));
        if (y > mid) res = min(res, query(x, y, mid + 1, r, p << 1 | 1));
        return res;
    }
};

void dfs1(int u, int p) {
    sz[u] = 1, parent[u] = p;
    int maxx = 0;
    for (auto v : G[u]) {
        if (v == p) continue;
        dep[v] = dep[u] + 1;
        dfs1(v, u);
        sz[u] += sz[v];
        if (sz[v] > maxx) maxx = sz[v], son[u] = v;
    }
}

void dfs2(int u, int p) {
    dfn[u] = ++DFN, top[u] = p;
    if (!son[u]) return;
    dfs2(son[u], p);
    for (auto v : G[u]) {
        if (v == parent[u] || v == son[u]) continue;
        dfs2(v, v);
    }
}

SegTree tree;
void apply(int u, int v, int s) {
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u, v);
        tree.update(dfn[top[u]], dfn[u], 1, n, 1, s);
        u = parent[top[u]];
    }
    if (dep[u] > dep[v]) swap(u, v);
    tree.update(dfn[u] + 1, dfn[v], 1, n, 1, s);
}

int query(int u, int v) {
    int minn = INF2;
    while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u, v);
        minn = min(minn, tree.query(dfn[top[u]], dfn[u], 1, n, 1));
        u = parent[top[u]];
    }
    if (dep[u] > dep[v]) swap(u, v);
    minn = min(minn, tree.query(dfn[u] + 1, dfn[v], 1, n, 1));
    return minn;
}
int main() {
#ifdef LOCALLL
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].push_back(v), G[v].push_back(u);
        edges.push_back({u, v});
    }
    dfs1(1, 1), dfs2(1, 1);
    scanf("%d", &m);
    while (m--) {
        int a, b, s;
        scanf("%d%d%d", &a, &b, &s);
        apply(a, b, s), Qs.push_back({a, b, s});
    }
    for (auto& q : Qs) {
        if (query(q.a, q.b) != q.s) {
            printf("-1");
            return 0;
        }
    }
    for (auto& e : edges) {
        int v = dep[e.a] > dep[e.b] ? e.a : e.b;
        printf("%d ", tree.query(v, v, 1, n, 1));
    }
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <random>
#include <unordered_map>
typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
using namespace std;
const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 1e18;
const double INFD = 1e30;
const double EPS = 1e-6;
const double PI = 3.14159265;
const ll MOD = 20101009;
const int MAXN = 5005;
int n, m, k;

int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};
int dr2[8] = {1, 1, 1, -1, -1, -1, 0, 0};
int dc2[8] = {1, 0, -1, 1, 0, -1, 1, -1};
int CASE = 1;

struct Query {
    int a, b, s;
};
vector<int> G[MAXN];
vector<Query> Qs;
vector<Query> edges;
int parent[MAXN], dep[MAXN], val[MAXN];

void dfs(int u, int p) {
    val[u] = 1;
    for (auto v : G[u]) {
        if (v == p) continue;
        parent[v] = p, dep[v] = dep[u] + 1;
        dfs(v, u);
    }
}

void apply(int u, int v, int s) {
    if (dep[u] < dep[v]) swap(u, v);
    while (dep[u] > dep[v]) val[u] = max(val[u], s), u = parent[u];
    while (u != v) {
        val[u] = max(val[u], s), val[v] = max(val[v], s);
        u = parent[u], v = parent[v];
    }
}

int query(int u, int v) {
    if (dep[u] < dep[v]) swap(u, v);
    int maxx = INF2;
    while (dep[u] > dep[v]) maxx = min(maxx, val[u]), u = parent[u];
    while (u != v) {
        maxx = min(maxx, val[u]), maxx = min(maxx, val[u]);
        u = parent[u], v = parent[v];
    }
    return maxx;
}
int main() {
#ifdef LOCALLL
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    scanf("%d", &n);
    for (int i = 1; i < n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].push_back(v), G[v].push_back(u);
        edges.push_back({u, v});
    }
    dfs(1, 1);
    scanf("%d", &m);
    while (m--) {
        int a, b, s;
        scanf("%d%d%d", &a, &b, &s);
        apply(a, b, s), Qs.push_back({a, b, s});
    }
    for (auto& q : Qs) {
        if (query(q.a, q.b) != q.s) {
            printf("-1");
            return 0;
        }
    }
    for (auto& e : edges) {
        printf("%d ", val[dep[e.a] > dep[e.b] ? e.a : e.b]);
    }
    return 0;
}