#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,LL>
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pp pop_back
#define reg register
#define du double
#define qr read()
inline int read()
{
    char ch=' ';
    int f=1,x=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f*=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}

#define N 2333333
int n,q,s,ju;
int c[N],to[N],nxt[N];
LL len[N];
int cnt,tot;
LL dis[N];
int vis[N];
int rt1,rt2,Ls[N],Rs[N];

inline void add(int u,int v,LL l)
{
	cnt++;
	to[cnt] = v;
	len[cnt] = l;
	nxt[cnt] = c[u];
	c[u] = cnt;
}

void build1(int &p,int l,int r)
{
	if(l == r)
	{
		p = l;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build1(Ls[p],l,mid);
	build1(Rs[p],mid + 1,r);
	add(p,Ls[p],0);
	add(p,Rs[p],0);
}

void build2(int &p,int l,int r)

{
	if(l == r)
	{
		p = r;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build2(Ls[p],l,mid);
	build2(Rs[p],mid + 1,r);
	add(Ls[p],p,0);
	add(Rs[p],p,0);
}

void update(int &p,int l,int r,int now,int u,int v,LL t)
{
	if(u <= l && r <= v)
	{
		if(ju == 2)
		{
			add(now,p,t);
		}
		if(ju == 3)
		{
			add(p,now,t);
		}
		return;
	}
	int mid = l + r >> 1;
	if(u <= mid)update(Ls[p],l,mid,now,u,v,t);
	if(v > mid)update(Rs[p],mid + 1,r,now,u,v,t);
}

void dij()
{
	for(int i = 0; i <= N - 10000; i++)dis[i] = 1e18;
	dis[s] = 0;
	priority_queue<pa,vector<pa>,greater<pa> >q;
	q.push(mp(0,s));
	while(!q.empty())
	{
		pa t = q.top();
		q.pop();
		int now = t.ss;
		LL ll = t.ff;
		if(vis[now])continue;
		vis[now] = 1;
		for(int i = c[now];i;i = nxt[i])
		{
			int v = to[i];
			if(dis[v] > ll + len[i])
			{
				dis[v] = ll + len[i];
				q.push(mp(dis[v],v));
			}
		}
	}
}

int main()
{
	n = qr;
	q = qr;
	s = qr;
	tot = n;
	build1(rt1,1,n);
	build2(rt2,1,n);
	for(int i = 1; i <= q; i++)
	{
		ju = qr;
		if(ju == 1)
		{
			int u = qr,v = qr,w = qr;
			add(u,v,w);
		}
		else
		{
			int u = qr,l = qr,r = qr,v;
			cin >> v;
			if(ju == 2)
			{
				update(rt1,1,n,u,l,r,v);
			}
			if(ju == 3)
			{
				update(rt2,1,n,u,l,r,v);
			}
		}
	}
	dij();
	for(int i = 1; i <= n; i++)
	{
		if(dis[i] == 1e18)printf("-1 ");
		else printf("%lld ",dis[i]);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,LL>
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pp pop_back
#define reg register
#define du double
#define qr read()
inline int read()
{
    char ch=' ';
    int f=1,x=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f*=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}

#define N 2333333
int n,q,s,ju;
int c[N],to[N],nxt[N];
LL len[N];
int cnt,tot;
LL dis[N];
int vis[N];
int rt1,rt2,Ls[N],Rs[N];

inline void add(int u,int v,LL l)
{
	cnt++;
	to[cnt] = v;
	len[cnt] = l;
	nxt[cnt] = c[u];
	c[u] = cnt;
}

void build1(int &p,int l,int r)
{
	if(l == r)
	{
		p = l;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build1(Ls[p],l,mid);
	build1(Rs[p],mid + 1,r);
	add(p,Ls[p],0);
	add(p,Rs[p],0);
}

void build2(int &p,int l,int r)

{
	if(l == r)
	{
		p = r;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build2(Ls[p],l,mid);
	build2(Rs[p],mid + 1,r);
	add(Ls[p],p,0);
	add(Rs[p],p,0);
}

void update(int &p,int l,int r,int now,int u,int v,LL t)
{
	if(u <= l && r <= v)
	{
		if(ju == 2)
		{
			add(now,p,t);
		}
		if(ju == 3)
		{
			add(p,now,t);
		}
		return;
	}
	int mid = l + r >> 1;
	if(u <= mid)update(Ls[p],l,mid,now,u,v,t);
	if(v > mid)update(Rs[p],mid + 1,r,now,u,v,t);
}

void dij()
{
	for(int i = 0; i <= N - 10000; i++)dis[i] = 1e18;
	dis[s] = 0;
	priority_queue<pa,vector<pa>,greater<pa> >q;
	q.push(mp(0,s));
	while(!q.empty())
	{
		pa t = q.top();
		q.pop();
		int now = t.ss;
		LL ll = t.ff;
		if(vis[now])continue;
		vis[now] = 1;
		for(int i = c[now];i;i = nxt[i])
		{
			int v = to[i];
			if(dis[v] > ll + len[i])
			{
				dis[v] = ll + len[i];
				q.push(mp(dis[v],v));
			}
		}
	}
}

int main()
{
	n = qr;
	q = qr;
	s = qr;
	tot = n;
	build1(rt1,1,n);
	build2(rt2,1,n);
	for(int i = 1; i <= q; i++)
	{
		ju = qr;
		if(ju == 1)
		{
			int u = qr,v = qr,w = qr;
			add(u,v,w);
		}
		else
		{
			int u = qr,l = qr,r = qr;
			cin >> v;
			if(ju == 2)
			{
				update(rt1,1,n,u,l,r,v);
			}
			if(ju == 3)
			{
				update(rt2,1,n,u,l,r,v);
			}
		}
	}
	dij();
	for(int i = 1; i <= n; i++)
	{
		if(dis[i] == 1e18)printf("-1 ");
		else printf("%lld ",dis[i]);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,LL>
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pp pop_back
#define reg register
#define du double
#define qr read()
inline int read()
{
    char ch=' ';
    int f=1,x=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f*=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}

#define N 2333333
int n,q,s,ju;
int c[N],to[N],nxt[N],len[N];
int cnt,tot;
LL dis[N];
int vis[N];
int rt1,rt2,Ls[N],Rs[N];

inline void add(int u,int v,int l)
{
	cnt++;
	to[cnt] = v;
	len[cnt] = l;
	nxt[cnt] = c[u];
	c[u] = cnt;
}

void build1(int &p,int l,int r)
{
	if(l == r)
	{
		p = l;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build1(Ls[p],l,mid);
	build1(Rs[p],mid + 1,r);
	add(p,Ls[p],0);
	add(p,Rs[p],0);
}

void build2(int &p,int l,int r)

{
	if(l == r)
	{
		p = r;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build2(Ls[p],l,mid);
	build2(Rs[p],mid + 1,r);
	add(Ls[p],p,0);
	add(Rs[p],p,0);
}

void update(int &p,int l,int r,int now,int u,int v,int t)
{
	if(u <= l && r <= v)
	{
		if(ju == 2)
		{
			add(now,p,t);
		}
		if(ju == 3)
		{
			add(p,now,t);
		}
		return;
	}
	int mid = l + r >> 1;
	if(u <= mid)update(Ls[p],l,mid,now,u,v,t);
	if(v > mid)update(Rs[p],mid + 1,r,now,u,v,t);
}

void dij()
{
	for(int i = 0; i <= N - 10000; i++)dis[i] = 1e18;
	dis[s] = 0;
	priority_queue<pa,vector<pa>,greater<pa> >q;
	q.push(mp(0,s));
	while(!q.empty())
	{
		pa t = q.top();
		q.pop();
		int now = t.ss;
		int ll = t.ff;
		if(vis[now])continue;
		vis[now] = 1;
		for(int i = c[now];i;i = nxt[i])
		{
			int v = to[i];
			if(dis[v] > ll + len[i])
			{
				dis[v] = ll + len[i];
				q.push(mp(dis[v],v));
			}
		}
	}
}

int main()
{
	n = qr;
	q = qr;
	s = qr;
	tot = n;
	build1(rt1,1,n);
	build2(rt2,1,n);
	for(int i = 1; i <= q; i++)
	{
		ju = qr;
		if(ju == 1)
		{
			int u = qr,v = qr,w = qr;
			add(u,v,w);
		}
		else
		{
			int u = qr,l = qr,r = qr,v = qr;
			if(ju == 2)
			{
				update(rt1,1,n,u,l,r,v);
			}
			if(ju == 3)
			{
				update(rt2,1,n,u,l,r,v);
			}
		}
	}
	dij();
	for(int i = 1; i <= n; i++)
	{
		if(dis[i] == 1e18)printf("-1 ");
		else printf("%d ",dis[i]);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
#define ff first
#define ss second
#define mp make_pair<int,int>
#define pb push_back
#define pp pop_back
#define reg register
#define du double
#define qr read()
inline int read()
{
    char ch=' ';
    int f=1,x=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f*=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}

#define N 2333333
int n,q,s,ju;
int c[N],to[N],nxt[N],len[N];
int cnt,dis[N],tot;
int vis[N];
int rt1,rt2,Ls[N],Rs[N];

inline void add(int u,int v,int l)
{
	cnt++;
	to[cnt] = v;
	len[cnt] = l;
	nxt[cnt] = c[u];
	c[u] = cnt;
}

void build1(int &p,int l,int r)
{
	if(l == r)
	{
		p = l;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build1(Ls[p],l,mid);
	build1(Rs[p],mid + 1,r);
	add(p,Ls[p],0);
	add(p,Rs[p],0);
}

void build2(int &p,int l,int r)
{
	if(l == r)
	{
		p = r;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build2(Ls[p],l,mid);
	build2(Rs[p],mid + 1,r);
	add(Ls[p],p,0);
	add(Rs[p],p,0);
}

void update(int &p,int l,int r,int now,int u,int v,int t)
{
	if(u <= l && r <= v)
	{
		if(ju == 2)
		{
			add(now,p,t);
		}
		if(ju == 3)
		{
			add(p,now,t);
		}
		return;
	}
	int mid = l + r >> 1;
	if(u <= mid)update(Ls[p],l,mid,now,u,v,t);
	if(v > mid)update(Rs[p],mid + 1,r,now,u,v,t);
}

void dij()
{
	memset(dis,0x3f3f3f3f,sizeof(dis));
	dis[s] = 0;
	priority_queue<pa,vector<pa>,greater<pa> >q;
	q.push(mp(0,s));
	while(!q.empty())
	{
		pa t = q.top();
		q.pop();
		int now = t.ss;
		int ll = t.ff;
		if(vis[now])continue;
		vis[now] = 1;
		for(int i = c[now];i;i = nxt[i])
		{
			int v = to[i];
			if(dis[v] > ll + len[i])
			{
				dis[v] = ll + len[i];
				q.push(mp(dis[v],v));
			}
		}
	}
}

int main()
{
	n = qr;
	q = qr;
	s = qr;
	tot = n;
	build1(rt1,1,n);
	build2(rt2,1,n);
	for(int i = 1; i <= q; i++)
	{
		ju = qr;
		if(ju == 1)
		{
			int u = qr,v = qr,w = qr;
			add(u,v,w);
		}
		else
		{
			int u = qr,l = qr,r = qr,v = qr;
			if(ju == 2)
			{
				update(rt1,1,n,u,l,r,v);
			}
			if(ju == 3)
			{
				update(rt2,1,n,u,l,r,v);
			}
		}
	}
	dij();
	for(int i = 1; i <= n; i++)
	{
		if(dis[i] > 1e9)printf("-1 ");
		else printf("%d ",dis[i]);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pp pop_back
#define reg register
#define du double
#define qr read()
inline int read()
{
    char ch=' ';
    int f=1,x=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f*=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}

#define N 2333333
int n,q,s,ju;
int c[N],to[N],nxt[N],len[N];
int cnt,dis[N],tot;
int vis[N];
int rt1,rt2,Ls[N],Rs[N];

inline void add(int u,int v,int l)
{
	cnt++;
	to[cnt] = v;
	len[cnt] = l;
	nxt[cnt] = c[u];
	c[u] = cnt;
}

void build1(int &p,int l,int r)
{
	if(l == r)
	{
		p = l;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build1(Ls[p],l,mid);
	build1(Rs[p],mid + 1,r);
	add(p,Ls[p],0);
	add(p,Rs[p],0);
}

void build2(int &p,int l,int r)

{
	if(l == r)
	{
		p = r;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build2(Ls[p],l,mid);
	build2(Rs[p],mid + 1,r);
	add(Ls[p],p,0);
	add(Rs[p],p,0);
}

void update(int &p,int l,int r,int now,int u,int v,int t)
{
	if(u <= l && r <= v)
	{
		if(ju == 2)
		{
			add(now,p,t);
		}
		if(ju == 3)
		{
			add(p,now,t);
		}
		return;
	}
	int mid = l + r >> 1;
	if(u <= mid)update(Ls[p],l,mid,now,u,v,t);
	if(v > mid)update(Rs[p],mid + 1,r,now,u,v,t);
}

void dij()
{
	memset(dis,0x3f3f3f3f,sizeof(dis));
	dis[s] = 0;
	priority_queue<pa,vector<pa>,greater<pa> >q;
	q.push(mp(0,s));
	while(!q.empty())
	{
		pa t = q.top();
		q.pop();
		int now = t.ss;
		int ll = t.ff;
		if(vis[now])continue;
		vis[now] = 1;
		for(int i = c[now];i;i = nxt[i])
		{
			int v = to[i];
			if(dis[v] > ll + len[i])
			{
				dis[v] = ll + len[i];
				q.push(mp(dis[v],v));
			}
		}
	}
}

int main()
{
	n = qr;
	q = qr;
	s = qr;
	tot = n;
	build1(rt1,1,n);
	build2(rt2,1,n);
	for(int i = 1; i <= q; i++)
	{
		ju = qr;
		if(ju == 1)
		{
			int u = qr,v = qr,w = qr;
			add(u,v,w);
		}
		else
		{
			int u = qr,l = qr,r = qr,v = qr;
			if(ju == 2)
			{
				update(rt1,1,n,u,l,r,v);
			}
			if(ju == 3)
			{
				update(rt2,1,n,u,l,r,v);
			}
		}
	}
	dij();
	for(int i = 1; i <= n; i++)
	{
		if(dis[i] > 1e9)printf("-1 ");
		else printf("%d ",dis[i]);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,LL>
#define ff first
#define ss second
#define mp make_pair
#define pb push_back
#define pp pop_back
#define reg register
#define du double
#define qr read()
inline int read()
{
    char ch=' ';
    int f=1,x=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f*=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}

#define N 2333333
int n,q,s,ju;
int c[N],to[N],nxt[N];
LL len[N];
int cnt,tot;
LL dis[N];
int vis[N];
int rt1,rt2,Ls[N],Rs[N];

inline void add(int u,int v,LL l)
{
	cnt++;
	to[cnt] = v;
	len[cnt] = l;
	nxt[cnt] = c[u];
	c[u] = cnt;
}

void build1(int &p,int l,int r)
{
	if(l == r)
	{
		p = l;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build1(Ls[p],l,mid);
	build1(Rs[p],mid + 1,r);
	add(p,Ls[p],0);
	add(p,Rs[p],0);
}

void build2(int &p,int l,int r)

{
	if(l == r)
	{
		p = r;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build2(Ls[p],l,mid);
	build2(Rs[p],mid + 1,r);
	add(Ls[p],p,0);
	add(Rs[p],p,0);
}

void update(int &p,int l,int r,int now,int u,int v,LL t)
{
	if(u <= l && r <= v)
	{
		if(ju == 2)
		{
			add(now,p,t);
		}
		if(ju == 3)
		{
			add(p,now,t);
		}
		return;
	}
	int mid = l + r >> 1;
	if(u <= mid)update(Ls[p],l,mid,now,u,v,t);
	if(v > mid)update(Rs[p],mid + 1,r,now,u,v,t);
}

void dij()
{
	for(int i = 0; i <= N - 10000; i++)dis[i] = 1e18;
	dis[s] = 0;
	priority_queue<pa,vector<pa>,greater<pa> >q;
	q.push(mp(0,s));
	while(!q.empty())
	{
		pa t = q.top();
		q.pop();
		int now = t.ss;
		LL ll = t.ff;
		if(vis[now])continue;
		vis[now] = 1;
		for(int i = c[now];i;i = nxt[i])
		{
			int v = to[i];
			if(dis[v] > ll + len[i])
			{
				dis[v] = ll + len[i];
				q.push(mp(dis[v],v));
			}
		}
	}
}

int main()
{
	n = qr;
	q = qr;
	s = qr;
	tot = n;
	build1(rt1,1,n);
	build2(rt2,1,n);
	for(int i = 1; i <= q; i++)
	{
		ju = qr;
		if(ju == 1)
		{
			int u = qr,v = qr,w = qr;
			add(u,v,w);
		}
		else
		{
			int u = qr,l = qr,r = qr;
			LL v;
			cin >> v;
			if(ju == 2)
			{
				update(rt1,1,n,u,l,r,v);
			}
			if(ju == 3)
			{
				update(rt2,1,n,u,l,r,v);
			}
		}
	}
	dij();
	for(int i = 1; i <= n; i++)
	{
		if(dis[i] == 1e18)printf("-1 ");
		else printf("%lld ",dis[i]);
	}
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;
#define LL long long
#define pa pair<int,int>
#define ff first
#define ss second
#define mp make_pair<int,int>
#define pb push_back
#define pp pop_back
#define reg register
#define du double
#define qr read()
inline int read()
{
    char ch=' ';
    int f=1,x=0;
    while(!isdigit(ch)){ch=getchar();if(ch=='-')f*=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}

#define N 2333333
int n,q,s,ju;
int c[N],to[N],nxt[N],len[N];
int cnt,dis[N],tot;
int vis[N];
int rt1,rt2,Ls[N],Rs[N];

inline void add(int u,int v,int l)
{
	cnt++;
	to[cnt] = v;
	len[cnt] = l;
	nxt[cnt] = c[u];
	c[u] = cnt;
}

void build1(int &p,int l,int r)
{
	if(l == r)
	{
		p = l;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build1(Ls[p],l,mid);
	build1(Rs[p],mid + 1,r);
	add(p,Ls[p],0);
	add(p,Rs[p],0);
}

void build2(int &p,int l,int r)
{
	if(l == r)
	{
		p = r;
		return;
	}
	p = ++tot;
	int mid = l + r >> 1;
	build2(Ls[p],l,mid);
	build2(Rs[p],mid + 1,r);
	add(Ls[p],p,0);
	add(Rs[p],p,0);
}

void update(int &p,int l,int r,int now,int u,int v,int t)
{
	if(u <= l && r <= v)
	{
		if(ju == 2)
		{
			add(now,p,t);
		}
		if(ju == 3)
		{
			add(p,now,t);
		}
		return;
	}
	int mid = l + r >> 1;
	if(u <= mid)update(Ls[p],l,mid,now,u,v,t);
	if(v > mid)update(Rs[p],mid + 1,r,now,u,v,t);
}

void dij()
{
	memset(dis,0x3f3f3f3f,sizeof(dis));
	dis[s] = 0;
	priority_queue<pa,vector<pa>,greater<pa> >q;
	q.push(mp(0,s));
	while(!q.empty())
	{
		pa t = q.top();
		q.pop();
		int now = t.ss;
		int ll = t.ff;
		if(vis[now])continue;
		vis[now] = 1;
		for(int i = c[now];i;i = nxt[i])
		{
			int v = to[i];
			if(dis[v] > ll + len[i])
			{
				dis[v] = ll + len[i];
				q.push(mp(dis[v],v));
			}
		}
	}
}

int main()
{
	n = qr;
	q = qr;
	s = qr;
	tot = n;
	build1(rt1,1,n);
	build2(rt2,1,n);
	for(int i = 1; i <= q; i++)
	{
		ju = qr;
		if(ju == 1)
		{
			int u = qr,v = qr,w = qr;
			add(u,v,w);
		}
		else
		{
			int u = qr,l = qr,r = qr,v = qr;
			if(ju == 2)
			{
				update(rt1,1,n,u,l,r,v);
			}
			if(ju == 3)
			{
				update(rt2,1,n,u,l,r,v);
			}
		}
	}
	dij();
	for(int i = 1; i <= n; i++)
	{
		if(dis[i] > 1e9)printf("-1 ");
		else printf("%d ",dis[i]);
	}
}


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,m,p,k,cnt,t=N*8+5;
struct node{
	int to,next,wt;
}edge[N*12];
int head[N*12];
void add(int u,int v,int w)
{
	edge[++k].to=v;
	edge[k].next=head[u];
	edge[k].wt=w;
	head[u]=k;
}
struct segment_tree{
	int l,r;
}tree[N*12];
int leaf[N*12];//0:出树，1:入树
void build(int id,int l,int r,int opt)
{
	tree[id].l=l,tree[id].r=r;
	if(tree[id].l==tree[id].r){
		if(opt)add(id+4*N,id,0);
		else leaf[l]=id;
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	opt?add(id+N*4,id*2+N*4,0),add(id+N*4,id*2+1+N*4,0):add(id*2,id,0),add(id*2+1,id,0);
	build(id*2,l,mid,opt),build(id*2+1,mid+1,r,opt);
}
void update_in(int id,int l,int r,int p)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(p,id+4*N,0);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_in(id*2,l,r,p);
	else if(l>mid)update_in(id*2+1,l,r,p);
	else update_in(id*2,l,mid,p),update_in(id*2+1,mid+1,r,p);
}
void update_out(int id,int l,int r,int p,int wt)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(id,p,wt);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_out(id*2,l,r,p,wt);
	else if(l>mid)update_out(id*2+1,l,r,p,wt);
	else update_out(id*2,l,mid,p,wt),update_out(id*2+1,mid+1,r,p,wt);
}
priority_queue<pair<int,int> >q;
int book[N*12],dis[N*12];
void dij(int s)
{
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size()){
		int u=q.top().second;
		q.pop();
		if(book[u])continue;
		book[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(book[v]==0&&dis[v]>dis[u]+edge[i].wt){
				dis[v]=dis[u]+edge[i].wt;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&p);
	build(1,1,n,0),build(1,1,n,1);
	for(int i=1,opt,a,b,c,w;i<=m;i++){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%d",&a,&b,&w);
			update_out(1,a,a,++t,w),update_in(1,b,b,t);
		}else if(opt==2){
			scanf("%d%d%d%d",&a,&b,&c,&w);
			update_out(1,a,a,++t,w),update_in(1,b,c,t);
		}else{
			scanf("%d%d%d%d",&c,&a,&b,&w);
			update_out(1,a,b,++t,w),update_in(1,c,c,t);
		}

	}
	dij(leaf[p]);
	for(int i=1;i<=n;i++)
		printf("%d ",dis[leaf[i]]);
	return 0;
}


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=3e5+10;
int n,m,p,k,cnt,t=N*8+5;
struct node{
	int to,next;
	ll wt;
}edge[N*12];
int head[N*12];
void add(int u,int v,ll w)
{
	edge[++k].to=v;
	edge[k].next=head[u];
	edge[k].wt=w;
	head[u]=k;
}
struct segment_tree{
	int l,r;
}tree[N*12];
int leaf[N*12];//0:出树，1:入树
void build(int id,int l,int r,int opt)
{
	tree[id].l=l,tree[id].r=r;
	if(tree[id].l==tree[id].r){
		if(opt)add(id+4*N,id,0);
		else leaf[l]=id;
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	opt?add(id+N*4,id*2+N*4,0),add(id+N*4,id*2+1+N*4,0):add(id*2,id,0),add(id*2+1,id,0);
	build(id*2,l,mid,opt),build(id*2+1,mid+1,r,opt);
}
void update_in(int id,int l,int r,int p)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(p,id+4*N,0);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_in(id*2,l,r,p);
	else if(l>mid)update_in(id*2+1,l,r,p);
	else update_in(id*2,l,mid,p),update_in(id*2+1,mid+1,r,p);
}
void update_out(int id,int l,int r,int p,ll wt)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(id,p,wt);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_out(id*2,l,r,p,wt);
	else if(l>mid)update_out(id*2+1,l,r,p,wt);
	else update_out(id*2,l,mid,p,wt),update_out(id*2+1,mid+1,r,p,wt);
}
priority_queue<pair<ll,int> >q;
int book[N*12];
ll dis[N*12];
void dij(int s)
{
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size()){
		int u=q.top().second;
		q.pop();
		if(book[u])continue;
		book[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(book[v]==0&&dis[v]>dis[u]+edge[i].wt){
				dis[v]=dis[u]+edge[i].wt;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&p);
	build(1,1,n,0),build(1,1,n,1);
	for(int i=1,opt,a,b,c;i<=m;i++){
		ll w;
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%lld",&a,&b,&w);
			update_out(1,a,a,++t,w),update_in(1,b,b,t);
		}else if(opt==2){
			scanf("%d%d%d%lld",&a,&b,&c,&w);
			update_out(1,a,a,++t,w),update_in(1,b,c,t);
		}else{
			scanf("%d%d%d%lld",&c,&a,&b,&w);
			update_out(1,a,b,++t,w),update_in(1,c,c,t);
		}

	}
	dij(leaf[p]);
	for(int i=1;i<=n;i++)
		printf("%lld ",dis[leaf[i]]==0x3f3f3f3f3f3f3f3fll?-1:dis[leaf[i]]);
	return 0;
}


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int N=1e5+10;
int n,m,p,k,cnt,t=N*8+5;
struct node{
	int to,next,wt;
}edge[N*12];
int head[N*12];
void add(int u,int v,int w)
{
	edge[++k].to=v;
	edge[k].next=head[u];
	edge[k].wt=w;
	head[u]=k;
}
struct segment_tree{
	int l,r;
}tree[N*12];
int leaf[N*12];//0:出树，1:入树
void build(int id,int l,int r,int opt)
{
	tree[id].l=l,tree[id].r=r;
	if(tree[id].l==tree[id].r){
		if(opt)add(id+4*N,id,0);
		else leaf[l]=id;
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	opt?add(id+N*4,id*2+N*4,0),add(id+N*4,id*2+1+N*4,0):add(id*2,id,0),add(id*2+1,id,0);
	build(id*2,l,mid,opt),build(id*2+1,mid+1,r,opt);
}
void update_in(int id,int l,int r,int p)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(p,id+4*N,0);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_in(id*2,l,r,p);
	else if(l>mid)update_in(id*2+1,l,r,p);
	else update_in(id*2,l,mid,p),update_in(id*2+1,mid+1,r,p);
}
void update_out(int id,int l,int r,int p,int wt)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(id,p,wt);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_out(id*2,l,r,p,wt);
	else if(l>mid)update_out(id*2+1,l,r,p,wt);
	else update_out(id*2,l,mid,p,wt),update_out(id*2+1,mid+1,r,p,wt);
}
priority_queue<pair<int,int> >q;
int book[N*12],dis[N*12];
void dij(int s)
{
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size()){
		int u=q.top().second;
		q.pop();
		if(book[u])continue;
		book[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(book[v]==0&&dis[v]>dis[u]+edge[i].wt){
				dis[v]=dis[u]+edge[i].wt;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
main(){
	scanf("%lld%lld%lld",&n,&m,&p);
	build(1,1,n,0),build(1,1,n,1);
	for(int i=1,opt,a,b,c,w;i<=m;i++){
		scanf("%lld",&opt);
		if(opt==1){
			scanf("%lld%lld%lld",&a,&b,&w);
			update_out(1,a,a,++t,w),update_in(1,b,b,t);
		}else if(opt==2){
			scanf("%lld%lld%lld%lld",&a,&b,&c,&w);
			update_out(1,a,a,++t,w),update_in(1,b,c,t);
		}else{
			scanf("%lld%lld%lld%lld",&c,&a,&b,&w);
			update_out(1,a,b,++t,w),update_in(1,c,c,t);
		}

	}
	dij(leaf[p]);
	for(int i=1;i<=n;i++)
		printf("%lld ",dis[leaf[i]]==0x3f3f3f3f3f3f3f3f?-1:dis[leaf[i]]);
	return 0;
}


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,m,p,k,cnt,t=N*8+5;
struct node{
	int to,next,wt;
}edge[N*12];
int head[N*12];
void add(int u,int v,int w)
{
	edge[++k].to=v;
	edge[k].next=head[u];
	edge[k].wt=w;
	head[u]=k;
}
struct segment_tree{
	int l,r;
}tree[N*12];
int leaf[N*12];//0:出树，1:入树
void build(int id,int l,int r,int opt)
{
	tree[id].l=l,tree[id].r=r;
	if(tree[id].l==tree[id].r){
		if(opt)add(id+4*N,id,0);
		else leaf[l]=id;
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	opt?add(id+N*4,id*2+N*4,0),add(id+N*4,id*2+1+N*4,0):add(id*2,id,0),add(id*2+1,id,0);
	build(id*2,l,mid,opt),build(id*2+1,mid+1,r,opt);
}
void update_in(int id,int l,int r,int p)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(p,id+4*N,0);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_in(id*2,l,r,p);
	else if(l>mid)update_in(id*2+1,l,r,p);
	else update_in(id*2,l,mid,p),update_in(id*2+1,mid+1,r,p);
}
void update_out(int id,int l,int r,int p,int wt)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(id,p,wt);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_out(id*2,l,r,p,wt);
	else if(l>mid)update_out(id*2+1,l,r,p,wt);
	else update_out(id*2,l,mid,p,wt),update_out(id*2+1,mid+1,r,p,wt);
}
priority_queue<pair<int,int> >q;
int book[N*12],dis[N*12];
void dij(int s)
{
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size()){
		int u=q.top().second;
		q.pop();
		if(book[u])continue;
		book[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(book[v]==0&&dis[v]>dis[u]+edge[i].wt){
				dis[v]=dis[u]+edge[i].wt;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&p);
	build(1,1,n,0),build(1,1,n,1);
	for(int i=1,opt,a,b,c,w;i<=m;i++){
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%d",&a,&b,&w);
			update_out(1,a,a,++t,w),update_in(1,b,b,t);
		}else if(opt==2){
			scanf("%d%d%d%d",&a,&b,&c,&w);
			update_out(1,a,a,++t,w),update_in(1,b,c,t);
		}else{
			scanf("%d%d%d%d",&c,&a,&b,&w);
			update_out(1,a,b,++t,w),update_in(1,c,c,t);
		}

	}
	dij(leaf[p]);
	for(int i=1;i<=n;i++)
		printf("%d ",dis[leaf[i]]==0x3f3f3f3f?-1:dis[leaf[i]]);
	return 0;
}


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lxl;
const int N=3e5+10;
int n,m,p,k,cnt,t=N*8+5;
struct node{
	int to,next;
	lxl wt;
}edge[N*12];
int head[N*12];
void add(int u,int v,lxl w)
{
	edge[++k].to=v;
	edge[k].next=head[u];
	edge[k].wt=w;
	head[u]=k;
}
struct segment_tree{
	int l,r;
}tree[N*12];
int leaf[N*12];//0:出树，1:入树
void build(int id,int l,int r,int opt)
{
	tree[id].l=l,tree[id].r=r;
	if(tree[id].l==tree[id].r){
		if(opt)add(id+4*N,id,0);
		else leaf[l]=id;
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	opt?add(id+N*4,id*2+N*4,0),add(id+N*4,id*2+1+N*4,0):add(id*2,id,0),add(id*2+1,id,0);
	build(id*2,l,mid,opt),build(id*2+1,mid+1,r,opt);
}
void update_in(int id,int l,int r,int p)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(p,id+4*N,0);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_in(id*2,l,r,p);
	else if(l>mid)update_in(id*2+1,l,r,p);
	else update_in(id*2,l,mid,p),update_in(id*2+1,mid+1,r,p);
}
void update_out(int id,int l,int r,int p,lxl wt)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(id,p,wt);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_out(id*2,l,r,p,wt);
	else if(l>mid)update_out(id*2+1,l,r,p,wt);
	else update_out(id*2,l,mid,p,wt),update_out(id*2+1,mid+1,r,p,wt);
}
priority_queue<pair<lxl,int> >q;
int book[N*12];
lxl dis[N*12];
void dij(int s)
{
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size()){
		int u=q.top().second;
		q.pop();
		if(book[u])continue;
		book[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(book[v]==0&&dis[v]>dis[u]+edge[i].wt){
				dis[v]=dis[u]+edge[i].wt;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
main(){
	scanf("%d%d%d",&n,&m,&p);
	build(1,1,n,0),build(1,1,n,1);
	for(int i=1,opt,a,b,c;i<=m;i++){
		lxl w;
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%lld",&a,&b,&w);
			update_out(1,a,a,++t,w),update_in(1,b,b,t);
		}else if(opt==2){
			scanf("%d%d%d%lld",&a,&b,&c,&w);
			update_out(1,a,a,++t,w),update_in(1,b,c,t);
		}else{
			scanf("%d%d%d%lld",&c,&a,&b,&w);
			update_out(1,a,b,++t,w),update_in(1,c,c,t);
		}

	}
	dij(leaf[p]);
	for(int i=1;i<=n;i++)
		printf("%lld ",dis[leaf[i]]==0x3f3f3f3f3f3f3f3fll?-1:dis[leaf[i]]);
	return 0;
}


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int N=5e5+10;
int n,m,p,k,cnt,t=N*8+5;
struct node{
	int to,next,wt;
}edge[N*12];
int head[N*12];
void add(int u,int v,int w)
{
	edge[++k].to=v;
	edge[k].next=head[u];
	edge[k].wt=w;
	head[u]=k;
}
struct segment_tree{
	int l,r;
}tree[N*12];
int leaf[N*12];//0:出树，1:入树
void build(int id,int l,int r,int opt)
{
	tree[id].l=l,tree[id].r=r;
	if(tree[id].l==tree[id].r){
		if(opt)add(id+4*N,id,0);
		else leaf[l]=id;
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	opt?add(id+N*4,id*2+N*4,0),add(id+N*4,id*2+1+N*4,0):add(id*2,id,0),add(id*2+1,id,0);
	build(id*2,l,mid,opt),build(id*2+1,mid+1,r,opt);
}
void update_in(int id,int l,int r,int p)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(p,id+4*N,0);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_in(id*2,l,r,p);
	else if(l>mid)update_in(id*2+1,l,r,p);
	else update_in(id*2,l,mid,p),update_in(id*2+1,mid+1,r,p);
}
void update_out(int id,int l,int r,int p,int wt)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(id,p,wt);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_out(id*2,l,r,p,wt);
	else if(l>mid)update_out(id*2+1,l,r,p,wt);
	else update_out(id*2,l,mid,p,wt),update_out(id*2+1,mid+1,r,p,wt);
}
priority_queue<pair<int,int> >q;
int book[N*12],dis[N*12];
void dij(int s)
{
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size()){
		int u=q.top().second;
		q.pop();
		if(book[u])continue;
		book[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(book[v]==0&&dis[v]>dis[u]+edge[i].wt){
				dis[v]=dis[u]+edge[i].wt;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
main(){
	scanf("%lld%lld%lld",&n,&m,&p);
	build(1,1,n,0),build(1,1,n,1);
	for(int i=1,opt,a,b,c,w;i<=m;i++){
		scanf("%lld",&opt);
		if(opt==1){
			scanf("%lld%lld%lld",&a,&b,&w);
			update_out(1,a,a,++t,w),update_in(1,b,b,t);
		}else if(opt==2){
			scanf("%lld%lld%lld%lld",&a,&b,&c,&w);
			update_out(1,a,a,++t,w),update_in(1,b,c,t);
		}else{
			scanf("%lld%lld%lld%lld",&c,&a,&b,&w);
			update_out(1,a,b,++t,w),update_in(1,c,c,t);
		}

	}
	dij(leaf[p]);
	for(int i=1;i<=n;i++)
		printf("%lld ",dis[leaf[i]]==0x3f3f3f3f3f3f3f3f?-1:dis[leaf[i]]);
	return 0;
}


#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lxl;
const int N=3e5+10;
int n,m,p,k,cnt,t=N*8+5;
struct node{
	int to,next;
	lxl wt;
}edge[N*12];
int head[N*12];
void add(int u,int v,lxl w)
{
	edge[++k].to=v;
	edge[k].next=head[u];
	edge[k].wt=w;
	head[u]=k;
}
struct segment_tree{
	int l,r;
}tree[N*12];
int leaf[N*12];//0:出树，1:入树
void build(int id,int l,int r,int opt)
{
	tree[id].l=l,tree[id].r=r;
	if(tree[id].l==tree[id].r){
		if(opt)add(id+4*N,id,0);
		else leaf[l]=id;
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	opt?add(id+N*4,id*2+N*4,0),add(id+N*4,id*2+1+N*4,0):add(id*2,id,0),add(id*2+1,id,0);
	build(id*2,l,mid,opt),build(id*2+1,mid+1,r,opt);
}
void update_in(int id,int l,int r,int p)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(p,id+4*N,0);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_in(id*2,l,r,p);
	else if(l>mid)update_in(id*2+1,l,r,p);
	else update_in(id*2,l,mid,p),update_in(id*2+1,mid+1,r,p);
}
void update_out(int id,int l,int r,int p,lxl wt)
{
	if(tree[id].l==l&&tree[id].r==r){
		add(id,p,wt);
		return ;
	}
	int mid=(tree[id].l+tree[id].r)/2;
	if(r<=mid)update_out(id*2,l,r,p,wt);
	else if(l>mid)update_out(id*2+1,l,r,p,wt);
	else update_out(id*2,l,mid,p,wt),update_out(id*2+1,mid+1,r,p,wt);
}
priority_queue<pair<lxl,int> >q;
int book[N*12];
lxl dis[N*12];
void dij(int s)
{
	memset(dis,0x3f,sizeof dis);
	dis[s]=0;
	q.push(make_pair(0,s));
	while(q.size()){
		int u=q.top().second;
		q.pop();
		if(book[u])continue;
		book[u]=1;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].to;
			if(book[v]==0&&dis[v]>dis[u]+edge[i].wt){
				dis[v]=dis[u]+edge[i].wt;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
main(){
	scanf("%d%d%d",&n,&m,&p);
	build(1,1,n,0),build(1,1,n,1);
	for(int i=1,opt,a,b,c;i<=m;i++){
		lxl w;
		scanf("%d",&opt);
		if(opt==1){
			scanf("%d%d%lld",&a,&b,&w);
			update_out(1,a,a,++t,w),update_in(1,b,b,t);
		}else if(opt==2){
			scanf("%d%d%d%lld",&a,&b,&c,&w);
			update_out(1,a,a,++t,w),update_in(1,b,c,t);
		}else{
			scanf("%d%d%d%d",&c,&a,&b,&w);
			update_out(1,a,b,++t,w),update_in(1,c,c,t);
		}

	}
	dij(leaf[p]);
	for(int i=1;i<=n;i++)
		printf("%lld ",dis[leaf[i]]==0x3f3f3f3f3f3f3f3fll?-1:dis[leaf[i]]);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 100010
#define LL long long
struct edge
{
    LL to, next, w;
} e[N << 4];
LL head[N], ecnt, ncnt;
inline void adde(LL from, LL to, LL w)
{
    e[++ecnt] = (edge){to, head[from], w}, head[from] = ecnt;
}
struct node
{
    LL l, r, id;
} T[N << 2], T2[N << 2];
LL id[N];
void build1(LL rt, LL l, LL r)
{
    T[rt].l = l, T[rt].r = r, T[rt].id = ++ncnt;
    if (l == r)
    {
        id[l] = ncnt;
        return;
    }
    LL mid = (l + r) >> 1;
    build1(rt << 1, l, mid), build1(rt << 1 | 1, mid + 1, r);
    adde(T[rt << 1].id, T[rt].id, 0), adde(T[rt << 1 | 1].id, T[rt].id, 0);
}
void build2(LL rt, LL l, LL r)
{
    T2[rt].l = l, T2[rt].r = r;
    if (l == r)
    {
        T2[rt].id = id[l];
        return;
    }
    T2[rt].id = ++ncnt;
    LL mid = (l + r) >> 1;
    build2(rt << 1, l, mid), build2(rt << 1 | 1, mid + 1, r);
    adde(T2[rt].id, T2[rt << 1].id, 0), adde(T2[rt].id, T2[rt << 1 | 1].id, 0);
}
void connect1(LL rt, LL start, LL end, LL to, LL w)
{
    LL l = T[rt].l, r = T[rt].r, mid = (l + r) >> 1;
    if (start <= l && r <= end)
    {
        adde(T[rt].id, to, w);
        return;
    }
    if (start <= mid)
        connect1(rt << 1, start, end, to, w);
    if (end > mid)
        connect1(rt << 1 | 1, start, end, to, w);
}
void connect2(LL rt, LL start, LL end, LL from, LL w)
{
    LL l = T2[rt].l, r = T2[rt].r, mid = (l + r) >> 1;
    if (start <= l && r <= end)
    {
        adde(from, T2[rt].id, w);
        return;
    }
    if (start <= mid)
        connect2(rt << 1, start, end, from, w);
    if (end > mid)
        connect2(rt << 1 | 1, start, end, from, w);
}
LL dis[N];
LL vis[N];
priority_queue<pair<LL, LL>> q;
void Dijkstra(LL s)
{
    for (int i = 1; i <= ncnt; ++i)
        dis[i] = 1000000000000000000LL;
    memset(dis, 0x3f, sizeof(dis)), memset(vis, 0, sizeof(vis));
    q.push(make_pair(0, s)), dis[s] = 0;
    while (!q.empty())
    {
        LL u = q.top().second;
        q.pop();
        if (vis[u])
            continue;
        vis[u] = 1;
        for (LL i = head[u]; i; i = e[i].next)
            if (!vis[e[i].to] && dis[u] + e[i].w < dis[e[i].to])
                dis[e[i].to] = dis[u] + e[i].w, q.push(make_pair(-dis[e[i].to], e[i].to));
    }
}
int main()
{
    LL n, q, s, op, a, b, c, d;
    scanf("%lld%lld%lld", &n, &q, &s);
    build1(1, 1, n), build2(1, 1, n);
    while (q--)
    {
        scanf("%lld%lld%lld%lld", &op, &a, &b, &c);
        if (op == 1)
            adde(id[a], id[b], c);
        else
        {
            scanf("%lld", &d);
            if (op == 2)
                connect2(1, b, c, id[a], d);
            else
                connect1(1, b, c, id[a], d);
        }
    }
    Dijkstra(id[s]);
    for (LL i = 1; i <= n; i++)
        if (dis[id[i]] < 1000000000000000000LL)
            printf("%lld ", dis[id[i]]);
        else
            printf("-1 ");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 100010
#define LL long long
struct edge {
    LL to,next,w;
}e[N<<4];
LL head[N],ecnt,ncnt;
inline void adde(LL from,LL to,LL w) {
    e[++ecnt]=(edge){to,head[from],w},head[from]=ecnt;
}
struct node {LL l,r,id;} T[N<<2],T2[N<<2];
LL id[N];
void build1(LL rt,LL l,LL r) {
    T[rt].l=l,T[rt].r=r,T[rt].id=++ncnt;
    if (l==r) {id[l]=ncnt;return;}
    LL mid=(l+r)>>1;
    build1(rt<<1,l,mid),build1(rt<<1|1,mid+1,r);
    adde(T[rt<<1].id,T[rt].id,0),adde(T[rt<<1|1].id,T[rt].id,0);
}
void build2(LL rt,LL l,LL r) {
    T2[rt].l=l,T2[rt].r=r;
    if (l==r) {T2[rt].id=id[l];return;}
    T2[rt].id=++ncnt;
    LL mid=(l+r)>>1;
    build2(rt<<1,l,mid),build2(rt<<1|1,mid+1,r);
    adde(T2[rt].id,T2[rt<<1].id,0),adde(T2[rt].id,T2[rt<<1|1].id,0);
}
void connect1(LL rt,LL start,LL end,LL to,LL w) {
    LL l=T[rt].l,r=T[rt].r,mid=(l+r)>>1;
    if (start<=l&&r<=end) {adde(T[rt].id,to,w);return;}
    if (start<=mid) connect1(rt<<1,start,end,to,w);
    if (end>mid) connect1(rt<<1|1,start,end,to,w);
}
void connect2(LL rt,LL start,LL end,LL from,LL w) {
    LL l=T2[rt].l,r=T2[rt].r,mid=(l+r)>>1;
    if (start<=l&&r<=end) {adde(from,T2[rt].id,w);return;}
    if (start<=mid) connect2(rt<<1,start,end,from,w);
    if (end>mid) connect2(rt<<1|1,start,end,from,w);
}
LL dis[N];LL vis[N];
priority_queue<pair<LL,LL> > q;
void Dijkstra(LL s) {
    memset(dis,0x3f,sizeof(dis)),memset(vis,0,sizeof(vis));
    q.push(make_pair(0,s)),dis[s]=0;
    while (!q.empty()) {
        LL u=q.top().second;q.pop();
        if (vis[u]) continue;vis[u]=1;
        for (LL i=head[u];i;i=e[i].next)
            if (!vis[e[i].to]&&dis[u]+e[i].w<dis[e[i].to])
                dis[e[i].to]=dis[u]+e[i].w,q.push(make_pair(-dis[e[i].to],e[i].to));
    }
}
LL main() {
    LL n,q,s,op,a,b,c,d;scanf("%lld%lld%lld",&n,&q,&s);
    build1(1,1,n),build2(1,1,n);
    while (q--) {
        scanf("%lld%lld%lld%lld",&op,&a,&b,&c);
        if (op==1) adde(id[a],id[b],c);
        else {
            scanf("%lld",&d);
            if (op==2) connect2(1,b,c,id[a],d);
            else connect1(1,b,c,id[a],d);
        }
    }
    Dijkstra(id[s]);
    for (LL i=1;i<=n;i++)
        if (dis[id[i]]<1e17) printf("%lld ",dis[id[i]]);
        else printf("-1 ");
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 100010
#define LL long long
struct edge {
    LL to,next,w;
}e[N<<4];
LL head[N],ecnt,ncnt;
inline void adde(LL from,LL to,LL w) {
    e[++ecnt]=(edge){to,head[from],w},head[from]=ecnt;
}
struct node {LL l,r,id;} T[N<<2],T2[N<<2];
LL id[N];
void build1(LL rt,LL l,LL r) {
    T[rt].l=l,T[rt].r=r,T[rt].id=++ncnt;
    if (l==r) {id[l]=ncnt;return;}
    LL mid=(l+r)>>1;
    build1(rt<<1,l,mid),build1(rt<<1|1,mid+1,r);
    adde(T[rt<<1].id,T[rt].id,0),adde(T[rt<<1|1].id,T[rt].id,0);
}
void build2(LL rt,LL l,LL r) {
    T2[rt].l=l,T2[rt].r=r;
    if (l==r) {T2[rt].id=id[l];return;}
    T2[rt].id=++ncnt;
    LL mid=(l+r)>>1;
    build2(rt<<1,l,mid),build2(rt<<1|1,mid+1,r);
    adde(T2[rt].id,T2[rt<<1].id,0),adde(T2[rt].id,T2[rt<<1|1].id,0);
}
void connect1(LL rt,LL start,LL end,LL to,LL w) {
    LL l=T[rt].l,r=T[rt].r,mid=(l+r)>>1;
    if (start<=l&&r<=end) {adde(T[rt].id,to,w);return;}
    if (start<=mid) connect1(rt<<1,start,end,to,w);
    if (end>mid) connect1(rt<<1|1,start,end,to,w);
}
void connect2(LL rt,LL start,LL end,LL from,LL w) {
    LL l=T2[rt].l,r=T2[rt].r,mid=(l+r)>>1;
    if (start<=l&&r<=end) {adde(from,T2[rt].id,w);return;}
    if (start<=mid) connect2(rt<<1,start,end,from,w);
    if (end>mid) connect2(rt<<1|1,start,end,from,w);
}
LL dis[N];LL vis[N];
priority_queue<pair<LL,LL> > q;
void Dijkstra(LL s) {
    memset(dis,0x3f,sizeof(dis)),memset(vis,0,sizeof(vis));
    q.push(make_pair(0,s)),dis[s]=0;
    while (!q.empty()) {
        LL u=q.top().second;q.pop();
        if (vis[u]) continue;vis[u]=1;
        for (LL i=head[u];i;i=e[i].next)
            if (!vis[e[i].to]&&dis[u]+e[i].w<dis[e[i].to])
                dis[e[i].to]=dis[u]+e[i].w,q.push(make_pair(-dis[e[i].to],e[i].to));
    }
}
int main() {
    LL n,q,s,op,a,b,c,d;scanf("%lld%lld%lld",&n,&q,&s);
    build1(1,1,n),build2(1,1,n);
    while (q--) {
        scanf("%lld%lld%lld%lld",&op,&a,&b,&c);
        if (op==1) adde(id[a],id[b],c);
        else {
            scanf("%lld",&d);
            if (op==2) connect2(1,b,c,id[a],d);
            else connect1(1,b,c,id[a],d);
        }
    }
    Dijkstra(id[s]);
    for (LL i=1;i<=n;i++)
        if (dis[id[i]]<1e17) printf("%lld ",dis[id[i]]);
        else printf("-1 ");
    return 0;
}


// C
#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define MAXN 200000

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ll> point;

int n, val[MAXN], best[MAXN];
vi connections[MAXN];

void dfs2(int prefix, int suffix, int node, int par) {
    best[node] = max(best[node], __gcd(prefix, suffix));
    for(const int conn : connections[node]) {
        if(conn == par) continue;
        dfs2(prefix, __gcd(prefix, val[conn]), conn, node);
    }
}

void dfs(int node, int par, int prefix) {
    dfs2(prefix, 0, node, par);
    int nextPrefix = __gcd(prefix, val[node]);
    for(const int conn : connections[node]) {
        if(conn == par) continue;
        dfs(conn, node, nextPrefix);
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    F0R(i, n) cin >> val[i];
    F0R(i, n - 1) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        connections[a].PB(b);
        connections[b].PB(a);
    }
    dfs(0, -1, 0);
    cout << val[0];
    FOR(i, 1, n) cout << " " << best[i];
    cout << "\n";
    return 0;
}


// C
#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define MAXN 200000

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ll> point;

int n, val[MAXN], par[MAXN], best[MAXN], prefix[MAXN], suffix[MAXN];
vi connections[MAXN];

void dfs(int node, int parent) {
    par[node] = parent;
    if(node == 0)prefix[node] = 0;
    else prefix[node] = __gcd(val[par[node]], prefix[par[node]]);
    for(const int conn : connections[node]) {
        if(conn == par[node]) continue;
        dfs(conn, node);
    }
}

void dfsBest(int goal, int node, int before) {
    if(node == goal) suffix[node] = 0;
    else suffix[node] = __gcd(val[before], suffix[before]);
    best[goal] = max(best[goal], __gcd(prefix[node], suffix[node]));
    if(node != 0) dfsBest(goal, par[node], node);
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    F0R(i, n) cin >> val[i];
    F0R(i, n - 1) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        connections[a].PB(b);
        connections[b].PB(a);
    }
    dfs(0, -1);
    F0R(i, n) dfsBest(i, i, -1);
    cout << val[0];
    FOR(i, 1, n) cout << " " << best[i];
    cout << "\n";
    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            //break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    for(int i=1;(i*i)<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if((i*i)<s) x.val=s/i,dels.push_back(x);
        }
    }
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    if(gcdd==0) ans[v]=val[v];
    else ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}
bool cmp(const pt&a,const pt&b)
{
    if(a.val<b.val) return true;
    return false;
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    if(s==48828) cout<<ans[200]<<'\n';
    for(int i=1;(i*i)<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if((i*i)<s) x.val=s/i,dels.push_back(x);
        }
    }
    sort(dels.begin(),dels.end(),&cmp);
    if(s==48828) for(int i=0;i<dels.size();++i) cout<<dels[i].val<<' ';
    cout<<'\n';
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

vector<pt>cur;

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1) ans[v]=max(ans[v],dels[i].val);
    }
    cur=dels;
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1),dels=cur;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
  //  for(int i=0;i<n;++i) cout<<ans[i]<<' ';
    used.assign(n,false);

    int s=val[0];
    for(int i=1;i<=sqrt(s);++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if(i!=sqrt(s)) x.val=s/i,dels.push_back(x);
        }
    }
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}
void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

void dfs(int v,int h,vector<pt>dels)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1) ans[v]=max(ans[v],dels[i].val);
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1,dels);
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
  //  for(int i=0;i<n;++i) cout<<ans[i]<<' ';
    used.assign(n,false);

    int s=val[0];
    for(int i=1;i<=sqrt(s);++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if(i!=sqrt(s)) x.val=s/i,dels.push_back(x);
        }
    }
    dfs(0,1,dels);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}
void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

void dfs(int v,int h,vector<pt>dels)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1) ans[v]=max(ans[v],dels[i].val);
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1,dels);
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    dfs0(0,0);
    used.assign(n,false);

    int s=val[0];
    for(int i=1;i<=sqrt(s);++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if(i!=sqrt(s)) x.val=s/i,dels.push_back(x);
        }
    }
    dfs(0,1,dels);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    for(int i=1;i*i<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if(i*i<s)) x.val=s/i,dels.push_back(x);
        }
    }
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}
bool cmp(const pt&a,const pt&b)
{
    if(a.val<b.val) return true;
    return false;
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    if(s==48828) cout<<ans[200]<<'\n';
    for(int i=1;(i*i)<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if((i*i)<s) x.val=s/i,dels.push_back(x);
        }
    }
    sort(dels.begin(),dels.end(),&cmp);
    if(s==48828) for(int i=0;i<dels.size();++i) cout<<dels[i].val<<' ';
    cout<<'\n';
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    if(gcdd==0) ans[v]=val[v];
    else ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}
bool cmp(const pt&a,const pt&b)
{
    if(a.val<b.val) return true;
    return false;
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    used[0]=true;
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
   // if(s==48828) cout<<ans[200]<<'\n';
    for(int i=1;(i*i)<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if((i*i)<s) x.val=s/i,dels.push_back(x);
        }
    }
    sort(dels.begin(),dels.end(),&cmp);
   // if(s==48828) for(int i=0;i<dels.size();++i) cout<<dels[i].val<<' ';
    cout<<'\n';
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}
bool cmp(const pt&a,const pt&b)
{
    if(a.val<b.val) return true;
    return false;
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    for(int i=1;(i*i)<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if((i*i)<s) x.val=s/i,dels.push_back(x);
        }
    }
    sort(dels.begin(),dels.end(),&cmp);
    if(s==48828) for(int i=0;i<dels.size();++i) cout<<dels[i].val<<' ';
    cout<<'\n';
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    if(gcdd==0) ans[v]=val[v];
    else ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}
bool cmp(const pt&a,const pt&b)
{
    if(a.val<b.val) return true;
    return false;
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    used[0]=true;
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    if(s==48828) cout<<ans[200]<<'\n';
    for(int i=1;(i*i)<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if((i*i)<s) x.val=s/i,dels.push_back(x);
        }
    }
    sort(dels.begin(),dels.end(),&cmp);
    if(s==48828) for(int i=0;i<dels.size();++i) cout<<dels[i].val<<' ';
    cout<<'\n';
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#include <vector>

using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;
struct pt
{
    int val;
    vector<int> kol;
};
vector<pt>fract;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}
void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

vector<int>prime;
vector<bool>pr(1e5+2,1);
void resh()
{
    pr[0]=pr[1]=0;
    for(int i=2;i<=350;++i)
    {
        if(pr[i]) prime.push_back(i);
        for(int j=i*i;j<=1e5;j+=i) pr[j]=false;
    }
}

void dfs(int v,vector<pt>mas)
{
    used[v]=true;
    for(int i=0;i<fract.size();++i)
    {
        if()
    }
}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    dfs0(0,0);
    used.assign(n,false);
    int s=val[0];
    for(int i=0;i<prime.size();++i)
    {
        if(s%prime[i]==0)
        {
            int x=0;
            while(s%prime[i]==0) s/=prime[i],++x;
        }
        pt x;
        x.val=prime[i];
        x.kol=vector<int>(x,1);
    }
    ans[0]=val[0];
    used[0]=true;
    for(int i=0;i<g[0].size();++i)dfs(0,fract);

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1) ans[v]=max(ans[v],dels[i].val);
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
  //  for(int i=0;i<n;++i) cout<<ans[i]<<' ';
    used.assign(n,false);

    int s=val[0];
    for(int i=1;i<=sqrt(s);++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if(i!=sqrt(s)) x.val=s/i,dels.push_back(x);
        }
    }
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}
bool cmp(const pt&a,const pt&b)
{
    if(a.val<b.val) return true;
    return false;
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    for(int i=1;(i*i)<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if((i*i)<s) x.val=s/i,dels.push_back(x);
        }
    }
    sort(dels.begin(),dels.end(),&cmp);
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


#include <iostream>
#define _USE_MATH_DEFINES
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <deque>
#include <list>
#include <set>
#include <stack>
#include <map>
#include <ctime>
#include <bitset>
#include <fstream>
#include<stdlib.h>
using namespace std;

int n;
vector<vector<int> >g;
vector<int>val;
vector<int>ans;
vector<bool>used;

struct pt
{
    int val;
    int kol;
};
vector<pt>dels;

int gcd(int x,int y)
{
    while(x)
    {
        y%=x;
        swap(x,y);
    }
    return y;
}

void dfs0(int v,int gcdd)
{
    used[v]=true;
    ans[v]=gcd(gcdd,val[v]);
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs0(g[v][i],ans[v]);
    }
}

void dfs(int v,int h)
{
    used[v]=true;
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) ++dels[i].kol;
    }
    for(int i=dels.size()-1;i>=0;--i)
    {
        if(dels[i].kol>=h-1)
        {
            ans[v]=max(ans[v],dels[i].val);
            break;
        }
    }
    for(int i=0;i<g[v].size();++i)
    {
        if(!used[g[v][i]]) dfs(g[v][i],h+1);
    }
    for(int i=0;i<dels.size();++i)
    {
        if(val[v]%dels[i].val==0) --dels[i].kol;
    }

}

int main()
{
    cin>>n;
    g.resize(n);
    ans.resize(n,1);
    val.resize(n,0);
    for(int i=0;i<n;++i) cin>>val[i];
    for(int i=0;i<n-1;++i)
    {
        int x,y;
        cin>>x>>y;
        --x,--y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    used.resize(n,false);
    for(int i=0;i<g[0].size();++i) dfs0(g[0][i],0);
    used.assign(n,false);

    int s=val[0];
    for(int i=1;i*i<=s;++i)
    {

        if(s%i==0)
        {
            pt x;
            x.kol=0,x.val=i;
            dels.push_back(x);
            if(i*i<s) x.val=s/i,dels.push_back(x);
        }
    }
    dfs(0,1);
    for(int i=0;i<n;++i) cout<<ans[i]<<' ';

    return 0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve2(int k){
	for (int i=1;i*i<=k;i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	for (int i=1;i*i<=a[k];i++){
		if(a[k]%i==0){
			if(i*i<a[k]){
				cnt[i]++;
				if(cnt[i]==deep) ans[k]=max(ans[k],i);
				if(cnt[i]==deep-1) ans[k]=max(ans[k],i);
				cnt[a[k]/i]++;
				if(cnt[a[k]/i]==deep) ans[k]=max(ans[k],a[k]/i);
				if(cnt[a[k]/i]==deep-1) ans[k]=max(ans[k],a[k]/i);
			}
			else{
				cnt[i]++;
				if(cnt[i]==deep) ans[k]=max(ans[k],i);
				if(cnt[i]==deep-1) ans[k]=max(ans[k],i);
			}
		}
	}
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		dfs(x,k,gcd(prim,a[k]),deep+1);
	}
	solve2(a[k]);
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return  0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i<=(int)(sqrt(k));i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i<=(int)(sqrt(k));i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	solve1(a[k]);
	for (int j=maxn;j>=1;j--){
			if(cnt[j]==deep){
				ans[k]=max(ans[k],j);
				break;
			}
			if(cnt[j]==(deep-1)&&cnt[j]){
				ans[k]=max(ans[k],j);
				break;
			}
	}
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		dfs(x,k,gcd(prim,a[k]),deep+1);
	}
	solve2(a[k]);
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


# include<bits/stdc++.h>
using namespace std;

vector<int> edge[200005];
int dp[200005][2],a[200005],n;

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f){
	if(f==0){
		dp[k][1]=0;
		dp[k][0]=a[k];
	}
	else{
		dp[k][0]=gcd(dp[f][0],a[k]);
		dp[k][1]=max(gcd(dp[f][1],a[k]),dp[f][0]);

	}
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f)  continue;
		dfs(x,k);
	}
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0);
	for (int i=1;i<=n;i++){
		printf("%d ",max(dp[i][1],dp[i][0]));
	}
	return 0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i*i<=k;i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i*i<=k;i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	solve1(a[k]);
	for (int j=maxn;j>=1;j--){
			if(cnt[j]==deep){
				ans[k]=max(ans[k],j);
				break;
			}
			if(cnt[j]==(deep-1)&&cnt[j]){
				ans[k]=max(ans[k],j);
				break;
			}
	}
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		dfs(x,k,gcd(prim,a[k]),deep+1);
	}
	solve2(a[k]);
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return  0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i<=(int)(sqrt(k));i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i<=(int)(sqrt(k));i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	solve1(a[k]);
	for (int i=0;i<edge[k].size();i++){
		for (int j=maxn;j>=1;j--){
			if(cnt[j]==deep){
				ans[k]=max(ans[k],j);
				break;
			}
			if(cnt[j]==(deep-1)&&cnt[j]){
				ans[k]=max(ans[k],j);
				break;
			}
		}
		int x=edge[k][i];
		if(x==f) continue;
		dfs(x,k,gcd(prim,a[k]),deep+1);
		solve2(a[k]);
	}
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i<=(int)sqrt(k);i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i<=(int)sqrt(k);i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		solve1(a[k]);
		for (int i=maxn;i>=1;i--){
			if(cnt[i]==deep){
				ans[k]=i;
				break;
			}
			if(cnt[i]==(deep-1)){
				ans[k]=i;
				break;
			}
		}
		dfs(x,k,gcd(prim,a[k]),deep+1);
		solve2(a[k]);
	}
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i<=(int)sqrt(k);i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i<=(int)sqrt(k);i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		solve1(a[k]);
		for (int i=maxn;i>=1;i--){
			if(cnt[i]%deep==0){
				ans[k]=i;
				break;
			}
			if(cnt[i]%(deep-1)==0){
				ans[k]=i;
				break;
			}
		}
		dfs(x,k,gcd(prim,a[k]),deep+1);
		solve2(a[k]);
	}
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i*i<=k;i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i*i<=k;i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	solve1(a[k]);
	for (int j=maxn;j>=1;j--){
			if(cnt[j]==deep){
				ans[k]=max(ans[k],j);
				break;
			}
			if(cnt[j]==(deep-1)&&cnt[j]){
				ans[k]=max(ans[k],j);
				break;
			}
	}
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		dfs(x,k,gcd(prim,a[k]),deep+1);
	}
	solve2(a[k]);
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i<=(int)(sqrt(k));i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i<=(int)(sqrt(k));i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	solve1(a[k]);
	for (int j=maxn;j>=1;j--){
			if(cnt[j]==deep){
				ans[k]=max(ans[k],j);
				break;
			}
			if(cnt[j]==(deep-1)&&cnt[j]){
				ans[k]=max(ans[k],j);
				break;
			}
	}
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		dfs(x,k,gcd(prim,a[k]),deep+1);
	}
	solve2(a[k]);
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return  0;
}


