#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
vector <int> point,rev,ans;
vector <int> g[MAXN],w[MAXN];
int dep[MAXN],du[MAXN],fa[MAXN],cnt[4];
map <int,bool> edge[MAXN];
void dfs(int x)
{
for(auto to:g[x])
if(to!=fa[x])
{
dep[to]=dep[x]+1;
fa[to]=x;
dfs(to);
}
}
void add(int x)
{
point[x-1]=1;
for(int i=0;i<g[x].size();i++)
{
int to=g[x][i], id=w[x][i];
if(edge[x][to])
rev[id]=1;
}
}
void work(int x)
{
if(ans[x-1])
{
for(int i=0;i<g[x].size();i++)
{
int to=g[x][i];
if(edge[x][to] || edge[to][x])
continue;
edge[to][x]=1, du[x]--, du[to]--;
}
}
else
{
for(int i=0;i<g[x].size();i++)
{
int to=g[x][i];
if(ans[to-1] && to!=fa[x])
{
edge[x][to]=1, du[x]--, du[to]--;
return;
}
}
edge[x][fa[x]]=1, du[x]--, du[fa[x]]--;
}
}
void Solve(int n,vector <int> a,vector <int> b)
{
for(int i=0;i<n-1;i++)
{
a[i]++, b[i]++;
g[a[i]].push_back(b[i]);
g[b[i]].push_back(a[i]);
w[b[i]].push_back(i);
w[a[i]].push_back(i);
du[a[i]]++, du[b[i]]++;
}
dep[1]=1, dfs(1);
for(int i=1;i<=30;i++)
{
memset(cnt,0,sizeof(cnt));
for(int j=1;j<=n;j++)
if(du[j])
cnt[dep[j]%3]++;
int need;
if(cnt[0]>=cnt[1] && cnt[0]>=cnt[2])
need=0;
else if(cnt[1]>=cnt[0] && cnt[1]>=cnt[2])
need=1;
else
need=2;
point.clear(), point.shrink_to_fit();
rev.clear(), rev.shrink_to_fit();
for(int i=1;i<=n;i++)
point.push_back(0);
for(int i=1;i<n;i++)
rev.push_back(0);
for(int j=1;j<=n;j++)
if(du[j] && dep[j]%3==need)
add(j);
ans=Query(rev,point);
for(int j=1;j<=n;j++)
if(du[j] && dep[j]%3==need)
work(j);
}
vector <int> res;
for(int i=0;i<n-1;i++)
res.push_back(edge[b[i]][a[i]]);
Answer(res);
}