/**************************************************************
    Problem: ????
    User: (team ina)   xiaodongc(little_Bear_c)
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:0 kb
    length:0 kb
    score: inf
****************************************************************/
//CLOCKS_PER_SEC
/*
A possible implementation
The first few steps are just BST routine
Node deletion algorithm
Specifically, we're going to have a search
And assume that the target node does exist
So we call the removeAt routine
Remove the node physically
Next, we're still going through a for cycle
Ancestral ancestors traversing deleted nodes
Please pay special attention to our starting point
The father of the deleted node
Instead of inserting it like that
It can start directly from its grandfather
Then, in the course of the whole traversal
Each of us discovers an unbalanced ancestor G
Make a proper rotation adjustment to the ancestor
The three nodes involved in rotation are still G
And the taller kid, P
And the higher grandson V down there
And whether it's unbalanced or rotated
We all need to update the height of this ancestor
You can see that in the worst case
Really need to do logn times
You might as well take the control logic of the previous insert operation
Make a contrast here
No, there's nothing
Tricks to terminate the traversal process ahead of time
Because in the worst case
We really need to leave everything behind
Deal with all generations of ancestors
Since then, we can successfully end the algorithm
And return
So far you may find out
Here's the rotation
We haven't given a specific implementation of it
It's exactly what we suggested
Single spin and double spin in that way?
Interestingly enough, the answer is negative
*/
using namespace std;
#include<bitset>
#include<deque>
#include<stdint.h>
#include<set>
#include<stack>
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<ctime>
#include<map>
#define sqr(x) (x)*(x)
#define sort stable_sort
#define ll long long
#define mk make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mk(mk(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define titose CLOCKS_PER_SEC
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt");
#define fast ios_base::sync_with_stdio(false);
void readi(int &x)
{
	int v=0,f=1;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readll(ll &x)
{
	ll v=0ll,f=1ll;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readc(char &x)
{
	char c;
	while ((c=getchar())==' ');
	x=c;
}
void writes(string s){puts(s.c_str());}
void writeln(){writes("");}
void writei(int x)
{
	if (x<0)
	{
		putchar('-');
		x=abs(x);
	}
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
void writell(ll x)
{
	if (x<0)
	{
		putchar('-');
		x=abs(x);
	}
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
inline long long inc(int &x){return ++x;}
inline long long inc(long long &x){return ++x;}
inline long long inc(int &x,long long y){return x+=y;}
inline long long inc(long long &x,long long y){return x+=y;}
inline double inc(double &x,double y){return x+=y;}
inline long long dec(int &x){return --x;}
inline long long dec(long long &x){return --x;}
inline long long dec(int &x,long long y){return x-=y;}
inline long long dec(long long &x,long long y){return x-=y;}
inline double dec(double &x,double y){return x-=y;}
inline long long mul(int &x){return x=((long long)x)*x;}
inline long long mul(long long &x){return x=x*x;}
inline long long mul(int &x,long long y){return x*=y;}
inline long long mul(long long &x,long long y){return x*=y;}
inline double mul(double &x,double y){return x*=y;}
inline long long divi(const int &x)
{
	long long ans,l,r,mid;
	ans=0;l=0;r=0x3fffffff;
	while (l<r)
	{
		mid=(l+r)/2;
		if (mid*mid<=x)
		{
			ans=mid;
			l=mid+1;
		}
		else r=mid;
	}
	return ans;
}
inline long long divi(const long long &x)
{
	long long ans,l,r,mid;
	ans=0;l=0;r=0x3fffffff;
	while (l<r)
	{
		mid=(l+r)/2;
		if (mid*mid<=x)
		{
			ans=mid;
			l=mid+1;
		}
		else r=mid;
	}
	return ans;
}
inline long long divi(int &x,long long y){return x/=y;}
inline long long divi(long long &x,long long y){return x/=y;}
inline double divi(double &x,double y){return x/=y;}
inline long long mod(int &x,long long y){return x%=y;}
inline long long mod(long long &x,long long y){return x%=y;}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii >
#define piipi pair<pii,int>
#define plll pair<ll,pll >
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
#define forup(i,x,y) if ((x)<=(y)) for ((i)=(x);(i)<=(y);(i)++)
#define fordo(i,x,y) if ((x)>=(y)) for ((i)=(x);(i)>=(y);(i)--)
#define rep(i,x) forup ((i),1,(x))
#define repd(i,x) fordo ((i),(x),1)
#define itr iterator
#define forwyx(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define NO {cout<<"Impossible";return 0;}
#define YES {cout<<"Possible\n";}
#define y0 y000000000000000000000000000
#define y1 y111111111111111111111111111
#define j0 j000000000000000000000000000
#define j1 j111111111111111111111111111
#define cl0(a) memset((a),(0),(sizeof((a))))
#define clz(a) memset((a),(0x16),(sizeof((a))))
#define clf(a) memset((a),(-(0x16)),(sizeof((a))))
#define inf 0x3bbbbbbb
#define lnf 0x1bbbbbbbbbbbbbbbll
#define sqrt divi
#define p2(i) (1ll<<(i))
/*************************************************/
ll n,m,i,j,dp[200005],x,y,ans[400005],sum,vis[200005];
vector<pair<ll,ll> > e[200005];
ll dfs(ll x)
{
	vis[x]=1;
	forwyx(it,e[x])
	{
		if (vis[it->fi]) continue;
		ll t=dfs(it->fi);
		ans[abs(it->se)]=it->se>0?t:-t;
		dp[x]+=t;
	}
	return dp[x];
}
int main()
{
	fast;
	cin>>n;
	rep(i,n) {cin>>dp[i];sum+=dp[i];}
	if (sum) NO
	cin>>m;
	YES
	rep(i,m)
	{
		cin>>x>>y;
		e[x].pb(mk(y,i));
		e[y].pb(mk(x,-i));
	}
	dfs(1);
	rep(i,m) cout<<ans[i]<<endl;
	return 0;
}


/**************************************************************
    Problem: ????
    User: (team ina)   xiaodongc(little_Bear_c)
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:0 kb
    length:0 kb
    score: inf
****************************************************************/
//CLOCKS_PER_SEC
/*
A possible implementation
The first few steps are just BST routine
Node deletion algorithm
Specifically, we're going to have a search
And assume that the target node does exist
So we call the removeAt routine
Remove the node physically
Next, we're still going through a for cycle
Ancestral ancestors traversing deleted nodes
Please pay special attention to our starting point
The father of the deleted node
Instead of inserting it like that
It can start directly from its grandfather
Then, in the course of the whole traversal
Each of us discovers an unbalanced ancestor G
Make a proper rotation adjustment to the ancestor
The three nodes involved in rotation are still G
And the taller kid, P
And the higher grandson V down there
And whether it's unbalanced or rotated
We all need to update the height of this ancestor
You can see that in the worst case
Really need to do logn times
You might as well take the control logic of the previous insert operation
Make a contrast here
No, there's nothing
Tricks to terminate the traversal process ahead of time
Because in the worst case
We really need to leave everything behind
Deal with all generations of ancestors
Since then, we can successfully end the algorithm
And return
So far you may find out
Here's the rotation
We haven't given a specific implementation of it
It's exactly what we suggested
Single spin and double spin in that way?
Interestingly enough, the answer is negative
*/
using namespace std;
#include<bitset>
#include<deque>
#include<stdint.h>
#include<set>
#include<stack>
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<ctime>
#include<map>
#define sqr(x) (x)*(x)
#define sort stable_sort
#define ll long long
#define mk make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mk(mk(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define titose CLOCKS_PER_SEC
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt");
#define fast ios_base::sync_with_stdio(false);
void readi(int &x)
{
	int v=0,f=1;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readll(ll &x)
{
	ll v=0ll,f=1ll;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readc(char &x)
{
	char c;
	while ((c=getchar())==' ');
	x=c;
}
void writes(string s){puts(s.c_str());}
void writeln(){writes("");}
void writei(int x)
{
	if (x<0)
	{
		putchar('-');
		x=abs(x);
	}
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
void writell(ll x)
{
	if (x<0)
	{
		putchar('-');
		x=abs(x);
	}
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
inline long long inc(int &x){return ++x;}
inline long long inc(long long &x){return ++x;}
inline long long inc(int &x,long long y){return x+=y;}
inline long long inc(long long &x,long long y){return x+=y;}
inline double inc(double &x,double y){return x+=y;}
inline long long dec(int &x){return --x;}
inline long long dec(long long &x){return --x;}
inline long long dec(int &x,long long y){return x-=y;}
inline long long dec(long long &x,long long y){return x-=y;}
inline double dec(double &x,double y){return x-=y;}
inline long long mul(int &x){return x=((long long)x)*x;}
inline long long mul(long long &x){return x=x*x;}
inline long long mul(int &x,long long y){return x*=y;}
inline long long mul(long long &x,long long y){return x*=y;}
inline double mul(double &x,double y){return x*=y;}
inline long long divi(const int &x)
{
	long long ans,l,r,mid;
	ans=0;l=0;r=0x3fffffff;
	while (l<r)
	{
		mid=(l+r)/2;
		if (mid*mid<=x)
		{
			ans=mid;
			l=mid+1;
		}
		else r=mid;
	}
	return ans;
}
inline long long divi(const long long &x)
{
	long long ans,l,r,mid;
	ans=0;l=0;r=0x3fffffff;
	while (l<r)
	{
		mid=(l+r)/2;
		if (mid*mid<=x)
		{
			ans=mid;
			l=mid+1;
		}
		else r=mid;
	}
	return ans;
}
inline long long divi(int &x,long long y){return x/=y;}
inline long long divi(long long &x,long long y){return x/=y;}
inline double divi(double &x,double y){return x/=y;}
inline long long mod(int &x,long long y){return x%=y;}
inline long long mod(long long &x,long long y){return x%=y;}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii >
#define piipi pair<pii,int>
#define plll pair<ll,pll >
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
#define forup(i,x,y) if ((x)<=(y)) for ((i)=(x);(i)<=(y);(i)++)
#define fordo(i,x,y) if ((x)>=(y)) for ((i)=(x);(i)>=(y);(i)--)
#define rep(i,x) forup ((i),1,(x))
#define repd(i,x) fordo ((i),(x),1)
#define itr iterator
#define forwyx(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
#define NO {cout<<"Impossible";return 0;}
#define YES {cout<<"Possible";}
#define y0 y000000000000000000000000000
#define y1 y111111111111111111111111111
#define j0 j000000000000000000000000000
#define j1 j111111111111111111111111111
#define cl0(a) memset((a),(0),(sizeof((a))))
#define clz(a) memset((a),(0x16),(sizeof((a))))
#define clf(a) memset((a),(-(0x16)),(sizeof((a))))
#define inf 0x3bbbbbbb
#define lnf 0x1bbbbbbbbbbbbbbbll
#define sqrt divi
#define p2(i) (1ll<<(i))
/*************************************************/
ll n,m,i,j,dp[200005],x,y,ans[400005],sum,vis[200005];
vector<pair<ll,ll> > e[200005];
ll dfs(ll x)
{
	vis[x]=1;
	forwyx(it,e[x])
	{
		if (vis[it->fi]) continue;
		ll t=dfs(it->fi);
		ans[abs(it->se)]=it->se>0?t:-t;
		dp[x]+=t;
	}
	return dp[x];
}
int main()
{
	fast;
	cin>>n;
	rep(i,n) {cin>>dp[i];sum+=dp[i];}
	if (sum) NO
	cin>>m;
	YES
	rep(i,m)
	{
		cin>>x>>y;
		e[x].pb(mk(y,i));
		e[y].pb(mk(x,-i));
	}
	dfs(1);
	rep(i,m) cout<<ans[i]-ans[i+1]<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define reg register
typedef long long ll;
using namespace std;
const int MN=2e5+5;
int to[MN<<1],nxt[MN<<1],h[MN],cnt=1;
inline void ins(int s,int t){
	to[++cnt]=t;nxt[cnt]=h[s];h[s]=cnt;
	to[++cnt]=s;nxt[cnt]=h[t];h[t]=cnt;
}
int n,m,a[MN],Ans[MN];
bool vis[MN];
void dfs(int st){
	vis[st]=true;
	for(reg int i=h[st];i;i=nxt[i]){
		if(vis[to[i]])continue;
		dfs(to[i]);a[st]+=a[to[i]];
		Ans[i/2]=((i&1)?-1:1)*a[to[i]];
	}
}
int main(){
	scanf("%d",&n);reg int tot=0;
	for(reg int i=1;i<=n;i++)scanf("%d",a+i),tot+=a[i];
	if(tot)return 0*puts("Impossible");
	puts("Possible");
	scanf("%d",&m);
	for(reg int i=1,s,t;i<=m;i++)
		scanf("%d%d",&s,&t),ins(s,t);
	dfs(1);
	for(reg int i=1;i<=m;i++)
		printf("%d ",Ans[i]);
	return 0;
}


/*
    Author : @evenbao
    Created :
*/

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

#ifndef LOCAL
	#define eprintf(...) fprintf(stderr , _VA_ARGS)
#else
	#define eprintf(...) 42
#endif

typedef long long LL;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//mt19937 mrand(random_device{}());

// #define evenbao
#define MP make_pair
#define FI first
#define SE second

const int N = 2e5 + 10;

struct edge {
	int v , id;
} ;

struct info {
	int u , v;
} e[N];

int n , all , m;
int fa[N] , size[N] , s[N] , ans[N];
vector< edge > a[N];

template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void read(T &x) {
   T f = 1; x = 0;
   char c = getchar();
   for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
   for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
   x *= f;
}

inline int find(int x){
	if (fa[x] == x) return x;
	else return (fa[x] = find(fa[x]));
}

inline void merge(int x, int y){
	int fx = find(x), fy = find(y);
	if (fx == fy) return;
	if (size[fx] > size[fy]) swap(fx, fy);
	size[fy] += size[fx], fa[fx] = fy;
}

inline int dfs(int pos, int dad, int id){
	if (e[id].u == pos) ans[id] = -s[pos];
	else ans[id] = s[pos];
	for (unsigned i = 0, si = a[pos].size(); i < si; ++i){
		int son = a[pos][i].v, sonid = a[pos][i].id;
		if (son != dad){
			if (e[id].u == pos) ans[id] += dfs(son, pos, sonid);
			else ans[id] -= dfs(son, pos, sonid);
		}
	}
	if (e[id].u == pos) return ans[id];
	return -ans[id];
}

int main() {

	read(n);
	for (int i = 1; i <= n; ++i) {
		read(s[i]);
		all += s[i];
		fa[i] = i;
		size[i] = 1;
	}
	if (all != 0) {
		printf("Impossible\n");
		return 0;
	}
	read(m);
	printf("Possible\n");
	for (int i = 1; i <= m; ++i) {
		int u , v;
		read(u) , read(v);
		e[i].u = u , e[i].v = v;
		if (find(u) != find(v)) {
			merge(u , v);
			a[u].push_back((edge) {v , i});
			a[v].push_back((edge) {u , i});
		}
	}
	dfs(1 , 0 , 0);
	for (int i = 1; i <= m; ++i)
		printf("%d\n" , ans[i]);
    return 0;
}


/*
    Author : @evenbao
    Created :
*/

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

#ifndef LOCAL
	#define eprintf(...) fprintf(stderr , _VA_ARGS)
#else
	#define eprintf(...) 42
#endif

typedef long long LL;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937 mrand(random_device{}());

// #define evenbao
#define MP make_pair
#define FI first
#define SE second

const int N = 2e5 + 10;

struct edge {
	int v , id;
} ;

struct info {
	int u , v;
} e[N];

int n , all , m;
int fa[N] , size[N] , s[N] , ans[N];
vector< edge > a[N];

template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void read(T &x) {
   T f = 1; x = 0;
   char c = getchar();
   for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
   for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
   x *= f;
}

inline int find(int x){
	if (fa[x] == x) return x;
	else return (fa[x] = find(fa[x]));
}

inline void merge(int x, int y){
	int fx = find(x), fy = find(y);
	if (fx == fy) return;
	if (size[fx] > size[fy]) swap(fx, fy);
	size[fy] += size[fx], fa[fx] = fy;
}

inline int dfs(int pos, int dad, int id){
	if (e[id].u == pos) ans[id] = -s[pos];
	else ans[id] = s[pos];
	for (unsigned i = 0, si = a[pos].size(); i < si; ++i){
		int son = a[pos][i].v, sonid = a[pos][i].id;
		if (son != dad){
			if (e[id].u == pos) ans[id] += dfs(son, pos, sonid);
			else ans[id] -= dfs(son, pos, sonid);
		}
	}
	if (e[id].u == pos) return ans[id];
	return -ans[id];
}

int main() {

	read(n);
	for (int i = 1; i <= n; ++i) {
		read(s[i]);
		all += s[i];
		fa[i] = i;
		size[i] = 1;
	}
	if (all != 0) {
		printf("Impossible\n");
		return 0;
	}
	read(m);
	printf("Possible\n");
	for (int i = 1; i <= m; ++i) {
		int u , v;
		read(u) , read(v);
		e[i].u = u , e[i].v = v;
		if (find(u) != find(v)) {
			merge(u , v);
			a[u].push_back((edge) {u , i});
			a[v].push_back((edge) {v , i});
		}
	}
	dfs(1 , 0 , 0);
	for (int i = 1; i <= m; ++i)
		printf("%d\n" , ans[i]);
    return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>

using namespace std;

typedef long long ll;
const int MAXN=200005,INF=1000000000;

int s[MAXN];
struct Node
{
    int v,c;
    Node *next,*rev;
}pool[MAXN<<3|1],*h[MAXN],*e[MAXN<<3|1];
int tot=0;

void addEdge(int u,int v,int c)
{
    Node *p=&pool[++tot],*q=&pool[++tot];
    p->v=v;p->c=c;p->next=h[u];h[u]=p;p->rev=q;
    q->v=u;q->c=0;q->next=h[v];h[v]=q;q->rev=p;
}

Node *addGdge(int u,int v,int c)
{
    Node *p=&pool[++tot],*q=&pool[++tot];
    p->v=v;p->c=c;p->next=h[u];h[u]=p;p->rev=q;
    q->v=u;q->c=c;q->next=h[v];h[v]=q;q->rev=p;
}

int n,m;
int src,sink;
int level[MAXN];
queue<int> q;
bool bfs()
{
    while(!q.empty())q.pop();
    q.push(src);
    level[src]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(Node *p=h[u];p;p=p->next)
        {
            if(level[p->v]<0 && p->c>0)
            {
                level[p->v]=level[u]+1;
                q.push(p->v);
            }
        }
        if(level[sink]>0)return true;
    }
    return false;
}

int dfs(int u,int key)
{
    if(u==sink)return key;
    int ans=0;
    for(Node *p=h[u];p;p=p->next)
    {
        if(level[p->v]==level[u]+1 && p->c>0)
        {
            int t=dfs(p->v,min(key,p->c));
            if(t>0)
            {
                p->c-=t;
                p->rev->c+=t;
                ans+=t;
                key-=t;
                if(key<=0)break;
            }
        }
    }
    if(!ans)level[u]=-1;
    return ans;
}

int dinic()
{
    int totflow=0;
    while(true)
    {
        memset(level,-1,sizeof(level));
        if(!bfs())break;
        totflow+=dfs(src,INF);
    }
    return totflow;
}

int main()
{
    #ifdef OnCode
    //freopen("code.in","r",stdin);
    //freopen("code.out","w",stdout);
    #endif
    int u,v;
    ll s1=0,s2=0;
    scanf("%d",&n);
    src=0;sink=n+1;
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&s[i]);
    	if(s[i]>0)
		{
			s2+=s[i];
			addEdge(i,n+1,s[i]);
		}
    	else
		{
			s1-=s[i];
			addEdge(0,i,-s[i]);
		}
    }
    if(s1!=s2)
	{
		cout<<"Impossible"<<endl;
		return 0;
	}
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
    	scanf("%d%d",&u,&v);
    	e[i]=addGdge(u,v,INF);
    }
    if(dinic()!=s1)
    {
		cout<<"Impossible"<<endl;
		return 0;
    }
    printf("Possible\n");
    for(int i=1;i<=m;i++)
    	if(e[i]->c<INF)printf("%d\n",INF-e[i]->c);
    	else printf("%d\n",e[i]->rev->c-INF);
    return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;
const int MAXN=200005,MOD=1000000007;

int n,m,a[MAXN],f[MAXN<<1|1];
struct Node
{
	int v,id;
	Node *next;
}pool[MAXN<<1|1],*h[MAXN];
int etot=0;
inline void addEdge(int u,int v,int id)
{
	Node *p=&pool[++etot];
	p->v=v;p->id=id;p->next=h[u];h[u]=p;
}

bool vis[MAXN];
int dfs(int u)
{
	vis[u]=1;
	for(Node *p=h[u];p;p=p->next)
	{
		if(vis[p->v])continue;
		a[u]+=(f[p->id]=dfs(p->v));
	}
	return a[u];
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("code.in","r",stdin);
    //freopen("code.out","w",stdout);
    #endif
    int u,v;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
    	scanf("%d%d",&u,&v);
    	addEdge(u,v,i);
    	addEdge(v,u,i+m);
    }
	int t=dfs(1);
    if(t)return 0*printf("Impossible\n");
    printf("Possible\n");
    for(int i=1;i<=m;i++)
    	if(f[i])printf("%d\n",f[i]);
    	else printf("%d\n",-f[i+m]);
    return 0;
}


#include<cstdio>
#define it register int
#define il inline
const int N=1000005;
int fa[N],h[N],nxt[N],adj[N],a[N],u,v,t,id[N],Id,ans[N],f[N],n,tot,m;
il int fd(it x){
	return fa[x]==x?x:fa[x]=fd(fa[x]);
}
il void add(){
	nxt[++t]=h[u],h[u]=t,adj[t]=v,id[t]=Id,nxt[++t]=h[v],h[v]=t,adj[t]=u,id[t]=Id;
}
il void mer(){
	it t1=fd(u),t2=fd(v);
	if(t1!=t2) fa[t1]=t2,add();
}
il void dfs(it x){
	for(it i=h[x],j;i;i=nxt[i])
		if((j=adj[i])!=f[x])
			f[j]=x,dfs(j),a[x]+=a[j],ans[id[i]]=(i&1?a[j]:-a[j]);
}
il void fr(int &num){
    num=0;char c=getchar();int p=1;
    while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
    while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
    num*=p;
}
int main(){
	fr(n);
	for(it i=1;i<=n;++i) fr(a[i]),tot+=a[i],fa[i]=i;
	if(tot) return puts("Impossible"),0;
	puts("Possible");
	fr(m);
	for(Id=1;Id<=m;++Id) fr(u),fr(v),mer();
	dfs(1);
	for(it i=1;i<=m;++i) printf("%d\n",ans[i]);
	return 0;
}


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

const int N = 2e5 + 52;

struct edge {
	int to, next, f, id;
} e[N << 1];
int head[N], cnt;
void addedge(int x, int y, int id) {
	e[++cnt] = {y, x[head], 1, id}, x[head] = cnt;
	e[++cnt] = {x, y[head], -1, id}, y[head] = cnt;
}

int p[N];
int f(int x) { return p[x] ? p[x] = f(p[x]) : x; }
void $(int x, int y) {
	if ((x = f(x)) != (y = f(y))) x[p] = y;
}

int n, a[N], m, x, y, s[N], ans[N];
void dfs(int x, int p) {
	x[s] = x[a];
	for (int i = head[x], nx; i; i = e[i].next)
		if ((nx = e[i].to) != p) {
			dfs(nx, x);
			ans[e[i].id] = e[i].f * nx[s];
			x[s] += nx[s];
		}
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", a + i), x += a[i];
	if (x) return puts("Impossible"), 0;
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &x, &y);
		if (f(x) ^ f(y)) $(x, y), addedge(x, y, i);
	}
	dfs(1, 0);
	puts("Possible");
	for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
}


#include <bits/stdc++.h>
#define f first
#define s second
#define ll long long
#define MP make_pair
#define PB push_back
#define INF ((1<<30)-1)
#define MOD 1000000007
#define MAXN 200100
#define EPS 1e-9
#define INFLL 1e18
using namespace std;
FILE *in,*out;

int N,M,K;
int ar[200100];
vector<vector<pair<int,int> > > edges(200100);
int used[200100];
int SUM;
int ANS[200100];

int dfs(int root)
{
    // printf("root:%d\n",root);
    int i,j,k;
    used[root]=1;
    j = ar[root];
    for(i=0;i<(int)(edges[root].size());i++)
    {
        if(used[edges[root][i].f])
            continue;
        k = dfs(edges[root][i].f);
        if(edges[root][i].s > 0 )
            ANS[edges[root][i].s] = (SUM - k);
        else
            ANS[-edges[root][i].s] = k;
        j += k;
    }
    // printf("root:%d -> %d\n",root,j);
    return j;
}

int read()
{
    int i,j,k;
    int x,y;
    cin >> N;
    for(i=1;i<=N;i++)
    {
        cin >> ar[i];
        SUM += ar[i];
    }
    cin >> M;
    for(i=0;i<M;i++)
    {
        cin >> x >> y;
        edges[x].push_back(make_pair(y,i+1));
        edges[y].push_back(make_pair(x,-i-1));
    }
    if(SUM!=0)
    {
        cout << "Impossible\n";
        return 0;
    }
    dfs(1);
    cout << "Possible\n";
    for(i=1;i<=M;i++)
    {
        cout << -ANS[i] << "\n";
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    // in = fopen("A.in","r");
    // out  = fopen("A.out","w");
    in = stdin;
    out = stdout;
    read();
    return 0;
}
//////////// !!!!!!!!!! Check
// Interactive problems => Deactiave read optimizer!

//////////// Sublime Snippets
// forx
// fory
// vectorx
// pairx
// sizex
// mod_operations

// lca
// rmq
// fft
// bigint
// bigint_fft
// bigint_normal
// hash_gnu
// simple_segment
// tree_decomposition
// number_theory


#include <bits/stdc++.h>
#define f first
#define s second
#define ll long long
#define MP make_pair
#define PB push_back
#define INF ((1<<30)-1)
#define MOD 1000000007
#define MAXN 200100
#define EPS 1e-9
#define INFLL 1e18
using namespace std;
FILE *in,*out;

int N,M,K;
int ar[200100];
vector<vector<pair<int,int> > > edges(200100);
int used[200100];
int SUM;
int ANS[200100];

int dfs(int root)
{
    // printf("root:%d\n",root);
    int i,j,k;
    used[root]=1;
    j = ar[root];
    for(i=0;i<(int)(edges[root].size());i++)
    {
        if(used[edges[root][i].f])
            continue;
        k = dfs(edges[root][i].f);
        if(edges[root][i].s > 0 )
            ANS[edges[root][i].s] = (SUM - k);
        else
            ANS[-edges[root][i].s] = k;
        j += k;
    }
    // printf("root:%d -> %d\n",root,j);
    return j;
}

int read()
{
    int i,j,k;
    int x,y;
    cin >> N;
    for(i=1;i<=N;i++)
    {
        cin >> ar[i];
        SUM += ar[i];
    }
    cin >> M;
    for(i=0;i<M;i++)
    {
        cin >> x >> y;
        edges[x].push_back(make_pair(y,i+1));
        edges[y].push_back(make_pair(x,-i-1));
    }
    if(SUM!=0)
    {
        cout << "Impossible\n";
        return 0;
    }
    dfs(1);
    cout << "Possible\n";
    for(i=1;i<=M;i++)
    {
        cout << ANS[i] << "\n";
    }
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    // in = fopen("A.in","r");
    // out  = fopen("A.out","w");
    in = stdin;
    out = stdout;
    read();
    return 0;
}
//////////// !!!!!!!!!! Check
// Interactive problems => Deactiave read optimizer!

//////////// Sublime Snippets
// forx
// fory
// vectorx
// pairx
// sizex
// mod_operations

// lca
// rmq
// fft
// bigint
// bigint_fft
// bigint_normal
// hash_gnu
// simple_segment
// tree_decomposition
// number_theory


#include<bits/stdc++.h>

using namespace std;

const int N=2e5+5;

int n,m;

int s[N],f[N];

long long sum;

vector<int>G[N];

vector<pair<int,int> >iddr[N];

bool vis[N];

void addedge(int u,int v,int id,int dr){
	G[u].push_back(v);
	iddr[u].push_back(make_pair(id,dr));
}

void dfs(int u,int pa){
	vis[u]=1;
	for(int v,now,dr,i=0;i<(int)G[u].size();i++){
		v=G[u][i];now=iddr[u][i].first;dr=iddr[u][i].second;
		if(v==pa||vis[v]){
			continue;
		}
		dfs(v,u);
		s[u]+=s[v];
		f[now]+=s[v]*dr;
	}
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&s[i]);
		sum+=s[i];
	}
	if(sum){
		printf("Impossible\n");
		return 0;
	}
	scanf("%d",&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		addedge(u,v,i,1);
		addedge(v,u,i,-1);
	}
	printf("Possible\n");
	dfs(1,0);
	for(int i=1;i<=m;i++){
		printf("%d\n",f[i]);
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

const int N=2e5+5;

int n,m,lg;

int s[N],f[N];

long long sum;

vector<int>G[N];

vector<pair<int,int> >iddr[N];

bool vis[N];

void addedge(int u,int v,int id,int dr){
	G[u].push_back(v);
	iddr[u].push_back(make_pair(id,dr));
}

void dfs(int u,int pa){
	vis[u]=1;
	for(int v,now,dr,i=0;i<(int)G[u].size();i++){
		v=G[u][i];now=iddr[u][i].first;dr=iddr[u][i].second;
		if(v==pa||vis[v]){
			continue;
		}
		dfs(v,u);
		s[u]+=s[v];
		f[now]+=s[v]*dr;
	}
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&s[i]);
		sum+=s[i];
	}
	if(sum){
		printf("Impossible\n");
		return 0;
	}
	scanf("%d",&m);
	for(int i=1,u,v;i<=m;i++){
		scanf("%d%d",&u,&v);
		addedge(u,v,i,1);
		addedge(v,u,i,-1);
	}
	printf("Possible\n");
	dfs(1,0);
	for(int i=1;i<=m;i++){
		printf("%d\n",f[i]);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200000 + 10;
const int M = 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
const int oo = 1000000000;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> ii;
#define pb push_back
#define all(c) (c).begin(),(c).end()
int n,v[N],m,y[N],vis[N],ans[N];
vector<ii> g[N];
ii E[N];
int dfs(int u){
	vis[u]=true;
	int cur=-v[u];
	for(int i=0; i<g[u].size(); ++i){
		int d=g[u][i].first, idx=g[u][i].second;
		if(!vis[d]){
			int cc=dfs(d);
			if(idx<0)ans[-idx]=-cc;
			else ans[idx]=cc;
			cur+=cc;
		}
	}
	return cur;
}
int main(){
	cin>>n;
	for(int i=0; i<n; ++i)
		scanf("%d",&v[i]);
	cin>>m;
	for(int a,b,i=0; i<m; ++i){
		scanf("%d%d",&a,&b);
		y[i]=1;
		--a;--b;
		g[a].pb(ii(b,i+1));
		g[b].pb(ii(a,-i-1));
	}
	if(dfs(0))
		return puts("Impossible"),0;
	puts("Possible");
	for(int i=0; i<m; ++i)
		printf("%d\n", ans[i+1]*y[i]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200000 + 10;
const int M = 1000000007;
const double eps = 1e-9;
const double PI = acos(-1);
const int oo = 1000000000;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> ii;
#define pb push_back
#define all(c) (c).begin(),(c).end()
int n,v[N],m,vis[N],ans[N];
vector<ii> g[N];
ii E[N];
int dfs(int u){
	vis[u]=true;
	int cur=-v[u];
	for(int i=0; i<g[u].size(); ++i){
		int d=g[u][i].first, idx=g[u][i].second;
		if(!vis[d]){
			int cc=dfs(d);
			if(idx<0)ans[-idx]=cc;
			else ans[idx]=-cc;
			cur+=cc;
		}
	}
	return cur;
}
int main(){
	cin>>n;
	for(int i=0; i<n; ++i)
		scanf("%d",&v[i]);
	cin>>m;
	for(int a,b,i=0; i<m; ++i){
		scanf("%d%d",&a,&b);
		--a;--b;
		g[a].pb(ii(b,i+1));
		g[b].pb(ii(a,-i-1));
	}
	if(dfs(0))
		return puts("Impossible"),0;
	puts("Possible");
	for(int i=0; i<m; ++i)
		printf("%d\n", ans[i+1]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll lim=200007;
ll sum=0,A[lim],Vis[lim];
map<ll,map<ll,ll>> M;
vector<ll> Adj[lim];
ll dfs(ll k,ll parent)
{
	// cout<<k<<" "<<parent<<endl;
	ll c=0;
	ll remaining=0;
	Vis[k]=1;
	sum+=A[k];
	for(ll i=0;i<Adj[k].size();i++)
	{
		if(Vis[Adj[k][i]]==0)
		{
			c++;
			remaining += dfs(Adj[k][i],k);
		}
	}
	// if(k==3) cout<<remaining<<"sudarsnh"<<endl;
	if(c==0)
	{
		M[parent][k]=A[k]; M[k][parent]=-1*A[k];
		return A[k];
	}
	else
	{
		M[parent][k]=remaining+A[k]; M[k][parent]=-1*remaining-A[k];
	}

	return sum;
}

int main() {
	ll n,m,X[lim],Y[lim];
	cin>>n;
	for(ll i=1;i<=n;i++) cin>>A[i];
	cin>>m;
	for(ll i=1;i<=m;i++)
	{
		cin>>X[i]>>Y[i];
		Adj[X[i]].push_back(Y[i]);
		Adj[Y[i]].push_back(X[i]);
	}

	for(ll i=1;i<=n;i++)
	{
		if(Vis[i]==0)
		{
			sum=0;
			dfs(i,i);
			if(sum!=0) {cout<<"impossible";return 0;}

		}
	}

	cout<<"possible"<<endl;
	for(ll i=1;i<=m;i++)
	{
		cout<<M[X[i]][Y[i]]<<endl;
	}
	// cout<<M[3][4];

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll lim=200007;
ll sum=0,A[lim],Vis[lim];
map<ll,map<ll,ll>> M;
vector<ll> Adj[lim];
ll dfs(ll k,ll parent)
{
	// cout<<k<<" "<<parent<<endl;
	ll c=0;
	ll remaining=0;
	Vis[k]=1;
	sum+=A[k];
	for(ll i=0;i<Adj[k].size();i++)
	{
		if(Vis[Adj[k][i]]==0)
		{
			c++;
			remaining += dfs(Adj[k][i],k);
		}
	}
	// if(k==3) cout<<remaining<<"sudarsnh"<<endl;
	if(c==0)
	{
		M[parent][k]=A[k]; M[k][parent]=-1*A[k];
		return A[k];
	}
	else
	{
		M[parent][k]=remaining+A[k]; M[k][parent]=-1*remaining-A[k];
		return 1*remaining+A[k];
	}

}

int main() {
	ll n,m,X[lim],Y[lim];
	cin>>n;
	for(ll i=1;i<=n;i++) cin>>A[i];
	cin>>m;
	for(ll i=1;i<=m;i++)
	{
		cin>>X[i]>>Y[i];
		Adj[X[i]].push_back(Y[i]);
		Adj[Y[i]].push_back(X[i]);
	}

	for(ll i=1;i<=n;i++)
	{
		if(Vis[i]==0)
		{
			sum=0;
			dfs(i,i);
			if(sum!=0) {cout<<"impossible";return 0;}

		}
	}

	cout<<"possible"<<endl;
	for(ll i=1;i<=m;i++)
	{
		cout<<M[X[i]][Y[i]]<<endl;
	}
	// cout<<M[3][4];

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll lim=200007;
ll sum=0,A[lim],Vis[lim];
map<ll,map<ll,ll>> M;
vector<ll> Adj[lim];
ll dfs(ll k,ll parent)
{
	// cout<<k<<" "<<parent<<endl;
	ll c=0;
	ll remaining=0;
	Vis[k]=1;
	sum+=A[k];
	for(ll i=0;i<Adj[k].size();i++)
	{
		if(Vis[Adj[k][i]]==0)
		{
			c++;
			remaining += dfs(Adj[k][i],k);
		}
	}
	// if(k==3) cout<<remaining<<"sudarsnh"<<endl;
	if(c==0)
	{
		M[parent][k]=A[k]; M[k][parent]=-1*A[k];
		return A[k];
	}
	else
	{
		M[parent][k]=remaining+A[k]; M[k][parent]=-1*remaining-A[k];
		return 1*remaining+A[k];
	}

}

int main() {
	ll n,m,X[lim],Y[lim];
	cin>>n;
	for(ll i=1;i<=n;i++) cin>>A[i];
	cin>>m;
	for(ll i=1;i<=m;i++)
	{
		cin>>X[i]>>Y[i];
		Adj[X[i]].push_back(Y[i]);
		Adj[Y[i]].push_back(X[i]);
	}

	for(ll i=1;i<=n;i++)
	{
		if(Vis[i]==0)
		{
			sum=0;
			dfs(i,i);
			if(sum!=0) {cout<<"Impossible";return 0;}

		}
	}

	cout<<"Possible"<<endl;
	for(ll i=1;i<=m;i++)
	{
		cout<<M[X[i]][Y[i]]<<endl;
	}
	// cout<<M[3][4];

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll lim=200007;
ll sum=0,A[lim],Vis[lim];
map<ll,map<ll,ll>> M;
vector<ll> Adj[lim];
ll dfs(ll k,ll parent)
{
	// cout<<k<<" "<<parent<<endl;
	ll c=0;
	ll remaining=0;
	Vis[k]=1;
	sum+=A[k];
	for(ll i=0;i<Adj[k].size();i++)
	{
		if(Vis[Adj[k][i]]==0)
		{
			c++;
			remaining += dfs(Adj[k][i],k);
		}
	}
	// if(k==3) cout<<remaining<<"sudarsnh"<<endl;
	if(c==0)
	{
		M[parent][k]=A[k]; M[k][parent]=-1*A[k];
		return A[k];
	}
	else
	{
		M[parent][k]=remaining+A[k]; M[k][parent]=-1*remaining-A[k];
	}

	return sum;
}

int main() {
	ll n,m,X[lim],Y[lim];
	cin>>n;
	for(ll i=1;i<=n;i++) cin>>A[i];
	cin>>m;
	for(ll i=1;i<=m;i++)
	{
		cin>>X[i]>>Y[i];
		Adj[X[i]].push_back(Y[i]);
		Adj[Y[i]].push_back(X[i]);
	}

	for(ll i=1;i<=n;i++)
	{
		if(Vis[i]==0)
		{
			sum=0;
			dfs(i,i);
			if(sum!=0) {cout<<"Impossible";return 0;}

		}
	}

	cout<<"Possible"<<endl;
	for(ll i=1;i<=m;i++)
	{
		cout<<M[X[i]][Y[i]]<<endl;
	}
	// cout<<M[3][4];

	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
typedef pair <int, int> pin;

const int N = 2e5 + 5;

int n, m, tot = 0, head[N], ufs[N], dep[N];
ll a[N], sum[N];
bool vis[N];
pin pat[N];

struct Edge {
	int to, nxt;
} e[N << 1];

inline void add(int from, int to) {
	e[++tot].to = to;
	e[tot].nxt = head[from];
	head[from] = tot;
}

template <typename T>
inline void read(T &X) {
	X = 0; char ch = 0; T op = 1;
	for (; ch > '9'|| ch < '0'; ch = getchar())
		if (ch == '-') op = -1;
	for (; ch >= '0' && ch <= '9'; ch = getchar())
		X = (X << 3) + (X << 1) + ch - 48;
	X *= op;
}

int find(int x) {
	return ufs[x] == x ? x : ufs[x] = find(ufs[x]);
}

inline bool merge(int x, int y) {
	int fx = find(x), fy = find(y);
	if (fx == fy) return 0;
	ufs[fx] = fy;
	return 1;
}

inline bool chk() {
	ll tmp = 0;
	for (int i = 1; i <= n; i++) tmp += a[i];
	return (!tmp);
}

void dfs(int x, int fat, int depth) {
	dep[x] = depth, sum[x] = a[x];
	for (int i = head[x]; i; i = e[i].nxt) {
		int y = e[i].to;
		if (y == fat) continue;
		dfs(y, x, depth + 1);
		sum[x] += sum[y];
	}
}

int main() {
	read(n);
	for (int i = 1; i <= n; i++) {
		read(a[i]);
		ufs[i] = i;
	}
	read(m);
	for (int x, y, i = 1; i <= m; i++) {
		read(x), read(y);
		pat[i].first = x, pat[i].second = y;
		if (!merge(x, y)) continue;
		vis[i] = 1;
		add(x, y), add(y, x);
	}

	if (!chk()) return puts("Impossible"), 0;

	dfs(1, 0, 1);

	puts("Possible");
	for (int i = 1; i <= m; i++) {
		if (vis[i])
			printf("%lld\n", dep[pat[i].first] < dep[pat[i].second] ? sum[pat[i].second] : -sum[pat[i].first]);
		else puts("0");
	}

	return 0;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <stack>
#include <deque>
#include <string.h>
#include <bitset>
#include <math.h>

using namespace std;

#define PI atan2(0, -1)
#define epsilon 0.000000001
#define INF 5000000000000000000
#define MOD 1000000007

int N, M, sum = 0, required [200010], parents [200010], heights [200010], subtreeSum [200010];
pair<int, int> edges [200010];
bool used [200010];
vector<int> adjacency [200010];

int findParent(int x){
    if(x == parents[x]) return x;
    parents[x] = findParent(parents[x]);
    return parents[x];
}

bool combine(int x, int y){
    int a = findParent(x); int b = findParent(y);
    if(a == b) return false;
    if(heights[b] < heights[a]) parents[b] = a;
    else if(heights[a] < heights[b]) parents[a] = b;
    else{
        parents[b] = a;
        heights[a]++;
    }
    return true;
}

void dfs(int curr, int prevy){
    subtreeSum[curr] = required[curr];
    for(int nexty : adjacency[curr]){
        if(nexty == prevy) continue;
        heights[nexty] = heights[curr]+1; dfs(nexty, curr);
        subtreeSum[curr] += subtreeSum[nexty];
        //cout << curr << " " << nexty << endl;
    }
}

int main(){
    //freopen("sort.in", "r", stdin); freopen("sort.out", "w", stdout);
    ios_base::sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(18);
    cin >> N;
    for(int i = 1; i <= N; i++){
        cin >> required[i]; sum += required[i];
        parents[i] = i; heights[i] = 0;
    }
    cin >> M;
    for(int i = 0; i < M; i++){
        cin >> edges[i].first >> edges[i].second;
        used[i] = combine(edges[i].first, edges[i].second);
        if(used[i]){
            adjacency[edges[i].first].push_back(edges[i].second);
            adjacency[edges[i].second].push_back(edges[i].first);
        }
    }
    if(sum != 0){
        cout << "Impossible\n";
        return 0;
    }
    cout << "Possible\n";
    memset(heights, 0, sizeof(heights)); dfs(1, 0);
    for(int i = 0; i < M; i++){
        int ret = 0;
        if(used[i]){
            //cout << edges[i].first << " " << edges[i].second << endl;
            //cout << heights[edges[i].first] << " " << heights[edges[i].second] << endl;
            if(heights[edges[i].first] < heights[edges[i].second]) ret = subtreeSum[edges[i].second];
            else ret = -subtreeSum[edges[i].first];
        }
        cout << ret << '\n';
    }
    return 0;
}


#define __USE_MINGW_ANSI_STDIO 0
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <stack>
#include <deque>
#include <string.h>
#include <bitset>
#include <math.h>

using namespace std;

#define PI atan2(0, -1)
#define epsilon 0.000000001
#define INF 5000000000000000000
#define MOD 1000000007

int N, M, sum = 0, required [200010], parents [200010], heights [200010], subtreeSum [200010];
pair<int, int> edges [200010];
bool used [200010];
vector<int> adjacency [200010];

int findParent(int x){
    if(x == parents[x]) return x;
    parents[x] = findParent(parents[x]);
    return parents[x];
}

bool combine(int x, int y){
    int a = findParent(x); int b = findParent(y);
    if(a == b) return false;
    if(heights[b] < heights[a]) parents[b] = a;
    else if(heights[a] < heights[b]) parents[a] = b;
    else{
        parents[b] = a;
        heights[a]++;
    }
    return true;
}

void dfs(int curr, int prevy){
    subtreeSum[curr] = required[curr];
    for(int nexty : adjacency[curr]){
        if(nexty == prevy) continue;
        dfs(nexty, curr); heights[nexty] = heights[curr]+1;
        subtreeSum[curr] += subtreeSum[nexty];
    }
}

int main(){
    //freopen("sort.in", "r", stdin); freopen("sort.out", "w", stdout);
    ios_base::sync_with_stdio(0); cin.tie(0); cout << fixed << setprecision(18);
    cin >> N;
    for(int i = 1; i <= N; i++){
        cin >> required[i]; sum += required[i];
        parents[i] = i; heights[i] = 0;
    }
    cin >> M;
    for(int i = 0; i < M; i++){
        cin >> edges[i].first >> edges[i].second;
        used[i] = combine(edges[i].first, edges[i].second);
        if(used[i]){
            adjacency[edges[i].first].push_back(edges[i].second);
            adjacency[edges[i].second].push_back(edges[i].first);
        }
    }
    if(sum != 0){
        cout << "Impossible\n";
        return 0;
    }
    cout << "Possible\n";
    memset(heights, 0, sizeof(heights)); dfs(1, 0);
    for(int i = 0; i < M; i++){
        int ret = 0;
        if(used[i]){
            if(heights[edges[i].first] < heights[edges[i].second]) ret = subtreeSum[edges[i].second];
            else ret = -subtreeSum[edges[i].first];
        }
        cout << ret << '\n';
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<int> cnt(200005, 0);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	queue<int> ones;
	for (int i = 0; i < n; i += 1) {
		if (cnt[i] == 1) ones.push(i+1);
	}
	while (!ones.empty()) {
		int p = ones.front();
		ones.pop();
		if (edges[p].empty()) continue;
		int next = *(edges[p].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (dir == 1) {
			f[{p, next}] = jnc[p-1];
			jnc[next-1] += jnc[p-1];
			jnc[p-1] = 0;
			edges[p].erase(next);
			edges[next].erase(-p);
			if (edges[next].size() == 1) ones.push(next);
		}
		else {
			f[{next, p}] = -jnc[p-1];
			jnc[next-1] -= -jnc[p-1];
			jnc[p-1] = 0;
			edges[next].erase(p);
			edges[p].erase(-next);
			if (edges[next].size() == 1) ones.push(next);
		}
	}
	for (int i = 0; i < n; i += 1) {
		if (edges[i+1].empty()) {
			if (jnc[i]) {
				cout << "Impossible" << endl;
				return ;
			}
		}
		else {
			if (!dfs(i+1)) {
				cout << "Impossible" << endl;
				return ;
			}
		}
	}
	cout << "Possible" << endl;
	for (int i = 0; i < m; i += 1) {
		cout << f[pipe[i]] << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
		cnt[pipe[i].first] += 1;
		cnt[pipe[i].second]+= 1;
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	if (dfs(1)) {
		cout << "Possible" << endl;
		for (int i = 0; i < m; i += 1) {
			cout << f[pipe[i]] << endl;
		}
	}
	else {
		cout << "Impossible" << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	if (dfs(1)) {
		cout << "Possible" << endl;
		for (int i = 0; i < m; i += 1) {
			cout << f[pipe[i]] << endl;
		}
	}
	else {
		cout << "Impossible" << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<int> cnt(200005, 0);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) {
			if (n == 200000) cout << cur << " " << jnc[cur-1] << endl;
			return false;
		}
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	queue<int> ones;
	for (int i = 0; i < n; i += 1) {
		if (cnt[i] == 1) ones.push(i+1);
	}
	while (!ones.empty()) {
		int p = ones.front();
		ones.pop();
		if (edges[p].empty()) continue;
		int next = *(edges[p].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (dir == 1) {
			f[{p, next}] = jnc[p-1];
			jnc[next-1] += jnc[p-1];
			jnc[p-1] = 0;
			edges[p].erase(next);
			edges[next].erase(-p);
			if (edges[next].size() == 1) ones.push(next);
		}
		else {
			f[{next, p}] = -jnc[p-1];
			jnc[next-1] -= -jnc[p-1];
			jnc[p-1] = 0;
			edges[next].erase(p);
			edges[p].erase(-next);
			if (edges[next].size() == 1) ones.push(next);
		}
	}
	for (int i = 0; i < n; i += 1) {
		if (edges[i+1].empty()) {
			if (jnc[i]) {
				cout << "Impossible" << endl;
				return ;
			}
		}
		else {
			if (!dfs(i+1)) {
				cout << "Impossible" << endl;
				if (n == 200000)
				cout << i+1 << endl;
				return ;
			}
		}
	}
	cout << "Possible" << endl;
	for (int i = 0; i < m; i += 1) {
		cout << f[pipe[i]] << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
		cnt[pipe[i].first] += 1;
		cnt[pipe[i].second]+= 1;
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<int> cnt(200005, 0);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	queue<int> ones;
	for (int i = 0; i < n; i += 1) {
		if (cnt[i] == 1) ones.push(i+1);
	}
	while (!ones.empty()) {
		int p = ones.front();
		ones.pop();
		if (edges[p].empty()) continue;
		int next = *(edges[p].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (dir == 1) {
			f[{p, next}] = jnc[p-1];
			jnc[next-1] += jnc[p-1];
			jnc[p-1] = 0;
			edges[p].erase(next);
			edges[next].erase(-p);
			if (edges[next].size() == 1) ones.push(next);
		}
		else {
			f[{next, p}] = -jnc[p-1];
			jnc[next-1] -= -jnc[p-1];
			jnc[p-1] = 0;
			edges[next].erase(p);
			edges[p].erase(-next);
			if (edges[next].size() == 1) ones.push(next);
		}
	}
	for (int i = 0; i < n; i += 1) {
		if (edges[i+1].empty()) {
			if (jnc[i]) {
				cout << "Impossible" << endl;
				return ;
			}
		}
		else {
			if (!dfs(i+1)) {
				cout << "Impossible" << endl;
				if (n == 200000) cout << "dfs" << endl;
				return ;
			}
		}
	}
	cout << "Possible" << endl;
	for (int i = 0; i < m; i += 1) {
		cout << f[pipe[i]] << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
		cnt[pipe[i].first] += 1;
		cnt[pipe[i].second]+= 1;
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<int> cnt(200005, 0);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	queue<int> ones;
	for (int i = 0; i < n; i += 1) {
		if (cnt[i] == 1) ones.push(i+1);
	}
	while (!ones.empty()) {
		int p = ones.front();
		ones.pop();
		if (edges[p].empty()) continue;
		int next = *(edges[p].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (dir == 1) {
			f[{p, next}] = jnc[p-1];
			jnc[next-1] += jnc[p-1];
			jnc[p-1] = 0;
			edges[p].erase(next);
			edges[next].erase(-p);
			if (edges[next].size() == 1) ones.push(next);
		}
		else {
			f[{next, p}] = -jnc[p-1];
			jnc[next-1] -= -jnc[p-1];
			jnc[p-1] = 0;
			edges[next].erase(p);
			edges[p].erase(-next);
			if (edges[next].size() == 1) ones.push(next);
		}
	}
	for (int i = 0; i < n; i += 1) {
		if (edges[i+1].empty()) {
			if (jnc[i]) {
				cout << "Impossible" << endl;
				return ;
			}
		}
		else {
			if (!dfs(i+1)) {
				cout << "Impossible" << endl;
				if (n == 200000)
				cout << i+1 << endl;
				return ;
			}
		}
	}
	cout << "Possible" << endl;
	for (int i = 0; i < m; i += 1) {
		cout << f[pipe[i]] << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
		cnt[pipe[i].first] += 1;
		cnt[pipe[i].second]+= 1;
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<int> cnt(200005, 0);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	queue<int> ones;
	for (int i = 0; i < n; i += 1) {
		if (cnt[i] == 1) ones.push(i+1);
	}
	while (!ones.empty()) {
		int p = ones.front();
		ones.pop();
		if (edges[p].empty()) continue;
		int next = *(edges[p].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (dir == 1) {
			f[{p, next}] = jnc[p-1];
			jnc[next-1] += jnc[p-1];
			jnc[p-1] = 0;
			edges[p].erase(next);
			edges[next].erase(-p);
			if (edges[next].size() == 1) ones.push(next);
		}
		else {
			f[{next, p}] = -jnc[p-1];
			jnc[next-1] -= -jnc[p-1];
			jnc[p-1] = 0;
			edges[next].erase(p);
			edges[p].erase(-next);
			if (edges[next].size() == 1) ones.push(next);
		}
	}
	for (int i = 0; i < n; i += 1) {
		if (edges[i+1].empty()) {
			if (jnc[i]) {
				cout << "Impossible" << endl;
				return ;
			}
		}
		else {
			if (!dfs(i+1)) {
				cout << "Impossible" << endl;
				cout << i+1 << endl;
				return ;
			}
		}
	}
	cout << "Possible" << endl;
	for (int i = 0; i < m; i += 1) {
		cout << f[pipe[i]] << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
		cnt[pipe[i].first] += 1;
		cnt[pipe[i].second]+= 1;
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<pair<int, int>> pipe(200005);
vector<int> edges[200005];

vector<int> p(200005, 0);
vector<int> rk(200005, 1);
vector<bool> used(200005, false);
vector<int> h(200005, 0);

int getP(int u) {
	if (u == p[u])
		return u;
	else {
		p[u] = getP(p[u]);
		return p[u];
	}
}

bool merge(int u, int v)
{
	u = getP(u);
	v = getP(v);
	if (u == v) return false;
	if (rk[u] > rk[v]) swap(v, u);
	p[u] = v;
	rk[v] += rk[u];
	return true;
}

void dfs(int cur, int par)
{
	for (int next : edges[cur]) {
		if (next == par) continue;
		h[next] = h[cur] + 1;
		dfs(next, cur);
		jnc[cur] += jnc[next];
	}
}

void cal()
{
	long long sum = 0;
	for (int i = 1; i <= n; i += 1) sum += jnc[i];
	if (sum != 0) {
		cout << "Impossible" << endl;
		return ;
	}
	else {
		cout << "Possible" << endl;
	}

    dfs(1, 0);

	for (int i = 0; i < m; i += 1) {
		if (used[i]) {
			if (h[pipe[i].first] < h[pipe[i].second]) {
				cout << jnc[pipe[i].second] << endl;
			}
			else {
				cout << -jnc[pipe[i].first] << endl;
			}
		}
		else {
			cout << 0 << endl;
		}
	}
}

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i += 1) {
		cin >> jnc[i];
		p[i] = i;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		if (merge(pipe[i].first, pipe[i].second)) {
			edges[pipe[i].first].push_back(pipe[i].second);
			edges[pipe[i].second].push_back(pipe[i].first);
			used[i] = true;
		}
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<int> cnt(200005, 0);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	queue<int> ones;
	for (int i = 0; i < n; i += 1) {
		if (cnt[i] == 1) ones.push(i+1);
	}
	while (!ones.empty()) {
		int p = ones.front();
		ones.pop();
		int next = *(edges[p].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (dir == 1) {
			f[{p, next}] = jnc[p-1];
			jnc[next-1] += jnc[p-1];
			jnc[p-1] = 0;
			edges[p].erase(next);
			edges[next].erase(-p);
			if (edges[next].size() == 1) ones.push(next);
		}
		else {
			f[{next, p}] = -jnc[p-1];
			jnc[next-1] -= -jnc[p-1];
			jnc[p-1] = 0;
			edges[next].erase(p);
			edges[p].erase(-next);
			if (edges[next].size() == 1) ones.push(next);
		}
	}
	for (int i = 0; i < n; i += 1) {
		if (edges[i+1].empty()) {
			if (jnc[i]) {
				cout << "Impossible" << endl;
				return ;
			}
		}
		else {
			if (!dfs(i+1)) {
				cout << "Impossible" << endl;
				return ;
			}
		}
	}
	cout << "Possible" << endl;
	for (int i = 0; i < m; i += 1) {
		cout << f[pipe[i]] << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
		cnt[pipe[i].first] += 1;
		cnt[pipe[i].second]+= 1;
	}
	cal();
}


#include <iostream>
#include <vector>
#include <map>
#include <unordered_set>
#include <queue>

using namespace std;
int n, m;
vector<int> jnc(200005);
vector<int> cnt(200005, 0);
vector<pair<int, int>> pipe(200005);
unordered_set<int> edges[200005];
map<pair<int, int>, int> f;

bool dfs(int cur)
{
	if (edges[cur].empty()) {
		if (jnc[cur-1]) return false;
		else return true;
	}
	bool ret = true;
	while (!edges[cur].empty() && ret) {
		int next = *(edges[cur].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (edges[cur].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = jnc[cur-1];
				jnc[next-1] += jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = -jnc[cur-1];
				jnc[next-1] -= -jnc[cur-1];
				jnc[cur-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
		else if (edges[next].size() == 1) {
			if (dir == 1) {
				f[{cur, next}] = -jnc[next-1];
				jnc[cur-1] -= -jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = jnc[next-1];
				jnc[cur-1] += jnc[next-1];
				jnc[next-1] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
		}
		else {
			if (dir == 1) {
				f[{cur, next}] = 0;
				edges[cur].erase(next);
				edges[next].erase(-cur);
			}
			else {
				f[{next, cur}] = 0;
				edges[cur].erase(-next);
				edges[next].erase(cur);
			}
			ret = dfs(next);
		}
	}
	return ret;
}

void cal()
{
	queue<int> ones;
	for (int i = 0; i < n; i += 1) {
		if (cnt[i] == 1) ones.push(i+1);
	}
	while (!ones.empty()) {
		int p = ones.front();
		ones.pop();
		if (edges[p].empty()) continue;
		int next = *(edges[p].begin());
		int dir = 1;
		if (next < 0) {
			dir = -1;
			next= -next;
		}
		if (dir == 1) {
			f[{p, next}] = jnc[p-1];
			jnc[next-1] += jnc[p-1];
			jnc[p-1] = 0;
			edges[p].erase(next);
			edges[next].erase(-p);
			if (edges[next].size() == 1) ones.push(next);
		}
		else {
			f[{next, p}] = -jnc[p-1];
			jnc[next-1] -= -jnc[p-1];
			jnc[p-1] = 0;
			edges[next].erase(p);
			edges[p].erase(-next);
			if (edges[next].size() == 1) ones.push(next);
		}
	}
	for (int i = 0; i < n; i += 1) {
		if (edges[i+1].empty()) {
			if (jnc[i]) {
				cout << "Impossible" << endl;
				return ;
			}
		}
		else {
			if (!dfs(i+1)) {
				cout << "dfs Impossible" << endl;
				return ;
			}
		}
	}
	cout << "Possible" << endl;
	for (int i = 0; i < m; i += 1) {
		cout << f[pipe[i]] << endl;
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i += 1) {
		cin >> jnc[i];
		jnc[i] *= -1;
	}
	cin >> m;
	for (int i = 0; i < m; i += 1) {
		cin >> pipe[i].first >> pipe[i].second;
		edges[pipe[i].first].insert(pipe[i].second);
		edges[pipe[i].second].insert(-pipe[i].first);
		cnt[pipe[i].first] += 1;
		cnt[pipe[i].second]+= 1;
	}
	cal();
}


#include <cstdio>

int f[200010],s[200010],ans[200010],n,m,t1,t2,head[200010],nxt[400010],b[400010],flow[400100],k;
int find(int x){return f[x]?f[x]=find(f[x]):x;}
void push(int s,int t,int edge){
    nxt[++k]=head[s];
    head[s]=k;
    b[k]=t;
    flow[k]=edge;
}
void dfs(int x,int f){
    for(int i=head[x];i;i=nxt[i])
        if(b[i]!=f){
            dfs(b[i],x);
            int flag=flow[i]>0?1:(flow[i]=-flow[i],-1);
            ans[flow[i]]=flag*s[b[i]];
            s[x]+=s[b[i]],s[b[i]]=0;
        }
}
int main(){
    scanf("%d",&n);
    int tot=0;
    for(int i=1;i<=n;i++)scanf("%d",s+i);
    int tem=s[1];
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&t1,&t2);
        t1=find(t1),t2=find(t2);
        if(t1==t2)continue;
        push(t1,t2,i);
        push(t2,t1,-i);
        f[t1]=t2;
    }
    dfs(1,0);
    if(s[1])puts("Impossible");
    else{
        puts("Possible");
        for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    }
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200010
using namespace std;
int a[N],head[N],to[N*2],nxt[N*2],idx[N*2],flow[N],S[N],rev[N*2];
int n,m,eCnt,ans;
bool vis[N];
inline int read(){
    int x=0,flag=1;
    char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=-1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch^'0');
    return x*flag;
}
inline void add(int u,int v,int i,int r){
    eCnt++;
    nxt[eCnt]=head[u];
    to[eCnt]=v;
    idx[eCnt]=i;
    rev[eCnt]=r;
    head[u]=eCnt;
}
void DFS(int x){
    vis[x]=true;
    S[x]=a[x];
    for(int i=head[x];i;i=nxt[i]){
        int y=to[i];
        if(vis[y])
            continue;
        DFS(y);
        S[x]+=S[y];
        if(rev[i])
            flow[idx[i]]=-S[y];
        else
            flow[idx[i]]=S[y];
    }
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)
        a[i]=read();
    m=read();
    int u,v;
    for(int i=1;i<=m;i++){
        u=read(),v=read();
        add(u,v,i,0);
        add(v,u,i,1);
    }
    DFS(1);
    if(S[1]){
        printf("Impossible");
        return 0;
    }
    printf("Possible\n");
    for(int i=1;i<=m;i++){
        printf("%d\n",flow[i]);
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200010;
typedef long long ll;
int n,f[N],fa[N],m,x,y,fx,fy;
ll a[N],ans[N],sum[N],s;
int p,head[N],nxt[N<<1],w[N<<1],to[N<<1];
bool tp[N<<1];
inline void add(int x,int y,int z) {
	to[++p]=y; w[p]=z; nxt[p]=head[x]; tp[p]=0; head[x]=p;
	to[++p]=x; w[p]=z; nxt[p]=head[y]; tp[p]=1; head[y]=p;
}
int getf(int x) {return x==f[x]?x:f[x]=getf(f[x]);}
void dfs(int x) {
	sum[x]+=a[x];
	for (int i=head[x]; i; i=nxt[i]) {
		if (fa[x]==to[i]) continue;
		fa[to[i]]=x;
		dfs(to[i]);
		sum[x]+=sum[to[i]];
		if (!tp[i]) ans[w[i]]=sum[to[i]];
		else ans[w[i]]=-sum[to[i]];
	}
}
int main() {
	scanf("%d",&n);
	for (int i=1; i<=n; i++) scanf("%lld",&a[i]),s+=a[i];
	if (s) {puts("Impossible"); return 0;}
	scanf("%d",&m);
	for (int i=1; i<=n; i++) f[i]=i;
	for (int i=1; i<=m; i++) {
		scanf("%d%d",&x,&y);
		if ((fx=getf(x))==(fy=getf(y))) continue;
		f[fx]=fy; add(x,y,i);
	}
	dfs(1);
	puts("Possible");
	for (int i=1; i<=m; i++) printf("%lld\n",ans[i]);
	return 0;
}


// awa

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

const int N = 2e5 + 52;

struct edge {
	int to, next, f, id;
} e[N << 1];
int head[N], cnt;
void addedge(int x, int y, int id) {
	e[++cnt] = {y, x[head], 1, id}, x[head] = cnt;
	e[++cnt] = {x, y[head], -1, id}, y[head] = cnt;
}

int p[N];
int f(int x) { return p[x] ? p[x] = f(p[x]) : x; }
void $(int x, int y) {
	if ((x = f(x)) != (y = f(y))) x[p] = y;
}

int n, a[N], m, x, y, s[N], ans[N];
void dfs(int x, int p) {
	x[s] = x[a];
	for (int i = head[x], nx; i; i = e[i].next)
		if ((nx = e[i].to) != p) {
			dfs(nx, x);
			ans[e[i].id] = e[i].f * nx[s];
			x[s] += nx[s];
		}
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", a + i), x += a[i];
	if (x) return puts("Impossible"), 0;
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &x, &y);
		if (f(x) ^ f(y)) $(x, y), addedge(x, y, i);
	}
	dfs(1, 0);
	puts("Possible");
	for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
}


#include <cstdio>

int f[200001],s[200001],ans[200001],n,m,t1,t2,head[200001],nxt[400001],b[400001],flow[400001],k;
int find(int x){return f[x]?f[x]=find(f[x]):x;}
void push(int s,int t,int edge){
    nxt[++k]=head[s];
    head[s]=k;
    b[k]=t;
    flow[k]=edge;
}
void dfs(int x,int f){
    for(int i=head[x];i;i=nxt[i])
        if(b[i]!=f){
            dfs(b[i],x);
            int flag=flow[i]>0?1:(flow[i]=-flow[i],-1);
            ans[flow[i]]=flag*s[b[i]];
            s[x]+=s[b[i]];
        }
}
int main(){
    scanf("%d",&n);
    int tot=0;
    for(int i=1;i<=n;i++)scanf("%d",s+i);
    int tem=s[1];
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&t1,&t2);
        t1=find(t1),t2=find(t2);
        if(t1==t2)continue;
        push(t1,t2,i);
        push(t2,t1,-i);
        f[t1]=t2;
    }
    dfs(1,0);
    if(s[1])puts("Impossible");
    else{
        puts("Possible");
        for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    }
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1000010
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define dwn(i,x,y) for(register int i=x;i>=y;--i)
using namespace std;
int n,m,tot,input,output,head[N],a[N],vis[N],ans[N];
struct node{int nex,to;}e[N<<1];
inline int read(){
	int fl=1,sum=0;char w=getchar();
	while(w>'9'||w<'0'){if(w=='-')fl=-1;w=getchar();}
	while(w>='0'&&w<='9'){sum=sum*10+w-'0';w=getchar();}
	return fl*sum;
}
inline void print(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>=10) print(x/10);
	putchar(x%10+'0');
}
inline void add(int u,int v){
	e[++tot].nex=head[u];e[tot].to=v;head[u]=tot;
}
inline void dfs(int u){
	vis[u]=1;
	for(int i=head[u];i;i=e[i].nex){
		int v=e[i].to;
		if(!vis[v]){
			dfs(v),ans[i]+=a[v],a[u]+=a[v],a[v]=0;
		}
	}
}
int main(){
//	freopen("flow.in","r",stdin);
//	freopen("flow.out","w",stdout);
    n=read();
    rep(i,1,n){
       a[i]=read();
	   if(a[i]>0) output+=a[i];
	   else if(a[i]<0) input+=(-a[i]);
	}
	m=read();
    rep(i,1,m){
    	int u=read(),v=read();add(u,v);add(v,u);
	}
	if(output!=input){puts("Impossible");return 0;}
	puts("Possible");
	dfs(1);
	rep(i,1,m) print(ans[i*2-1]-ans[i*2]),putchar('\n');
	return 0;
}


#include <cstdio>

int f[200001],s[200001],ans[200001],n,m,t1,t2,head[200001],nxt[400001],b[400001],flow[400001],k;
int find(int x){return f[x]?f[x]=find(f[x]):x;}
void push(int s,int t,int edge){
    nxt[++k]=head[s];
    head[s]=k;
    b[k]=t;
    flow[k]=edge;
}
void dfs(int x,int f){
    for(int i=head[x];i;i=nxt[i])
        if(b[i]!=f){
            dfs(b[i],x);
            int flag=flow[i]>0?1:(flow[i]=-flow[i],-1);
            ans[flow[i]]=flag*s[b[i]];
            s[x]+=s[b[i]],s[b[i]]=0;
        }
}
int main(){
    scanf("%d",&n);
    int tot=0;
    for(int i=1;i<=n;i++)scanf("%d",s+i);
    int tem=s[1];
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&t1,&t2);
        t1=find(t1),t2=find(t2);
        if(t1==t2)continue;
        push(t1,t2,i);
        push(t2,t1,-i);
        f[t1]=t2;
    }
    dfs(1,0);
    if(s[1])puts("Impossible");
    else{
        puts("Possible");
        for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    }
}


#include<iostream>
#include<iomanip>
#include<cctype>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
using namespace std;

const int MAXN = 200005;
const int MAXM = 300005;

struct _edge{
	int next, to, len;
	_edge(int next=0, int to=0, int len=0):next(next), to(to), len(len){}
	#define next(x) edge[x].next
	#define to(x) edge[x].to
	#define len(x) edge[x].len
}edge[MAXM<<1];

int first[MAXN], sz[MAXN], fa[MAXN], n, m, tot;
int need[MAXN];
char visit[MAXN];

inline void Add_Edge(int f, int t){
	edge[++tot] = _edge(first[f], t); first[f] = tot;
	edge[++tot] = _edge(first[t], f); first[t] = tot;
}

inline int other(int x){return ((x+1)^1)-1;}

inline void Work(int ind, int val){
	len(ind) += val;
	len(other(ind)) -= val;
}

inline void Dfs(int x){
	sz[x] = need[x];
	for(register int u=first[x]; u; u=next(u)){
		int v=to(u);
		if(fa[v] != x && visit[v] == false){
			visit[v] = true;
			fa[v] = x;
			Dfs(v);
			Work(u, sz[v]);
			sz[x] += sz[v];
		}
	}
}

int main(){
	scanf("%d", &n);
	long long sum=0;
	for(register int i=1; i<=n; i++){
		scanf("%d", &need[i]);
		sum += need[i];
	}
	if(sum){
		puts("Impossible");
		return 0;
	}
	puts("Possible");
	scanf("%d", &m);
	for(register int i=1; i<=m; i++){
		int f, t;
		scanf("%d%d", &f, &t);
		Add_Edge(f, t);
	}
	visit[1] = true;
	Dfs(1);
	for(register int i=1; i<=m; i++){
		printf("%d\n", len((i<<1)+1));
	}
	return 0;
}


#include <cstdio>

int d[200001];
int f[200001],s[200001],ans[200001],n,m,t1,t2,head[200001],nxt[400001],b[400001],flow[400001],k;
int find(int x){return f[x]?f[x]=find(f[x]):x;}
void push(int s,int t,int edge){
    nxt[++k]=head[s];
    head[s]=k;
    b[k]=t;
    flow[k]=edge;
}
void dfs(int x,int f){
    d[x]=s[x];
    for(int i=head[x];i;i=nxt[i])
        if(b[i]!=f){
            dfs(b[i],x);
            int flag=(flow[i]>0)?1:(flow[i]=-flow[i],-1);
            ans[flow[i]]=flag*d[b[i]];
            d[x]+=d[b[i]];
        }
}
int main(){
    scanf("%d",&n);
    int tot=0;
    for(int i=1;i<=n;i++)scanf("%d",s+i);
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&t1,&t2);
        t1=find(t1),t2=find(t2);
        if(t1==t2)continue;
        push(t1,t2,i);
        push(t2,t1,-i);
        f[t1]=t2;
    }
    dfs(1,0);
    int f=0;
    for(int i=head[1];i;i=nxt[i])
        f+=d[b[i]];
    if(s[1]+f!=0)puts("Impossible");
    else{
        puts("Possible");
        for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
    }
}


#include <cstdio>

int f[200001],s[200001],ans[200001],n,m,t1,t2,head[200001],nxt[400001],b[400001],flow[400001],k;
int find(int x){return f[x]?f[x]=find(f[x]):x;}
void push(int s,int t,int edge){
    nxt[++k]=head[s];
    head[s]=k;
    b[k]=t;
    flow[k]=edge;
}
void dfs(int x,int f){
    for(int i=head[x];i;i=nxt[i])
        if(b[i]!=f){
            dfs(b[i],x);
            int flag=flow[i]>0?1:(flow[i]=-flow[i],-1);
            ans[flow[i]]=flag*s[b[i]];
            s[x]+=s[b[i]];
        }
}
int main(){
    scanf("%d",&n);
    int tot=0;
    for(int i=1;i<=n;i++)scanf("%d",s+i),tot+=s[i];
    if(tot){
        puts("Impossible");
        return 0;
    }
    puts("Possible");
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d",&t1,&t2);
        t1=find(t1),t2=find(t2);
        if(t1==t2)continue;
        push(t1,t2,i);
        push(t2,t1,-i);
        f[t1]=t2;
    }
    dfs(1,0);
    for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
}


#include <cstdio>
#include <cstring>
#include<iostream>
#include <algorithm>
#define rint register int
using namespace std;

template <class T>inline void read(T &X)
{
	X=0;int W=0;char ch=0;
	while(!isdigit(ch))W|=ch=='-',ch=getchar();
	while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	X=W?-X:X;return;
}

int cnt=0,tot=0,head[200010];
struct node{int to,next,num,w;}edge[600010];
int n,m,ne[400010],a[200010],f[400010];
bool vis[200010];

void add(int u,int v,int num,int w)
{
	edge[++cnt].to=v;
	edge[cnt].num=num;
	edge[cnt].w=w;
	edge[cnt].next=head[u];
	head[u]=cnt;
}

int dfs(int x) {
    int now=a[x];
    vis[x]=1;
    for(rint i=head[x];i;i=edge[i].next)
    {
    	int to=edge[i].to;
        if (!vis[to])
		{
            int tow=dfs(to);
         	now+=tow;
            f[edge[i].num]=(tow*edge[i].w);
        }
    }
	return now;
}

int main() {
       // freopen("flow.in","r",stdin);
      //  freopen("flow.out","w",stdout);
        read(n);
        for(rint i=1;i<=n;++i)
			read(a[i]),tot+=a[i];
        read(m);
        for(rint i=1;i<=m;++i)
		{
                int x,y;
				read(x),read(y);
                add(x,y,i,1),add(y,x,i,-1);
        }
        if(tot)
		{
            printf("Impossible\n");
            return 0;
        }
        printf("Possible\n");
        dfs(1);
        for(rint i=1;i<=m;++i) printf("%d\n",f[i]);
}


#include <iostream>
#include <cstdio>
using namespace std;
int n, s[200005], m, hea[200005], sum[200005], uu, vv, dep[200005];
int ru[200005], cnt;
bool vis[200005];
struct Edge{
	int fro, too, nxt, iso;
}edge[200005];
void add_edge(int fro, int too){
	edge[++cnt].nxt = hea[fro];
	edge[cnt].fro = fro;
	edge[cnt].too = too;
	hea[fro] = cnt;
}
void dfs1(int x){
	vis[x] = true;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(vis[t])	continue;
		edge[i].iso = 1;
		dfs1(t);
	}
}
void dfs2(int x, int f){
	sum[x] = s[x];
	dep[x] = dep[f] + 1;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(!edge[i].iso || t==f)	continue;
		dfs2(t, x);
		sum[x] += sum[t];
	}
}
int main(){
	cin>>n;
	int qwq=0;
	for(int i=1; i<=n; i++){
		scanf("%d", &s[i]);
		qwq += s[i];
	}
	if(qwq){
		printf("Impossible\n");
		return 0;
	}
	cin>>m;
	for(int i=1; i<=m; i++){
		scanf("%d %d", &uu, &vv);
		add_edge(uu, vv);
		ru[vv]++;
	}
	int beg=1;
	for(int i=1; i<=n; i++)
		if(!ru[i]){
			beg = i;
			break;
		}
	dfs1(beg);
	dfs2(beg, 0);
	printf("Possible\n");
	for(int i=1; i<=m; i++){
		if(!edge[i].iso)	printf("0\n");
		else if(dep[edge[i].fro]<dep[edge[i].too])
			printf("%d\n", sum[edge[i].too]);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
int n, s[200005], hea[200005], cnt, m, ru[200005], uu, vv, bgn;
int qwq[200005];
bool vis[200005];
struct Edge{
	int too, nxt, val;
}edge[200005];
void add_edge(int fro, int too){
	edge[++cnt].nxt = hea[fro];
	edge[cnt].too = too;
	hea[fro] = cnt;
}
void dfs(int x){
	vis[x] = true;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(vis[t])	continue;
		dfs(t);
		edge[i].val = s[t] - qwq[t];
		qwq[x] -= edge[i].val;
	}
}
int main(){
	cin>>n;
	int sum=0;
	for(int i=1; i<=n; i++){
		scanf("%d", &s[i]);
		sum += s[i];
	}
	if(sum){
		printf("Impossible\n");
		return 0;
	}
	cin>>m;
	for(int i=1; i<=m; i++){
		scanf("%d %d", &uu, &vv);
		add_edge(uu, vv);
		ru[vv]++;
	}
	bgn = 1;
	for(int i=1; i<=n; i++)
		if(!ru[i]){
			bgn = i;
			break;
		}
	dfs(bgn);
	printf("Possible\n");
	for(int i=1; i<=m; i++)
		printf("%d\n", edge[i].val);
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
int n, s[200005], m, hea[200005], cnt, uu[200005], vv[200005];
int fa[200005], sum[200005], dep[200005];
bool vis[200005];
struct Edge{
	int too, nxt;
}edge[400005];
int myfind(int x){
	return fa[x]==x?x:fa[x]=myfind(fa[x]);
}
void add_edge(int fro, int too){
	edge[++cnt].nxt = hea[fro];
	edge[cnt].too = too;
	hea[fro] = cnt;
}
void dfs(int x, int f){
	sum[x] = s[x];
	dep[x] = dep[f] + 1;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(t!=f){
			dfs(t, x);
			sum[x] += sum[t];
		}
	}
}
int main(){
	cin>>n;
	int orz=0;
	for(int i=1; i<=n; i++){
		scanf("%d", &s[i]);
		orz += s[i];
		fa[i] = i;
	}
	if(orz){
		printf("Impossible\n");
		return 0;
	}
	cin>>m;
	for(int i=1; i<=m; i++){
		scanf("%d %d", &uu[i], &vv[i]);
		int p=myfind(uu[i]), q=myfind(vv[i]);
		if(p!=q){
			vis[i] = true;
			add_edge(uu[i], vv[i]);
			add_edge(vv[i], uu[i]);
			fa[q] = p;
		}
	}
	dfs(1, 0);
	for(int i=1; i<=m; i++){
		if(!vis[i])	printf("0\n");
		else if(dep[uu[i]]<dep[vv[i]])	printf("%d\n", sum[vv[i]]);
		else	printf("%d\n", -sum[uu[i]]);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
int n, s[200005], m, hea[200005], sum[200005], uu, vv, dep[200005];
int ru[200005], cnt;
bool vis[200005];
struct Edge{
	int fro, too, nxt, iso;
}edge[200005];
void add_edge(int fro, int too){
	edge[++cnt].nxt = hea[fro];
	edge[cnt].too = too;
	hea[fro] = cnt;
}
void dfs1(int x){
	vis[x] = true;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(vis[t])	continue;
		edge[i].iso = 1;
		dfs1(t);
	}
}
void dfs2(int x, int f){
	sum[x] = s[x];
	dep[x] = dep[f] + 1;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(!edge[i].iso || t==f)	continue;
		dfs2(t, x);
		sum[x] += sum[t];
	}
}
int main(){
	cin>>n;
	int qwq=0;
	for(int i=1; i<=n; i++){
		scanf("%d", &s[i]);
		qwq += s[i];
	}
	if(qwq){
		printf("Impossible\n");
		return 0;
	}
	cin>>m;
	for(int i=1; i<=m; i++){
		scanf("%d %d", &uu, &vv);
		add_edge(uu, vv);
		ru[vv]++;
	}
	int beg=1;
	for(int i=1; i<=n; i++)
		if(!ru[i]){
			beg = i;
			break;
		}
	dfs1(beg);
	dfs2(beg, 0);
	printf("Possible\n");
	for(int i=1; i<=m; i++){
		if(!edge[i].iso)	printf("0\n");
		else if(dep[edge[i].fro]<dep[edge[i].too])
			printf("%d\n", sum[edge[i].too]);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
using namespace std;
int n, s[200005], m, hea[200005], cnt, uu[200005], vv[200005];
int fa[200005], sum[200005], dep[200005];
bool vis[200005];
struct Edge{
	int too, nxt;
}edge[400005];
int myfind(int x){
	return fa[x]==x?x:fa[x]=myfind(fa[x]);
}
void add_edge(int fro, int too){
	edge[++cnt].nxt = hea[fro];
	edge[cnt].too = too;
	hea[fro] = cnt;
}
void dfs(int x, int f){
	sum[x] = s[x];
	dep[x] = dep[f] + 1;
	for(int i=hea[x]; i; i=edge[i].nxt){
		int t=edge[i].too;
		if(t!=f){
			dfs(t, x);
			sum[x] += sum[t];
		}
	}
}
int main(){
	cin>>n;
	int orz=0;
	for(int i=1; i<=n; i++){
		scanf("%d", &s[i]);
		orz += s[i];
		fa[i] = i;
	}
	if(orz){
		printf("Impossible\n");
		return 0;
	}
	cin>>m;
	for(int i=1; i<=m; i++){
		scanf("%d %d", &uu[i], &vv[i]);
		int p=myfind(uu[i]), q=myfind(vv[i]);
		if(p!=q){
			vis[i] = true;
			add_edge(uu[i], vv[i]);
			add_edge(vv[i], uu[i]);
			fa[q] = p;
		}
	}
	dfs(1, 0);
	printf("Possible\n");
	for(int i=1; i<=m; i++){
		if(!vis[i])	printf("0\n");
		else if(dep[uu[i]]<dep[vv[i]])	printf("%d\n", sum[vv[i]]);
		else	printf("%d\n", -sum[uu[i]]);
	}
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <map>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define sd(x) scanf("%d",&x);
#define sll(x) scanf("%I64d",&x);
#define pd(x) printf("%d",x);
#define pll(x) printf("%I64d",x);

ll s[200001];
vector<ll> v[200001];
map<pll, ll> f;
bool vis[200001];

void func(int x,int y)
{
	vis[x] = 1;
	ll t = 0;
	for (ll i = 0; i < v[x].size(); i++)
	{
		if(vis[v[x][i]] == 0)
		{
			func(v[x][i],x);
			t += f[make_pair(v[x][i],x)];
		}
	}
	f[make_pair(x,y)] = t - s[x];
	f[make_pair(y,x)] = s[x] - t;
}

ll x[200001],y[200001];

int main()
{
	ll n,t = 0,m;
	sll(n);
	for (ll i = 0; i < n; ++i)
		sll(s[i+1]);
	for (ll i = 0; i < n; ++i)
		t += s[i+1];
	if(t != 0)
	{
		cout << "Impossible";
		return 0;
	}
	sll(m);
	for (ll i = 0; i < m; ++i)
	{
		sll(x[i]);
		sll(y[i]);
		v[x[i]].push_back(y[i]);
		v[y[i]].push_back(x[i]);
	}
	vis[1] = 1;
	for (ll i = 0; i < v[1].size(); i++)
	{
		if(vis[v[1][i]] == 0)
			func(v[1][i],1);
	}
	cout << "Possible" << endl;
	for (ll i = 0; i < m; ++i)
	{
		cout<<f[make_pair(x[i],y[i])] << endl;
	}
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <map>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define sd(x) scanf("%d",&x);
#define sll(x) scanf("%I64d",&x);
#define pd(x) printf("%d",x);
#define pll(x) printf("%I64d",x);

ll s[200001];
vector<ll> v[200001];
map<pll, ll> f;
bool vis[200001];

void func(int x,int y)
{
	vis[x] = 1;
	ll t = 0;
	for (ll i = 0; i < v[x].size(); i++)
	{
		if(vis[v[x][i]] == 0)
		{
			func(v[x][i],x);
			t += f[make_pair(v[x][i],x)];
		}
	}
	cout << x << " " << y << " " << t << " " << s[x] << endl;
	f[make_pair(x,y)] = t - s[x];
	f[make_pair(y,x)] = s[x] - t;
}

ll x[200001],y[200001];

int main()
{
	ll n,t = 0,m;
	sll(n);
	for (ll i = 0; i < n; ++i)
		sll(s[i+1]);
	for (ll i = 0; i < n; ++i)
		t += s[i+1];
	if(t != 0)
	{
		cout << "Impossible";
		return 0;
	}
	sll(m);
	for (ll i = 0; i < m; ++i)
	{
		sll(x[i]);
		sll(y[i]);
		v[x[i]].push_back(y[i]);
		v[y[i]].push_back(x[i]);
	}
	vis[1] = 1;
	for (ll i = 0; i < v[1].size(); i++)
	{
		if(vis[v[1][i]] == 0)
			func(v[1][i],1);
	}
	cout << "Possible" << endl;
	for (ll i = 0; i < m; ++i)
	{
		cout<<f[make_pair(x[i],y[i])] << endl;
	}
	return 0;
}


#include <bits/stdc++.h>

#define pb push_back
#define fi first
#define se second
using namespace std;
typedef pair<int, int> PII;
const int maxn = 2e5 + 5;

vector<PII> G[maxn];
int u[maxn], v[maxn];
int n, s[maxn], vis[maxn], res[maxn];

void dfs(int now) {
    vis[now] = 1;
    for (auto &x : G[now]) {
        int son = x.fi, id = x.se;
        if (vis[son]) continue;
        dfs(son);
        s[now] += s[son];
        res[id] = (v[id] == son ? s[son] : -s[son]);
    }
}

int main() {
    int m;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &s[i]);
    scanf("%d", &m);
    for (int i = 1; i <= m; i++) {
        scanf("%d%d", &u[i], &v[i]);
        G[u[i]].pb({v[i], i});
        G[v[i]].pb({u[i], i});
    }
    dfs(1);
    if (s[1]) return puts("Impossible"), 0;
    puts("Possible");
    for (int i = 1; i <= m; i++) printf("%d\n", res[i]);
    return 0;
}


#include <stdio.h>
#include <string.h>
const int N=2e5+2,M=6e5+2;
typedef long long ll;
ll s[N],ans[M],zr,zc;
int lj[M][2],nxt[M],fir[N],a[N];
int x,y,z,n,m,i,j,bs,c,fh;
bool ed[N];
inline void read(int &x)
{
	c=getchar();x=0;fh=1;
	while ((c<48)||(c>57))
	{
		if (c=='-') fh=-1;
		c=getchar();
	}
	while ((c>=48)&&(c<=57))
	{
		x=x*10+(c^48);c=getchar();
	}
	x*=fh;
}
inline void add(int x,int y,int z)
{
	lj[++bs][0]=y;
	lj[bs][1]=z;
	nxt[bs]=fir[x];
	fir[x]=bs;
	lj[++bs][0]=x;
	lj[bs][1]=z;
	nxt[bs]=fir[y];
	fir[y]=bs;
}
void dfs(int x)
{
	ed[x]=1;
	s[x]=-a[x];
	if (a[x]<0) zc-=a[x]; else zr+=a[x];
	int i;
	for (i=fir[x];i;i=nxt[i]) if (!ed[lj[i][0]])
	{
		dfs(lj[i][0]);
		if (lj[i][1]==lj[i+1][1]) ans[lj[i][1]]=-s[lj[i][0]]; else ans[lj[i][1]]=s[lj[i][0]];
		s[x]+=s[lj[i][0]];
	}
}
int main()
{
	//freopen("flow.in","r",stdin);
	//freopen("flow.out","w",stdout);
	read(n);
	for (i=1;i<=n;i++) read(a[i]);
	read(m);
	for (i=1;i<=m;i++)
	{
		read(x);read(y);
		add(x,y,i);
	}
	for (i=1;i<=n;i++) if (!ed[i])
	{
		zr=zc=0;
		dfs(i);
		if (zr!=zc)
		{
			printf("Impossible");
			return 0;
		}
	}
	printf("Possible\n");
	for (i=1;i<=m;i++) printf("%lld\n",ans[i]);
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN=2e5+5,MAXM=6e5+5;

int head[MAXM],nxt[MAXM],v[MAXM],cnt;

int tag[MAXN];

LL flow[MAXM],a[MAXN];

int n,m;

inline void Addline(int x,int y)
{
	v[cnt]=y;
	nxt[cnt]=head[x],head[x]=cnt++;

	return;
}

inline int DFS(int x)
{
	tag[x]=true;
	LL ans=0;

	for(int i=head[x];~i;i=nxt[i])
		if(!tag[v[i]])
		{
			LL temp=DFS(v[i]);
			flow[i^1]=temp;
			ans+=temp;
		}

	return ans+a[x];
}

inline bool Judge(void)
{
	LL sum=0;
	for(int i=1;i<=n;i++)
		sum+=a[i];

	return !sum;
}

signed main(void)
{
	memset(head,-1,sizeof head);

	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld",a+i);

	if(Judge())
		puts("Possible");
	else
	{
		puts("Impossible");
		return 0;
	}

	scanf("%d",&m);
	for(int i=1,x,y;i<=m;i++)
	{
		scanf("%d %d",&x,&y);

		Addline(x,y),Addline(y,x);
	}

	DFS(rand()%n+1);

	for(int i=1;i<=m;i++)
		printf("%lld\n",flow[(i-1)*2+1]-flow[(i-1)*2]);

	return 0;
}


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#define lol long long
#define LINF 1000000000000000000
#define INF 0x3f3f3f3f
void read(int & x)
{
	char c;
	bool f=false;
	for(c=getchar();c>'9'||c<'0';c=getchar()) if(c=='-') f=1;
	for(x=0;c<='9'&&c>='0';c=getchar()) x=(x<<3)+(x<<1)+c-48;
	if(f) x=-x;
}
using namespace std;

const int MAXN = 200010;

int f[MAXN];
int pval[MAXN];
bool poi[MAXN];
int ans[MAXN];
int n,m;
int head[MAXN],cnt;
struct EE
{
	int next,to,cur;
}edge[2*MAXN];
void addedge(int f,int t,int cur)
{
	edge[++cnt].next=head[f];
	edge[cnt].to=t;
	edge[cnt].cur=cur;
	head[f]=cnt;
}
int find(int x)
{
	if(f[x]==x) return x;
	else return f[x]=find(f[x]);
}
void dfs(int u,int fa)
{
	for(int i=head[u];i;i=edge[i].next)
	{
		int v=edge[i].to;
		if(v==fa) continue;
		dfs(v,u);
		pval[u]+=pval[v];
		if(i&1) ans[edge[i].cur]=pval[v];
		else ans[edge[i].cur]=-pval[v];
	}
}
signed main(void)
{
	int a,b;
	int sum=0;
	read(n);
	for(int i=1;i<=n;i++)
	{
		read(pval[i]);
		sum+=pval[i];
		f[i]=i;
	}
	if(sum)
	{
		printf("Impossible");
		return 0;
	}
	read(m);
	for(int i=1;i<=m;i++)
	{
		read(a),read(b);
		if(find(a)!=find(b))
		{
			addedge(a,b,i);
			addedge(b,a,i);
			f[find(a)]=b;
		}
	}
	dfs(1,0);
	printf("Possible\n");
	for(int i=1;i<=m;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include <bits/stdc++.h>

#define forn(i, n) for (int i = 0; i < int(n); i++)

using namespace std;

const int N = 1000013;

int n, m;
pair<int, int> e[N];
int a[N], rk[N];
long long sum[N], ans[N];

int p[N];

int getP(int a){
	return (a == p[a] ? a : p[a] = getP(p[a]));
}

bool merge(int a, int b){
	a = getP(a);
	b = getP(b);
	if (a == b) return false;
	if (rk[a] > rk[b]) swap(a, b);
	p[a] = b;
	rk[b] += rk[a];
	return true;
}

bool used[N];
vector<int> g[N];
int h[N];

void dfs(int v, int p){
	sum[v] = a[v];
	for (auto u : g[v]){
		if (u != p){
			h[u] = h[v] + 1;
			dfs(u, v);
			sum[v] += sum[u];
		}
	}
}

int main() {
	scanf("%d", &n);
	forn(i, n)
		scanf("%d", &a[i]);

	forn(i, n) p[i] = i, rk[i] = 1;
	scanf("%d", &m);
	forn(i, m){
		int &v = e[i].first;
		int &u = e[i].second;
		scanf("%d%d", &v, &u);
		--v, --u;
		if (merge(v, u)){
			g[v].push_back(u);
			g[u].push_back(v);
			used[i] = true;
		}
	}

	long long tot = 0;
	forn(i, n) tot += a[i];
	if (tot != 0){
		puts("Impossible");
		return 0;
	}

	dfs(0, -1);

	puts("Possible");
	forn(i, m){
		if (used[i]){
			int v = e[i].first, u = e[i].second;
			if (h[v] < h[u])
				ans[i] = sum[u];
			else
				ans[i] = -sum[v];
		}
		cout<<ans[i]<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>

#define forn(i, n) for (int i = 0; i < int(n); i++)

using namespace std;

mt19937 rnd(time(NULL));

const int N = 1'000'013;

int n, m;
pair<int, int> e[N];
int a[N], rk[N];
long long sum[N], ans[N];

int p[N];

int getP(int a){
	return (a == p[a] ? a : p[a] = getP(p[a]));
}

bool merge(int a, int b){
	a = getP(a);
	b = getP(b);
	if (a == b) return false;
	if (rk[a] > rk[b]) swap(a, b);
	p[a] = b;
	rk[b] += rk[a];
	return true;
}

bool used[N];
vector<int> g[N];
int h[N];

void dfs(int v, int p){
	sum[v] = a[v];
	for (auto u : g[v]){
		if (u != p){
			h[u] = h[v] + 1;
			dfs(u, v);
			sum[v] += sum[u];
		}
	}
}

int main() {
	scanf("%d", &n);
	forn(i, n)
		scanf("%d", &a[i]);

	forn(i, n) p[i] = i, rk[i] = 1;
	scanf("%d", &m);
	forn(i, m){
		int &v = e[i].first;
		int &u = e[i].second;
		scanf("%d%d", &v, &u);
		--v, --u;
		if (merge(v, u)){
			g[v].push_back(u);
			g[u].push_back(v);
			used[i] = true;
		}
	}

	long long tot = 0;
	forn(i, n) tot += a[i];
	if (tot != 0){
		puts("Impossible");
		return 0;
	}

	dfs(0, -1);

	puts("Possible");
	forn(i, m){
		if (used[i]){
			int v = e[i].first, u = e[i].second;
			if (h[v] < h[u])
				ans[i] = sum[u];
			else
				ans[i] = -sum[v];
		}
		cout<<ans[i]<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>

#define forn(i, n) for (int i = 0; i < int(n); i++)

using namespace std;

mt19937 rnd(time(NULL));

const int N = 1'000'013;

int n, m;
pair<int, int> e[N];
int a[N], rk[N];
long long sum[N], ans[N];

int p[N];

int getP(int a){
	return (a == p[a] ? a : p[a] = getP(p[a]));
}

bool merge(int a, int b){
	a = getP(a);
	b = getP(b);
	if (a == b) return false;
	if (rk[a] > rk[b]) swap(a, b);
	p[a] = b;
	rk[b] += rk[a];
	return true;
}

bool used[N];
vector<int> g[N];
int h[N];

void dfs(int v, int p){
	sum[v] = a[v];
	for (auto u : g[v]){
		if (u != p){
			h[u] = h[v] + 1;
			dfs(u, v);
			sum[v] += sum[u];
		}
	}
}

int main() {
	scanf("%d", &n);
	forn(i, n)
		scanf("%d", &a[i]);

	forn(i, n) p[i] = i, rk[i] = 1;
	scanf("%d", &m);
	forn(i, m){
		int &v = e[i].first;
		int &u = e[i].second;
		scanf("%d%d", &v, &u);
		--v, --u;
		if (merge(v, u)){
			g[v].push_back(u);
			g[u].push_back(v);
			used[i] = true;
		}
	}

	long long tot = 0;
	forn(i, n) tot += a[i];
	if (tot != 0){
		puts("Impossible");
		return 0;
	}

	dfs(0, -1);

	puts("Possible");
	forn(i, m){
		if (used[i]){
			int v = e[i].first, u = e[i].second;
			if (h[v] < h[u])
				ans[i] = sum[u];
			else
				ans[i] = -sum[v];
		}
		printf("%I64\n", ans[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

#define forn(i, n) for (int i = 0; i < int(n); i++)

using namespace std;

const int N = 1'000'013;

int n, m;
pair<int, int> e[N];
int a[N], rk[N];
long long sum[N], ans[N];

int p[N];

int getP(int a){
	return (a == p[a] ? a : p[a] = getP(p[a]));
}

bool merge(int a, int b){
	a = getP(a);
	b = getP(b);
	if (a == b) return false;
	if (rk[a] > rk[b]) swap(a, b);
	p[a] = b;
	rk[b] += rk[a];
	return true;
}

bool used[N];
vector<int> g[N];
int h[N];

void dfs(int v, int p){
	sum[v] = a[v];
	for (auto u : g[v]){
		if (u != p){
			h[u] = h[v] + 1;
			dfs(u, v);
			sum[v] += sum[u];
		}
	}
}

int main() {
	scanf("%d", &n);
	forn(i, n)
		scanf("%d", &a[i]);

	forn(i, n) p[i] = i, rk[i] = 1;
	scanf("%d", &m);
	forn(i, m){
		int &v = e[i].first;
		int &u = e[i].second;
		scanf("%d%d", &v, &u);
		--v, --u;
		if (merge(v, u)){
			g[v].push_back(u);
			g[u].push_back(v);
			used[i] = true;
		}
	}

	long long tot = 0;
	forn(i, n) tot += a[i];
	if (tot != 0){
		puts("Impossible");
		return 0;
	}

	dfs(0, -1);

	puts("Possible");
	forn(i, m){
		if (used[i]){
			int v = e[i].first, u = e[i].second;
			if (h[v] < h[u])
				ans[i] = sum[u];
			else
				ans[i] = -sum[v];
		}
		cout<<ans[i]<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#define F first
#define S second
#define $ ios::sync_with_stdio(0);
const int INF = 0x3f3f3f3f;
const int MAXN = 100005;
using namespace std;
using ii = pair<int, int>;
using ll = long long int;
using vi = vector<ii>;
using graph = vector<vi>;
graph g;
int v[MAXN], ans[MAXN], sz[MAXN];
bool seen[MAXN];
int dfs(int u) {
    //printf("%d\n", u);
    seen[u] = 1;
    sz[u] = v[u];
    for (auto w : g[u]) if (!seen[w.F]) {
        dfs(w.F);
        if (w.S < 0) ans[-w.S] = -sz[w.F];
        else ans[w.S] = sz[w.F];
        sz[u] += sz[w.F];
    }
}
int main() {
    int n, m, k;
    scanf("%d", &n);
    g.assign(n+1, vi());
    int res = 0;
    for (int i = 1; i<=n; ++i) {
        scanf("%d", v+i);
        res += v[i];
    }
    if (res) {
        puts("Impossible");
        return 0;
    }
    scanf("%d", &m);
    for (int i = 1, u, w; i<=m; ++i) {
        scanf("%d %d", &u, &w);
        g[u].emplace_back(w, i);
        g[w].emplace_back(u, -i);
    }

    puts("Possible");
    dfs(1);
    for (int i = 1; i<=m; ++i) {
        printf("%d\n", ans[i]);
    }

}