# include<bits/stdc++.h>
using namespace std;

int cnt[200005],ans[200005],a[200005],maxn,n;
vector<int> edge[200005];

void solve1(int k){
	for (int i=1;i<=(int)sqrt(k);i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]++;
				cnt[k/i]++;
			}
			else cnt[i]++;
		}
	}
}

void solve2(int k){
	for (int i=1;i<=(int)sqrt(k);i++){
		if(k%i==0){
			if(i*i<k){
				cnt[i]--;
				cnt[k/i]--;
			}
			else cnt[i]--;
		}
	}
}

int gcd(int a,int b){
	if(a==0) return b;
	if(b==0) return a;
	if(a%b==0) return b;
	else return gcd(b,a%b);
}

void dfs(int k,int f,int prim,int deep){
	ans[k]=prim;
	for (int i=0;i<edge[k].size();i++){
		int x=edge[k][i];
		if(x==f) continue;
		solve1(a[k]);
		for (int i=maxn;i>=1;i--){
			if(cnt[i]==deep){
				ans[k]=i;
				break;
			}
			if(cnt[i]==(deep-1)&&cnt[i]){
				ans[k]=i;
				break;
			}
		}
		dfs(x,k,gcd(prim,a[k]),deep+1);
		solve2(a[k]);
	}
}

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		maxn=max(a[i],maxn);
	}
	for (int i=1;i<=n-1;i++){
		int x,y;
		scanf("%d %d",&x,&y);
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs(1,0,a[1],1);
	for (int i=1;i<=n;i++) printf("%d ",ans[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],d;
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa,int ci){
	if (d>f[x]) f[x]=d;
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			if (a[y]%d==0) dfs(y,x,ci);else if (!ci) dfs(y,x,1);
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,1);//dfs0(e[i].y,-1)
	}
	for(d=2;d<=a[1];d++) if (a[1]%d==0) dfs(1,-1,0);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(i,1,dt) g[i]+=(a[y]%di[i]!=0);//(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(i,1,dt) g[i]-=(a[y]%di[i]!=0);//(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	fo(i,2,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[205],g[205];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(j,1,dt) g[j]+=((a[y]%di[j])!=0);//fo(i,1,dt) g[i]+=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(j,1,dt) g[j]-=((a[y]%di[j])!=0);//fo(i,1,dt) g[i]-=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,1);//dfs0(e[i].y,-1);
	}
	fo(i,1,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa,int d,int ci){
	if (ci>1) return;
	if (d>f[x]) f[x]=d;
	fe(x){
		int &y=e[i].y;
		if (y!=fa) dfs(y,x,d,ci+(a[y]%d!=0));
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	fo(d,1,a[1]) if (a[1]%d==0) dfs(1,-1,d,0);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(i,1,dt) g[i]+=(a[x]%di[i]);
			dfs(y,x);
			fo(i,1,dt) g[i]-=(a[x]%di[i]);
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	fo(i,2,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],d;
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa,int ci){
	if (d>f[x]) f[x]=d;
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			if (a[y]%d==0) dfs(y,x,ci);else if (!ci) dfs(y,x,1);
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,1);// dfs0(e[i].y,-1)
	}
	for(d=2;d<=a[1];d++) if (a[1]%d==0) dfs(1,-1,0);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],d;
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa,int ci){
	if (d>f[x]) f[x]=d;
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			if (a[y]%d==0) dfs(y,x,ci);else if (!ci) dfs(y,x,1);
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	for(d=2;d<=a[1];d++) if (a[1]%d==0) dfs(1,-1,0);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(j,1,dt) g[j]+=((a[y]%di[j])!=0);//fo(i,1,dt) g[i]+=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(j,1,dt) g[j]-=((a[y]%di[j])!=0);//fo(i,1,dt) g[i]-=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,1);//dfs0(e[i].y,-1);
	}
	fo(i,1,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(j,1,dt) g[j]+=((a[y]%di[j])!=0);//fo(i,1,dt) g[i]+=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(j,1,dt) g[j]-=((a[y]%di[j])!=0);//fo(i,1,dt) g[i]-=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,1);//dfs0(e[i].y,-1);
	}
	fo(i,2,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(i,1,dt) g[i]+=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(i,1,dt) g[i]-=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,1);//dfs0(e[i].y,-1);
	}
	fo(i,2,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		//break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(i,1,dt) g[i]+=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(i,1,dt) g[i]-=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	fo(i,2,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],d;
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa,int ci){
	if (d>f[x]) f[x]=d;
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			if (a[y]%d==0) dfs(y,x,ci);else if (!ci) dfs(y,x,1);
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	for(;d=2;d<=a[1]) if (a[1]%d==0) dfs(1,-1,0);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],g[210000];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			g[y]=gcd(g[x],a[y]);
			f[y]=max(gcd(f[x],a[y]),g[x]);
			dfs(y,x);//!!!!!!!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=g[1]=a[1];
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(i,1,dt) g[i]+=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(i,1,dt) g[i]-=((a[y]%di[i])!=0);//(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	fo(i,2,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#include<map>
#include<queue>
#include<set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define fe(x) for(int i=be[x];i;i=e[i].ne)
using namespace std;
int n,xx,yy,et,be[210000],a[210000],f[210000],dt,di[65],g[65];//g[200200][65];
struct edg{
	int y,ne;
};
edg e[410000];
inline void add_edge(int x,int y){
	e[++et].y=y;
	e[et].ne=be[x];
	be[x]=et;
}
int gcd(int a,int b){
	if (b==0) return a;else return gcd(b,a%b);
}
void dfs0(int x,int fa){
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			f[y]=gcd(f[x],a[y]);
			dfs0(y,x);
		}
	}
}
void dfs(int x,int fa){
	fd(i,dt,1) if (g[i]<=1){
		if (di[i]>f[x]) f[x]=di[i];
		break;
	}
	fe(x){
		int &y=e[i].y;
		if (y!=fa){
			fo(i,1,dt) g[i]+=(a[y]%di[i]);//a[x]!!!
			dfs(y,x);
			fo(i,1,dt) g[i]-=(a[y]%di[i]);//a[x]!!!
		}
	}
}
int main(){
	scanf("%d",&n);
	fo(i,1,n) scanf("%d",&a[i]);
	fo(i,2,n){
		scanf("%d%d",&xx,&yy);
		add_edge(xx,yy);
		add_edge(yy,xx);
	}
	f[1]=a[1];
	fe(1){
		f[e[i].y]=a[e[i].y];
		dfs0(e[i].y,-1);
	}
	fo(i,2,a[1]) if (a[1]%i==0) di[++dt]=i;
	dfs(1,-1);
	fo(i,1,n) printf("%d ",f[i]);
	return 0;
}