#include <iostream>
#include <set>
#include <map>

using namespace std;

int main () {
	ios_base::sync_with_stdio(false);

	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	bool died[1000001];
	for (int i = 0; i < 1000001; i++) {
		died[i] = false;
	}

	set< pair<int,int> > s;
	map<int, int> count;
	for (int i = 0; i < n; i++) {
		if (s.find(make_pair(0, a[i])) == s.end()) {
			s.insert(make_pair(0, a[i]));
			count[a[i]] = 0;
			died[a[i]] = false;
		}
	}

	for (int i = 0; i < n; i++) {
		if (!died[a[i]]) {
			s.erase(make_pair(count[a[i]], a[i]));
			s.insert(make_pair(count[a[i]]+1, a[i]));
			count[a[i]]++;
		}
		if (a[i] == A) {
			while (s.begin()->first < count[a[i]]) {
				died[s.begin()->second] = true;
				s.erase(s.begin());
			}
		}
	}

	bool b = false;
	for (auto it = s.begin(); it != s.end() && !b; ++it) {
		if (it->second != A) {
			cout << it->second << "\n";
			b = true;
		}
	}
	if (!b) {
		cout << "-1\n";
	}
}


#include <iostream>
#include <set>
#include <map>

using namespace std;

int main () {
	ios_base::sync_with_stdio(false);

	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	set< pair<int,int> > s;
	map<int, int> count;
	map<int, bool> died;
	for (int i = 0; i < n; i++) {
		if (s.find(make_pair(0, a[i])) == s.end()) {
			s.insert(make_pair(0, a[i]));
			count[a[i]] = 0;
			died[a[i]] = false;
		}
	}

	for (int i = 0; i < n; i++) {
		s.erase(make_pair(count[a[i]], a[i]));
		s.insert(make_pair(count[a[i]]+1, a[i]));
		count[a[i]]++;
		if (a[i] == A) {
			for (auto it = s.begin(); it->first < count[A]; ++it) {
				died[it->second] = true;
			}
		}
	}

	bool b = false;
	for (auto it = died.begin(); it != died.end() && !b; ++it) {
		if (it->first != A && !it->second) {
			cout << it->first << "\n";
			b = true;
		}
	}
	if (!b) {
		cout << "-1\n";
	}
}


#include <iostream>
#include <map>

using namespace std;

int main () {
	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	map<int,int> m;
	for (int i = 0; i < n; i++) {
		m[a[i]] = 0;
	}

	for (int i = 0; i < n; i++) {
		if (m.find(a[i]) != m.end()) m[a[i]]++;
		if (a[i] == A) {
			for (map<int,int>::iterator it = m.begin(); it != m.end(); ++it) {
				if (it->first != A && it->second < a[i]) {
					m.erase(it->first);
				} else {
				}
			}
		}
	}

	bool b = false;
	for (auto it = m.begin(); !b && it != m.end(); ++it) {
		if (it->first != A) {
			cout << it->first << endl;
			b = true;
		}
	}
	if (!b) {
		cout << -1 << endl;
	}
}


#include <iostream>
#include <set>
#include <map>

using namespace std;

int main () {
	ios_base::sync_with_stdio(false);

	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	bool died[1000001];
	for (int i = 0; i < 1000001; i++) {
		died[i] = false;
	}

	set< pair<int,int> > s;
	map<int, int> count;
	for (int i = 0; i < n; i++) {
		if (s.find(make_pair(0, a[i])) == s.end()) {
			s.insert(make_pair(0, a[i]));
			count[a[i]] = 0;
			died[a[i]] = false;
		}
	}

	for (int i = 0; i < n; i++) {
		if (!died[a[i]]) {
			s.erase(make_pair(count[a[i]], a[i]));
			s.insert(make_pair(count[a[i]]+1, a[i]));
			count[a[i]]++;
		}
		if (a[i] == A) {
			while (s.begin()->first < count[A]) {
				died[s.begin()->second] = true;
				s.erase(s.begin());
			}
		}
	}

	bool b = false;
	for (auto it = s.begin(); it != s.end() && !b; ++it) {
		if (it->second != A) {
			cout << it->first << "\n";
			b = true;
		}
	}
	if (!b) {
		cout << "-1\n";
	}
}


#include <iostream>
#include <map>

using namespace std;

int main () {
	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	map<int,int> m;
	for (int i = 0; i < n; i++) {
		m[a[i]] = 0;
	}

	for (int i = 0; i < n; i++) {
		if (m.find(a[i]) != m.end()) m[a[i]]++;
		if (a[i] == A) {
			for (auto it = m.begin(); it != m.end(); ++it) {
				if (it->first != A && it->second < m[A]) {
					m.erase(it->first);
					--it;
				} else {
				}
			}
		}
	}

	bool b = false;
	for (auto it = m.begin(); !b && it != m.end(); ++it) {
		if (it->first != A) {
			cout << it->first << endl;
			b = true;
		}
	}
	if (!b) {
		cout << -1 << endl;
	}
}


#include <iostream>
#include <set>
#include <map>

using namespace std;

int main () {
	ios_base::sync_with_stdio(false);

	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	set< pair<int,int> > s;
	map<int, int> count;
	map<int, bool> died;
	for (int i = 0; i < n; i++) {
		if (s.find(make_pair(0, a[i])) == s.end()) {
			s.insert(make_pair(0, a[i]));
			count[a[i]] = 0;
			died[a[i]] = false;
		}
	}

	for (int i = 0; i < n; i++) {
		if (!died[a[i]]) {
			s.erase(make_pair(count[a[i]], a[i]));
			s.insert(make_pair(count[a[i]]+1, a[i]));
			count[a[i]]++;
		}
		if (a[i] == A) {
			for (auto it = s.begin(); it->first < count[A]; ++it) {
				died[it->second] = true;
			}
		}
	}

	bool b = false;
	for (auto it = died.begin(); it != died.end() && !b; ++it) {
		if (it->first != A && !it->second) {
			cout << it->first << "\n";
			b = true;
		}
	}
	if (!b) {
		cout << "-1\n";
	}
}


#include <iostream>
#include <map>

using namespace std;

int main () {
	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	map<int,int> m;
	for (int i = 0; i < n; i++) {
		m[a[i]] = 0;
	}

	for (int i = 0; i < n; i++) {
		if (m.find(a[i]) != m.end()) m[a[i]]++;
		if (a[i] == A) {
			for (map<int,int>::iterator it = m.begin(); it != m.end(); ++it) {
				if (it->first != A && it->second < m[A]) {
					m[it->first] = -100000000;
				} else {
				}
			}
		}
	}

	bool b = false;
	for (auto it = m.begin(); !b && it != m.end(); ++it) {
		if (it->first != A && it->second >= m[A]) {
			cout << it->first << endl;
			b = true;
		}
	}
	if (!b) {
		cout << -1 << endl;
	}
}


#include <iostream>
#include <map>

using namespace std;

int main () {
	int n, A;
	cin >> n >> A;

	int a[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}

	map<int,int> m;
	for (int i = 0; i < n; i++) {
		m[a[i]] = 0;
	}

	for (int i = 0; i < n; i++) {
		if (m.find(a[i]) != m.end()) m[a[i]]++;
		if (a[i] == A) {
			for (auto it = m.begin(); it != m.end(); ++it) {
				if (it->first != A && it->second < m[A]) {
					m.erase(it->first);
				} else {
				}
			}
		}
	}

	bool b = false;
	for (auto it = m.begin(); !b && it != m.end(); ++it) {
		if (it->first != A) {
			cout << it->first << endl;
			b = true;
		}
	}
	if (!b) {
		cout << -1 << endl;
	}
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

int a[200010];
int sums[200010], roots[200010];
int ans[200010] = { 0 };

struct edge
{
    int where, index;
    bool direction;
};

std::vector< std::vector<edge> > g(200010);

void initialize(int n)
{
    for (int i = 0; i < n; ++i)
    {
        roots[i] = i;
        sums[i] = 1;
    }
}

int root(int index)
{
    while (index != roots[index])
    {
        roots[index] = roots[roots[index]];
        index = roots[index];
    }

    return index;
}

void makeUnion(int a, int b)
{
    int rootOfA = root(a), rootOfB = root(b);

    if (sums[rootOfA] >= sums[rootOfB])
    {
        sums[rootOfA] += sums[rootOfB];
        roots[rootOfB] = roots[rootOfA];
    }
    else
    {
        sums[rootOfB] += sums[rootOfA];
        roots[rootOfA] = roots[rootOfB];
    }
}

void dfs(int index, int parent)
{
    int sum = 0;
    for (int i = 0; i < g[index].size(); ++i)
    {
        edge next = g[index][i];

        if (next.where != parent)
        {
            dfs(next.where, index);

            if (next.direction == 0)
            {
                ans[next.index] = +a[next.where];
                a[index] += a[next.where];
                a[next.where] = 0;
            }
            else
            {
                ans[next.index] = -a[next.where];
                a[index] += a[next.where];
                a[next.where] = 0;
            }
        }
    }
}

int main()
{
    int n;
    std::cin >> n;

    int sum = 0;
    for (int i = 0; i < n; ++i)
    {
        std::cin >> a[i];
        sum += a[i];
    }

    if (sum != 0)
    {
        std::cout << "Impossible";
        return 0;
    }

    int m;
    std::cin >> m;

    initialize(n);
    int curSize[200010] = { 0 };
    for (int i = 0; i < m; ++i)
    {
        int x, y;
        std::cin >> x >> y;
        --x;
        --y;

        int rootOfA = root(x), rootOfB = root(y);
        if (rootOfA != rootOfB)
        {
            makeUnion(rootOfA, rootOfB);

            edge cur;
            cur.where = y;
            cur.index = i;
            cur.direction = 0;

            g[x].push_back(cur);
            cur.where = x;
            cur.direction = 1;
            g[y].push_back(cur);
            ++curSize[x];
            ++curSize[y];
        }
    }

    dfs(0, -1);
/*
    if (cnt != n)
    {
        std::cout << cnt << "|";
    }*/

    std::cout << "Possible\n";
    for (int i = 0; i < m; ++i)
    {
        std::cout << ans[i] << "\n";
    }
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

int a[200010];
int sums[200010], roots[200010];
int ans[200010] = { 0 };

struct edge
{
    int where, index;
    bool direction;
};

std::vector< std::vector<edge> > g(200010);

void initialize(int n)
{
    for (int i = 0; i < n; ++i)
    {
        roots[i] = i;
        sums[i] = 1;
    }
}

int root(int index)
{
    while (index != roots[index])
    {
        roots[index] = roots[roots[index]];
        index = roots[index];
    }

    return index;
}

void makeUnion(int a, int b)
{
    int rootOfA = root(a), rootOfB = root(b);

    if (sums[rootOfA] >= sums[rootOfB])
    {
        sums[rootOfA] += sums[rootOfB];
        roots[rootOfB] = roots[rootOfA];
    }
    else
    {
        sums[rootOfB] += sums[rootOfA];
        roots[rootOfA] = roots[rootOfB];
    }
}

int main()
{
    int n;
    std::cin >> n;

    int sum = 0;
    for (int i = 0; i < n; ++i)
    {
        std::cin >> a[i];
        sum += a[i];
    }

    if (sum != 0)
    {
        std::cout << "Impossible";
        return 0;
    }

    int m;
    std::cin >> m;

    initialize(n);
    int curSize[200010] = { 0 };
    for (int i = 0; i < m; ++i)
    {
        int x, y;
        std::cin >> x >> y;
        --x;
        --y;

        int rootOfA = root(x), rootOfB = root(y);
        if (rootOfA != rootOfB)
        {
            makeUnion(rootOfA, rootOfB);

            edge cur;
            cur.where = y;
            cur.index = i;
            cur.direction = 0;

            g[x].push_back(cur);
            cur.where = x;
            cur.direction = 1;
            g[y].push_back(cur);
            ++curSize[x];
            ++curSize[y];
        }
    }

    std::queue<int> cur;
    bool visited[200010] = { 0 };
    for (int i = 0; i < n; ++i)
    {
        if (g[i].size() == 1)
        {
            cur.push(i);
            visited[i] = true;
        }
    }

    int cnt = 0;
    while (cur.empty() == false)
    {
        int top = cur.front();
        visited[top] = true;
        cur.pop();

        for (int j = 0; j < g[top].size(); ++j)
        {
            edge next = g[top][j];

            if (!visited[next.where])
            {
                --curSize[next.where];
                if (curSize[next.where] == 0)
                {
                    cur.push(next.where);
                    visited[next.where] = true;
                }

                if (next.direction == 0)
                {
                    ans[next.index] = -a[top];
                    a[next.where] += a[top];
                    a[top] = 0;
                }
                else
                {
                    ans[next.index] = a[top];
                    a[next.where] -= a[top];
                    a[top] = 0;
                }
            }
        }
        ++cnt;
    }

    if (cnt != n)
    {
        std::cout << cnt << "|";
    }

    std::cout << "Possible\n";
    for (int i = 0; i < m; ++i)
    {
        std::cout << ans[i] << "\n";
    }
}


#include <bits/stdc++.h>

using namespace std;

int N, M;
vector<int> graph[200005];
int val[200005];
bool vis[200005];
pair<int, int> edge[200005];
int ans[200005];

void dfs(int n, int p){
    vis[n] = 1;
    for(int e : graph[n]){
        if(e == p){
            continue;
        }
        if(edge[e].first == n){
            int k = edge[e].second;
            if(vis[k]){
                continue;
            }
            dfs(k, e);
            ans[e] = (val[k]);
            val[k] = 0;
            val[n] += ans[e];
        }
        else{
            int k = edge[e].first;
            if(vis[k]){
                continue;
            }
            dfs(k, e);
            ans[e] = -(val[k]);
            val[k] = 0;
            val[n] -= ans[e];
        }
    }
//    cout << " " << n << " " << val[n] << " " << p << endl;
}

int main(){
    cin.sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for(int i =1; i<=N; i++){
        cin >> val[i];
    }
    cin >> M;
    for(int i = 1; i<=M; i++){
        int a, b;
        cin >> a >> b;
        graph[a].push_back(i);
        graph[b].push_back(i);
        edge[i] = {a, b};
    }
    bool pos = 1;
    for(int n = 1; n<=N; n++){
        if(!vis[n]){
            dfs(n, 0);
            if(val[n]){
                pos = 0;
            }
        }
    }
    if(pos){
        cout << "Possible" << "\n";
        for(int i = 1; i<=M; i++){
            cout << ans[i] << "\n";
        }
    }
    else{
        cout << "Impossible" << "\n";
    }
}


#include <bits/stdc++.h>

using namespace std;

int N, M;
vector<int> graph[200005];
int val[200005];
bool vis[200005];
pair<int, int> edge[200005];
int ans[200005];

void dfs(int n, int p){
    vis[n] = 1;
    for(int e : graph[n]){
        if(e == p){
            continue;
        }
        if(edge[e].first == n){
            int k = edge[e].second;
            if(vis[k]){
                continue;
            }
            dfs(k, e);
            ans[e] = -(val[k]);
            val[k] = 0;
            val[n] -= ans[e];
        }
        else{
            int k = edge[e].first;
            if(vis[k]){
                continue;
            }
            dfs(k, e);
            ans[e] = (val[k]);
            val[k] = 0;
            val[n] += ans[e];
        }
    }
}

int main(){
    cin.sync_with_stdio(0);
    cin.tie(0);
    cin >> N;
    for(int i =1; i<=N; i++){
        cin >> val[i];
    }
    cin >> M;
    for(int i = 1; i<=M; i++){
        int a, b;
        cin >> a >> b;
        graph[a].push_back(i);
        graph[b].push_back(i);
        edge[i] = {a, b};
    }
    bool pos = 1;
    for(int n = 1; n<=N; n++){
        if(!vis[n]){
            dfs(n, 0);
            if(val[n]){
                pos = 0;
            }
        }
    }
    if(pos){
        cout << "Possible" << "\n";
        for(int i = 1; i<=M; i++){
            cout << ans[i] << "\n";
        }
    }
    else{
        cout << "Impossible" << "\n";
    }
}


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

typedef pair <int, int> P;

const int N = 2e5 + 10;

vector <P> G[N];
int val[N], used[N], ans[N];

void dfs(int x, int fa, int id){
	used[x] = 1;
	for (int i = 0; i < G[x].size(); i++){
		if (!used[G[x][i].first])
			dfs(G[x][i].first, x, G[x][i].second);
	}
	if (val[x] != 0){
		if (id < 0) ans[-id] -= val[x];
		else ans[id] += val[x];
		val[fa] += val[x];
		val[x] = 0;
	}
}

int main(){
	int n, m, u, v, sum;
	scanf("%d",&n);
	for (int i = 1; i <= n; i++) scanf("%d",&val[i]);
	scanf("%d",&m);
	for (int i = 1; i <= m; i++){
		scanf("%d %d",&u,&v);
		G[u].emplace_back(v, i);
		G[v].emplace_back(u, -i);
	}
	sum = 0;
	for (int i = 1; i <= n; i++) sum += val[i];
	if (sum != 0){
		printf("Impossible\n");
		return 0;
	}
	memset(used, 0, sizeof(used));
	dfs(1, 0, 0);
	printf("Possible\n");
	for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#define Rep(i,a,b) for(register int i=(a),i##end=(b);i<=i##end;++i)
#define Repe(i,a,b) for(register int i=(a),i##end=(b);i>=i##end;--i)
#define For(i,a,b) for(i=(a),i<=(b);++i)
#define Forward(i,a,b) for(i=(a),i>=(b);--i)
template<typename T>inline void read(T &x)
{
	T f=1;x=0;char c;
	for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
	for(;isdigit(c);c=getchar())x=x*10+(c^48);
	x*=f;
}
using namespace std;
#define Chkmax(a,b) a=a>b?a:b
#define Chkmin(a,b) a=a<b?a:b
const int MAXN=2e5+7;
inline void file()
{
	#ifndef ONLINE_LUDGE
		freopen("b.in","r",stdin);
		freopen("b.out","w",stdout);
	#endif
}
static int n,m,s[MAXN];

static long long ans[MAXN];

static int e,head[MAXN];

static struct edge
{
	int v,nxt,id,w;
}p[MAXN<<1];

inline void add(int u,int v,int id,int w)
{p[++e]=(edge){v,head[u],id,w};head[u]=e;}

inline void init()
{
	read(n);
	Rep(i,1,n)read(s[i]);
	read(m);
	static int u,v;
	Rep(i,1,m)read(u),read(v),add(u,v,i,1),add(v,u,i,-1);
}
static int vis[MAXN],fr[MAXN],fa[MAXN];

static int que[MAXN],tp;

static queue<int>G;

inline void seaq(int ss)
{
	static int u;
	static long long sm;sm=0;
	G.push(ss);que[tp=1]=ss;vis[ss]=true;
	while(!G.empty())
	{
		u=G.front();G.pop();sm+=s[u];
		for(register int v=head[u];v;v=p[v].nxt)if(!vis[p[v].v])
			fa[p[v].v]=u,fr[p[v].v]=v,G.push(p[v].v),que[++tp]=p[v].v,vis[p[v].v]=true;
	}
	if(sm!=0)puts("Impossible"),exit(0);
	Repe(i,tp,2)
	{
		u=que[i];
		s[fa[u]]+=s[u];
		ans[p[fr[u]].id]+=(long long)s[u]*-p[fr[u]].w;
	}
}
inline void solve()
{
	Rep(i,1,n)if(!vis[i])seaq(i);
	puts("Possible");
	Rep(i,1,m)printf("%I64d\n",-ans[i]);
}
int main()
{
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#define Rep(i,a,b) for(register int i=(a),i##end=(b);i<=i##end;++i)
#define Repe(i,a,b) for(register int i=(a),i##end=(b);i>=i##end;--i)
#define For(i,a,b) for(i=(a),i<=(b);++i)
#define Forward(i,a,b) for(i=(a),i>=(b);--i)
template<typename T>inline void read(T &x)
{
	T f=1;x=0;char c;
	for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
	for(;isdigit(c);c=getchar())x=x*10+(c^48);
	x*=f;
}
using namespace std;
#define Chkmax(a,b) a=a>b?a:b
#define Chkmin(a,b) a=a<b?a:b
const int MAXN=2e5+7;
inline void file()
{
	#ifndef ONLINE_LUDGE
		freopen("b.in","r",stdin);
		freopen("b.out","w",stdout);
	#endif
}
static int n,m,s[MAXN];

static long long ans[MAXN];

static int e,head[MAXN];

static struct edge
{
	int v,nxt,id,w;
}p[MAXN<<1];

inline void add(int u,int v,int id,int w)
{p[++e]=(edge){v,head[u],id,w};head[u]=e;}

inline void init()
{
	read(n);
	Rep(i,1,n)read(s[i]);
	read(m);
	static int u,v;
	Rep(i,1,m)read(u),read(v),add(u,v,i,1),add(v,u,i,-1);
}
static int vis[MAXN],fr[MAXN],fa[MAXN];

static int que[MAXN],tp;

static queue<int>G;

inline void seaq(int ss)
{
	static int u;
	static long long sm;sm=0;
	G.push(ss);que[tp=1]=ss;vis[ss]=true;
	while(!G.empty())
	{
		u=G.front();G.pop();sm+=s[u];
		for(register int v=head[u];v;v=p[v].nxt)if(!vis[p[v].v])
			fa[p[v].v]=u,fr[p[v].v]=v,G.push(p[v].v),que[++tp]=p[v].v,vis[p[v].v]=true;
	}
	if(sm!=0)puts("Impossible"),exit(0);
	Repe(i,tp,2)
	{
		u=que[i];
		s[fa[u]]+=s[u];
		ans[p[fr[u]].id]+=(long long)s[u]*-p[fr[u]].w;
	}
}
inline void solve()
{
	Rep(i,1,n)if(!vis[i])seaq(i);
	puts("Possible");
	Rep(i,1,m)printf("%I64d\n",ans[i]);
}
int main()
{
	init();
	solve();
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
int i,j,k,l,s,n,m,x,y,a[N],ans[N],last[N],to[2*N],Next[2*N],vis[N],tot;
inline void add(int x,int y) {
	Next[++tot]=last[x]; last[x]=tot; to[tot]=y;
}
inline void dfs(int x) {
	vis[x]=1;
	for (int i=last[x];i;i=Next[i]) {
		if (!vis[to[i]]) {
			dfs(to[i]);
			int pp=a[to[i]];
			a[to[i]]-=pp;
			if (i&1) {
				ans[(i+1)/2]=pp;
				a[x]+=pp;
			}
			else {
				ans[(i+1)/2]=-pp;
				a[x]+=pp;
			}
		}
	}
}
int main() {
	scanf("%d",&n);
	for (i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d",&m);
	for (i=1;i<=m;i++) {
		scanf("%d%d",&x,&y);
		add(x,y),add(y,x);
	}
	dfs(1);
	for (i=1;i<=n;i++) if (a[i]) return puts("Impossible"),0;
	puts("Possible");
	for (i=1;i<=m;i++) printf("%d\n",ans[i]);
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
int i,j,k,l,s,n,m,x,y,a[N],ans[N];
int main() {
	scanf("%d",&n);
	for (i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d",&m);
	for (i=1;i<=m;i++) {
		scanf("%d%d",&x,&y);
		int p=min(abs(a[x]),abs(a[y]));
		if (!p) continue;
		if (a[x]>0&&a[y]>0||a[x]<0&&a[y]<0) continue;
		if (a[x]>0) ans[i]=-p,a[x]-=p,a[y]+=p;
		else ans[i]=p,a[x]+=p,a[y]-=p;
	}
	for (i=1;i<=n;i++) if (a[i]) return puts("Impossible"),0;
	puts("Possible");
	for (i=1;i<=m;i++) printf("%d\n",ans[i]);
}


#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <array>
#include <string>
#include <stack>
#include <bitset>
#include <cmath>
#include <set>
#include <memory>
#include <iomanip>

using namespace std;

int dfs(const vector<vector<array<int, 3>>>& edges, vector<int>& ans, vector<int>& s, vector<char>& used, int v)
{
    used[v] = true;

    int sum = 0;
    for(auto& w : edges[v])
    {
        if(!used[w[0]])
        {
            int d = dfs(edges, ans, s, used, w[0]);
            ans[w[1]] = -d * w[2];

            sum += d;
        }
    }

    return sum - s[v];
}

int main()
{
    std::ios::sync_with_stdio(false);

    int n, m;

    cin >> n;

    vector<int> s(n);
    for(int i = 0; i < n; ++i)
    {
        cin >> s[i];
    }

    cin >> m;

    vector<vector<array<int, 3>>> edges(m);
    vector<int> ans(m);
    for(int i = 0; i < m; ++i)
    {
        int x, y;
        cin >> x >> y;
        --x; --y;

        edges[x].push_back({y, i, 1});
        edges[y].push_back({x, i, -1});
    }

    vector<char> used(n);

    if(dfs(edges, ans, s, used, 0) == 0)
    {
        cout << "Possible\n";
        for(int i : ans)
        {
            cout << i << endl;
        }
    }
    else
    {
        cout << "Impossible";
    }

    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <array>
#include <string>
#include <stack>
#include <bitset>
#include <cmath>
#include <set>
#include <memory>
#include <iomanip>

using namespace std;

int dfs(const vector<vector<array<int, 3>>>& edges, vector<int>& ans, vector<int>& s, vector<char>& used, int v)
{
    used[v] = true;

    int sum = 0;
    for(auto& w : edges[v])
    {
        if(!used[w[0]])
        {
            int d = dfs(edges, ans, s, used, w[0]);
            ans[w[1]] = -d * w[2];

            sum += d;
        }
    }

    return sum - s[v];
}

int main()
{
    std::ios::sync_with_stdio(false);

    int n, m;

    cin >> n;

    vector<int> s(n);
    for(int i = 0; i < n; ++i)
    {
        cin >> s[i];
    }

    cin >> m;

    if(n == 1)
    {
        cout << (s[0] == 0 ? "Possible" : "Impossible");

        return 0;
    }

    vector<vector<array<int, 3>>> edges(m);
    vector<int> ans(m);
    for(int i = 0; i < m; ++i)
    {
        int x, y;
        cin >> x >> y;
        --x; --y;

        edges[x].push_back({y, i, 1});
        edges[y].push_back({x, i, -1});
    }

    vector<char> used(n);

    if(dfs(edges, ans, s, used, 0) == 0)
    {
        cout << "Possible\n";
        for(int i : ans)
        {
            cout << i << endl;
        }
    }
    else
    {
        cout << "Impossible";
    }

    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <array>
#include <string>
#include <stack>
#include <bitset>
#include <cmath>
#include <set>
#include <memory>
#include <iomanip>

using namespace std;

int dfs(const vector<vector<array<int, 3>>>& edges, vector<int>& ans, vector<int>& s, vector<char>& used, int v)
{
    used[v] = true;

    int sum = 0;
    for(auto& w : edges[v])
    {
        if(!used[w[0]])
        {
            int d = dfs(edges, ans, s, used, w[0]);
            ans[w[1]] = -d * w[2];

            sum += d;
        }
    }

    return sum - s[v];
}

int main()
{
    std::ios::sync_with_stdio(false);

    int n, m;

    cin >> n;

    vector<int> s(n);
    for(int i = 0; i < n; ++i)
    {
        cin >> s[i];
    }

    cin >> m;

    if(n == 1)
    {
        cout << (s[0] == 0 ? "Possible" : "Impossible");

        return 0;
    }

    vector<vector<array<int, 3>>> edges(n);
    vector<int> ans(m);
    for(int i = 0; i < m; ++i)
    {
        int x, y;
        cin >> x >> y;
        --x; --y;

        edges[x].push_back({y, i, 1});
        edges[y].push_back({x, i, -1});
    }

    vector<char> used(n);

    if(dfs(edges, ans, s, used, 0) == 0)
    {
        cout << "Possible\n";
        for(int i : ans)
        {
            cout << i << endl;
        }
    }
    else
    {
        cout << "Impossible";
    }

    return 0;
}


/*
Trading life for life
It all must fall
It must end with us
It must end with me

Insinuations of what might be
Fight through depriviation
There will be no sleep

Heed my cry

Because of greed and hatred
To dust we return
They will see the strength in our numbers
Only then will the self-righteous learn

Insinuations of what might be

To the masses, we mean nothing
But it starts in the hearts of the few
Witness the birth of a people
Unite. Renew.

There is no forever, just today
Don't let your sacrifice waste away

Through change and purity, turn the shadows to light
Buried beneath the ashes is a passion for life

There is no forever, just today
Don't let your sacrifice waste away

Let there be no more of this bloodshed

Heed my cry.

There is no forever, just today
Don't let your sacrifice waste away
*/

#pragma GCC optimize("O3")
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <string>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>

#include <memory.h>
#include <assert.h>

#define y0 sdkfaslhagaklsldk

#define y1 aasdfasdfasdf
#define yn askfhwqriuperikldjk
#define j1 assdgsdgasghsf
#define tm sdfjahlfasfh
#define lr asgasgash
#define norm asdfasdgasdgsd
#define have adsgagshdshfhds
#define ends asdgahhfdsfshdshfd
#define prev asdgSHJsfgsdfhdsh

#define eps 1e-8
#define M_PI 3.141592653589793
#define bsize 512

#define ldouble long double
using namespace std;

#define bs 1000000007

const int N = 1200031;

int ts;
long long S[N];
int m,x[N],y[N];

const int MAXN = 400031;

map<pair<int,int>,int > maps;
long long res;

struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge (int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back ((int) e.size());
	e.push_back (e1);
	g[b].push_back ((int) e.size());
	e.push_back (e2);
}

bool bfs() {
	int qh=0, qt=0;
	q[qt++] = s;
	memset (d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i=0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs (int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs (to, min (flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id^1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}

int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset (ptr, 0, n * sizeof ptr[0]);
		while (true){
			int pushed=dfs(s,1000000000);
			if (pushed==0)
				break;
			flow += pushed;
		}
	}
	return flow;
}

int ans[N];

int bal[N];
int used[N];
int in_tree[N];

void dfs(int v){
	bal[v]=S[v];
	used[v]=1;
	for (int i=0;i<g[v].size();i++){
		int id=g[v][i];
		int to=x[id]+y[id]-v;
		if (used[to])
			continue;
		if (to==y[id])
			in_tree[id]=1;
		else
			in_tree[id]=-1;
		dfs(to);
		bal[v]+=bal[to];
	}
}

int main(){
//	freopen("apache.in","r",stdin);
//	freopen("apache.out","w",stdout);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0);
//	cin.tie(0);

	cin>>n;
	for (int i=1;i<=n;i++){
		cin>>S[i];
		ts+=S[i];
	}

	if (ts!=0){
		cout<<"Impossible"<<endl;
		return 0;
	}

	cout<<"Possible"<<endl;

	cin>>m;

	for (int i=1;i<=m;i++){
		cin>>x[i]>>y[i];
		g[x[i]].push_back(i);
		g[y[i]].push_back(i);
	}

	dfs(1);

	for (int i=1;i<=m;i++){
		if (in_tree[i]==0){
			cout<<0<<endl;
			continue;
		}
		if (in_tree[i]==1)
			cout<<bal[y[i]]<<endl;
		else
			cout<<-bal[x[i]]<<endl;
	}

//	cin.get(); cin.get();
	return 0;
}


/*
Trading life for life
It all must fall
It must end with us
It must end with me

Insinuations of what might be
Fight through depriviation
There will be no sleep

Heed my cry

Because of greed and hatred
To dust we return
They will see the strength in our numbers
Only then will the self-righteous learn

Insinuations of what might be

To the masses, we mean nothing
But it starts in the hearts of the few
Witness the birth of a people
Unite. Renew.

There is no forever, just today
Don't let your sacrifice waste away

Through change and purity, turn the shadows to light
Buried beneath the ashes is a passion for life

There is no forever, just today
Don't let your sacrifice waste away

Let there be no more of this bloodshed

Heed my cry.

There is no forever, just today
Don't let your sacrifice waste away
*/

#pragma GCC optimize("O3")
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <string>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>

#include <memory.h>
#include <assert.h>

#define y0 sdkfaslhagaklsldk

#define y1 aasdfasdfasdf
#define yn askfhwqriuperikldjk
#define j1 assdgsdgasghsf
#define tm sdfjahlfasfh
#define lr asgasgash
#define norm asdfasdgasdgsd
#define have adsgagshdshfhds
#define ends asdgahhfdsfshdshfd
#define prev asdgSHJsfgsdfhdsh

#define eps 1e-8
#define M_PI 3.141592653589793
#define bsize 512

#define ldouble long double
using namespace std;

#define bs 1000000007

const int N = 1200031;

int ts;
long long S[N];
int m,x[N],y[N];

const int MAXN = 400031;

map<pair<int,int>,int > maps;
long long res;

struct edge {
	int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge (int a, int b, int cap) {
	edge e1 = { a, b, cap, 0 };
	edge e2 = { b, a, 0, 0 };
	g[a].push_back ((int) e.size());
	e.push_back (e1);
	g[b].push_back ((int) e.size());
	e.push_back (e2);
}

bool bfs() {
	int qh=0, qt=0;
	q[qt++] = s;
	memset (d, -1, n * sizeof d[0]);
	d[s] = 0;
	while (qh < qt && d[t] == -1) {
		int v = q[qh++];
		for (size_t i=0; i<g[v].size(); ++i) {
			int id = g[v][i],
				to = e[id].b;
			if (d[to] == -1 && e[id].flow < e[id].cap) {
				q[qt++] = to;
				d[to] = d[v] + 1;
			}
		}
	}
	return d[t] != -1;
}

int dfs (int v, int flow) {
	if (!flow)  return 0;
	if (v == t)  return flow;
	for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
		int id = g[v][ptr[v]],
			to = e[id].b;
		if (d[to] != d[v] + 1)  continue;
		int pushed = dfs (to, min (flow, e[id].cap - e[id].flow));
		if (pushed) {
			e[id].flow += pushed;
			e[id^1].flow -= pushed;
			return pushed;
		}
	}
	return 0;
}

int dinic() {
	int flow = 0;
	for (;;) {
		if (!bfs())  break;
		memset (ptr, 0, n * sizeof ptr[0]);
		while (true){
			int pushed=dfs(s,1000000000);
			if (pushed==0)
				break;
			flow += pushed;
		}
	}
	return flow;
}

int ans[N];

int main(){
//	freopen("apache.in","r",stdin);
//	freopen("apache.out","w",stdout);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0);
//	cin.tie(0);

	cin>>n;
	for (int i=1;i<=n;i++){
		cin>>S[i];
		ts+=S[i];
	}

	if (ts!=0){
		cout<<"Impossible"<<endl;
		return 0;
	}

	cout<<"Possible"<<endl;

	cin>>m;

	for (int i=1;i<=m;i++){
		cin>>x[i]>>y[i];
		add_edge(x[i],y[i],1000000000);
		add_edge(y[i],x[i],1000000000);
		maps[make_pair(x[i],y[i])]=maps[make_pair(y[i],x[i])]=i;
	}

	for (int i=1;i<=n;i++){
		if (S[i]<0)
			add_edge(0,i,-S[i]);
		else
			add_edge(i,n+1,S[i]);
	}
	s=0;
	t=n+1;
	n=t+1;
	res=dinic();

	//cout<<res<<endl;

	for (int i=0;i<e.size();i++){
		if (e[i].flow>0){
			int a=e[i].a;
			int b=e[i].b;
			if(a==0||a==n-1||b==0||b==n-1){
				continue;
			}
			int id=maps[make_pair(a,b)];
			//cout<<id<<" "<<maps[make_pair(a,b)]<<" "<<e[i].flow<<endl;
			if (x[id]==a)
				ans[id]+=e[i].flow;
			else
				ans[id]-=e[i].flow;
		}
	}

	for (int i=1;i<=m;i++){
		cout<<ans[i]<<endl;
	}

//	cin.get(); cin.get();
	return 0;
}


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

const int N = 2e5 + 10;
struct E {int v, nt;} e[N<<1];
int n, m, tot=1, h[N], s[N], sum[N], vis[N], val[N<<1];

inline void add(int u, int v) {
	e[++tot] = (E){v, h[u]}, h[u] = tot;
	e[++tot] = (E){u, h[v]}, h[v] = tot;
}

template <class T> inline void in(T &x) {
	x = 0; int f = 1; char ch = getchar();
	for (; ch<'0' || ch>'9';) {if (ch=='-') f=-1; ch = getchar();}
	for (; ch>='0' && ch<='9';) x = x*10 + ch-'0', ch = getchar();
	x *= f;
}

inline void dfs(int x) {
	sum[x] = s[x], vis[x] = 1;
	for (int v, i = h[x]; i; i = e[i].nt)
		if (!vis[v = e[i].v]) dfs(v), sum[x] += sum[v], val[i] = sum[v];
}

int main() {
	int u, v, ret = 0; in(n);
	for (int i = 1; i <= n; ++i) in(s[i]), ret += s[i];
	if (ret) {puts("Impossible"); return 0;}
	in(m);
	for (int i = 1; i <= m; ++i) in(u), in(v), add(u, v);
	dfs(1);
	if (sum[1]) {puts("Impossible"); return 0;}
	puts("Possible");
	for(int i = 2; i <= tot; i += 2)
		printf("%d\n", val[i^1] ? -val[i^1] : val[i]);
	return 0;
}


#include <cstdio>
using namespace std;

const int N = 2e5 + 10;
struct E {int v, w, id, nt;} e[N<<1];
int n, m, tot, h[N], s[N], f[N], vis[N], use[N<<1];

inline void add(int u, int v, int id) {
	e[++tot] = (E){v, 1, id, h[u]}, h[u] = tot;
	e[++tot] = (E){u, 0, id, h[v]}, h[v] = tot;
}
template <class T> inline void in(T &x) {
	x = 0; int f = 1; char ch = getchar();
	for (; ch<'0' || ch>'9';) {if (ch=='-') f=-1; ch = getchar();}
	for (; ch>='0' && ch<='9';) x = x*10 + ch-'0', ch = getchar();
	x *= f;
}

inline void dfs(int x) {
	vis[x] = 1;
	for (int v, i = h[x]; i; i = e[i].nt) {
		if (vis[v = e[i].v] || use[e[i].id]) continue;
		use[e[i].id] = 1;
		if (e[i].w) f[e[i].id] = -s[x], s[v] += s[x];
		else f[e[i].id] = s[x], s[v] += s[x];
		dfs(v);
		return;
	}
}

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


#include <cstdio>
using namespace std;

const int N = 2e5 + 10;
struct E {int v, w, id, nt;} e[N<<1];
int n, m, tot, h[N], s[N], f[N], vis[N], use[N<<1];

inline void add(int u, int v, int id) {
	e[++tot] = (E){v, 1, id, h[u]}, h[u] = tot;
	e[++tot] = (E){u, 0, id, h[v]}, h[v] = tot;
}
template <class T> inline void in(T &x) {
	x = 0; int f = 1; char ch = getchar();
	for (; ch<'0' || ch>'9';) {if (ch=='-') f=-1; ch = getchar();}
	for (; ch>='0' && ch<='9';) x = x*10 + ch-'0', ch = getchar();
	x *= f;
}

inline void dfs(int x) {
	vis[x] = 1;
	for (int v, i = h[x]; i; i = e[i].nt)
		if (s[v = e[i].v] != 0 && !vis[v]) dfs(v);
	for (int v, i = h[x]; i; i = e[i].nt) {
		if (use[e[i].id]) continue;
		use[e[i].id] = 1, v = e[i].v;
		if (s[x] != 0) {
			if (e[i].w) f[e[i].id] = -s[x], s[v] += s[x];
			else f[e[i].id] = s[x], s[v] += s[x];
			s[x] = 0;
		}
	}
}

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


#include <cstdio>
using namespace std;

const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
struct E {int v, w, id, nt;} e[N<<1];
int n, m, T, tot = 1, h[N], q[N], s[N], ans[N], cur[N], dis[N];

inline void add(int u, int v, int w1, int w2, int id) {
	e[++tot] = (E){v, w1, id, h[u]}, h[u] = tot;
	e[++tot] = (E){u, w2, 0, h[v]}, h[v] = tot;
}

template <class T> inline T max(T a, T b) {return a > b ? a : b;}
template <class T> inline T min(T a, T b) {return a < b ? a : b;}
template <class T> inline void in(T &x) {
	x = 0; int f = 1; char ch = getchar();
	for (; ch<'0' || ch>'9';) {if (ch=='-') f=-1; ch = getchar();}
	for (; ch>='0' && ch<='9';) x = x*10 + ch-'0', ch = getchar();
	x *= f;
}

inline int bfs() {
	int i, u, v, l = 0, r = 0;
	for (i = 0; i <= T; ++i) dis[i] = -1;
	for (dis[q[++r] = 0] = 0; l < r;)
		for (i = h[u = q[++l]]; i; i = e[i].nt)
			if (e[i].w && dis[v = e[i].v] < 0)
				dis[v] = dis[u] + 1, q[++r] = v;
	return dis[T] != -1;
}

inline int dfs(int x, int f) {
	if (x == T || !f) return f;
	int v, w, used = 0;
	for (int &i = cur[x]; i; i = e[i].nt)
		if (e[i].w && dis[v = e[i].v] == dis[x] + 1) {
			w = dfs(v, min(e[i].w, f - used));
			e[i].w -= w, e[i^1].w += w, used += w;
			if (used == f) return used;
		}
	if (!used) dis[x] = -1;
	return used;
}

inline int Dinic() {
	int flow = 0;
	for (; bfs();) {
		for (int i = 0; i <= T; ++i) cur[i] = h[i];
		flow += dfs(0, inf);
	}
	return flow;
}

int main() {
	int u, v, ret = 0, sum = 0; in(n), T = n + 1;
	for (int i = 1; i <= n; ++i) {
		in(s[i]), sum += s[i];
		if (s[i] > 0) add(0, i, s[i], 0, 0), ret += s[i];
		else if (s[i] < 0) add(i, T, -s[i], 0, 0);
	}
	if (sum != 0) {puts("Impossible"); return 0;}
	in(m);
	for (int i = 1; i <= m; ++i) in(u), in(v), add(u, v, inf, inf, i);
	int flow = Dinic();
	if (flow != ret) {puts("Impossible"); return 0;}
	puts("Possible");
	for (int i = 2; i <= tot; ++i)
		if (e[i].id) ans[e[i].id] = inf - e[i^1].w;
	for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
	return 0;
}


#include <cstdio>
using namespace std;

const int N = 1e6 + 10;
const int inf = 0x3f3f3f3f;
struct E {int v, w, id, nt;} e[N<<1];
int n, m, T, tot = 1, h[N], q[N], s[N], ans[N], cur[N], dis[N];

inline void add(int u, int v, int w1, int w2, int id) {
	e[++tot] = (E){v, w1, id, h[u]}, h[u] = tot;
	e[++tot] = (E){u, w2, 0, h[v]}, h[v] = tot;
}

template <class T> inline T max(T a, T b) {return a > b ? a : b;}
template <class T> inline T min(T a, T b) {return a < b ? a : b;}
template <class T> inline void in(T &x) {
	x = 0; int f = 1; char ch = getchar();
	for (; ch<'0' || ch>'9';) {if (ch=='-') f=-1; ch = getchar();}
	for (; ch>='0' && ch<='9';) x = x*10 + ch-'0', ch = getchar();
	x *= f;
}

inline int bfs() {
	int i, u, v, l = 0, r = 0;
	for (i = 0; i <= T; ++i) dis[i] = -1;
	for (dis[q[++r] = 0] = 0; l < r;)
		for (i = h[u = q[++l]]; i; i = e[i].nt)
			if (e[i].w && dis[v = e[i].v] < 0)
				dis[v] = dis[u] + 1, q[++r] = v;
	return dis[T] != -1;
}

inline int dfs(int x, int f) {
	if (x == T || !f) return f;
	int v, w, used = 0;
	for (int &i = cur[x]; i; i = e[i].nt)
		if (e[i].w && dis[v = e[i].v] == dis[x] + 1) {
			w = dfs(v, min(e[i].w, f - used));
			e[i].w -= w, e[i^1].w += w, used += w;
			if (used == f) return used;
		}
	if (!used) dis[x] = -1;
	return used;
}

inline void Dinic() {
	int flow = 0;
	for (; bfs();) {
		for (int i = 0; i <= T; ++i) cur[i] = h[i];
		flow += dfs(0, inf);
	}
}

int main() {
	int u, v; in(n), T = n + 1;
	for (int i = 1; i <= n; ++i) {
		in(s[i]);
		if (s[i] > 0) add(0, i, s[i], 0, 0);
		else if (s[i] < 0) add(i, T, -s[i], 0, 0);
	}
	in(m);
	for (int i = 1; i <= m; ++i) in(u), in(v), add(u, v, inf, inf, i);
	Dinic();
	for (int i = 2; i <= tot; ++i)
		if (e[i].id) ans[e[i].id] = inf - e[i^1].w;
	for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
	return 0;
}


#include <cstdio>
using namespace std;

const int N = 2e5 + 10;
struct E {int v, w, id, nt;} e[N<<1];
int n, m, tot, h[N], s[N], f[N], vis[N], use[N<<1];

inline void add(int u, int v, int id) {
	e[++tot] = (E){v, 1, id, h[u]}, h[u] = tot;
	e[++tot] = (E){u, 0, id, h[v]}, h[v] = tot;
}
template <class T> inline void in(T &x) {
	x = 0; int f = 1; char ch = getchar();
	for (; ch<'0' || ch>'9';) {if (ch=='-') f=-1; ch = getchar();}
	for (; ch>='0' && ch<='9';) x = x*10 + ch-'0', ch = getchar();
	x *= f;
}

inline void dfs(int x) {
	vis[x] = 1;
	for (int v, i = h[x]; i; i = e[i].nt) {
		if (vis[v = e[i].v] || use[e[i].id]) continue;
		use[e[i].id] = 1;
		dfs(v);
		if (s[v] != 0) {
			if (e[i].w) f[e[i].id] = s[v], s[x] += s[x];
			else f[e[i].id] = -s[v], s[x] += s[v];
			s[v] = 0;
		}
	}
}

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


#include <bits/stdc++.h>
typedef long long ll;
typedef double ld;
using namespace std;
const int Max = 5e5+ 5, Mod = 1e9 + 7;

ll n, m, f[Max];
int s[Max];
vector<pair<int, int>> G[Max], T[Max];
bool vis[Max];

void build(int u)
{
    vis[u] = true;
    for(auto v : G[u])
        if (!vis[v.first])
        {
            T[u].push_back(v);
            T[v.first].push_back({ u,v.second ^ 1 });
            build(v.first);
        }
}

ll DFS1(int u, int p)
{
    ll sum = 0;
    if (s[u] > 0)
        sum += s[u];
    for(auto v : T[u])
        if (v.first != p)
        {
            ll x= DFS1(v.first, u);
            f[v.second] += x;
            sum += x;
        }
    return sum;
}

ll DFS2(int u, int p)
{
    ll sum = 0;
    if (s[u] < 0)
        sum += -s[u];
    for (auto v : T[u])
        if (v.first != p)
        {
            ll x = DFS2(v.first, u);
            f[v.second ^ 1] += x;
            sum += x;
        }
    return sum;
}

int main()
{
    int ID = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> s[i];
    cin >> m;
    for (int i = 0; i < m; i++)
    {
        int x, y;
        cin >> x >> y;
        G[x].push_back({ y,ID++ });
        G[y].push_back({ x,ID++ });
    }
    build(1);
    ll s1 = DFS1(1, 1);
    ll s2 = DFS2(1, 1);
    if (s1 != s2)
    {
        cout << "Impossible" << endl;
        return 0;
    }
    cout << "Possible" << endl;
    for (int i = 0; i < ID; i += 2)
        cout << f[i] - f[i + 1] << endl;
    return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <algorithm>
#include <iomanip>
#include <map>
#include <set>
#include <math.h>
#include <stack>
#include <deque>
#include <numeric>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <bitset>
#include <functional>
#define mpair make_pair
#define all(v) v.begin(),v.end()
using namespace std;
typedef long long ll;
typedef long double ld;
const ld epsylon = 1e-9;

const std::string PROGRAM_NAME = "ivo";

int main() {
  // freopen((PROGRAM_NAME + ".in").c_str(), "r", stdin);
  // freopen((PROGRAM_NAME + ".out").c_str(), "w", stdout);

  int n;
  cin >> n;
  vector<int> a(n);
  for (int i = 0; i < (int)a.size(); ++i) {
    scanf("%d", &a[i]);
  }

  int total = 0;
  for (int i = 0; i < (int)a.size(); ++i) {
     total += a[i];
  }
  if (total != 0) {
    cout << "Impossible" << endl;
    return 0;
  }
  vector<vector<pair<int, int> > > ne(n);
  vector<pair<int, int> > edges;

  int m;
  cin >> m;
  for (int i = 0; i < m; ++i) {
    int f, t;
    scanf("%d %d", &f, &t);
    f--;
    t--;
    ne[f].push_back(mpair(t, i));
    ne[t].push_back(mpair(f, i));
    edges.push_back(mpair(f, t));
  }

  vector<int> res(m, 0);

  vector<pair<int, int> > dad(n, pair<int, int>(-1, -1));
  dad[0] = mpair(0, -1);
  queue<int> q;
  q.push(0);

  vector<int> ordered;
  while (!q.empty()) {
    int c = q.front();
    q.pop();
    ordered.push_back(c);
    for (int i = 0; i < (int)ne[c].size() ;++i) {
      int v = ne[c][i].first;

      if (dad[v].first != -1) {
        continue;
      }
      dad[v] = mpair(c, ne[c][i].second);
      q.push(v);
    }
  }

  if (n > 1) {
    for (int i = (int)ordered.size() - 1; i >= 0; --i) {
      int v = ordered[i];

      int ei = dad[v].second;
      int nv = dad[v].first;
      if (edges[ei].second == v) {
         res[ei] = a[v];
      } else {
        res[ei] = -a[v];
      }
      if (nv >= 0) {
        a[nv] += a[v];
      }
    }
  }
  cout << "Possible" << endl;
  for (int i = 0; i < (int)res.size(); ++i) {
    printf("%d\n", res[i]);
  }
  return 0;
}


#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <queue>
#include <algorithm>
#include <iomanip>
#include <map>
#include <set>
#include <math.h>
#include <stack>
#include <deque>
#include <numeric>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <bitset>
#include <functional>
#define mpair make_pair
#define all(v) v.begin(),v.end()
using namespace std;
typedef long long ll;
typedef long double ld;
const ld epsylon = 1e-9;

const std::string PROGRAM_NAME = "ivo";

int main() {
  // freopen((PROGRAM_NAME + ".in").c_str(), "r", stdin);
  // freopen((PROGRAM_NAME + ".out").c_str(), "w", stdout);

  int n;
  cin >> n;
  vector<int> a(n);
  for (int i = 0; i < (int)a.size(); ++i) {
    scanf("%d", &a[i]);
  }

  int total = 0;
  for (int i = 0; i < (int)a.size(); ++i) {
     total += a[i];
  }
  if (total != 0) {
    cout << "Impossible" << endl;
    return 0;
  }
  vector<vector<pair<int, int> > > ne(n);
  vector<pair<int, int> > edges;

  int m;
  cin >> m;
  for (int i = 0; i < m; ++i) {
    int f, t;
    scanf("%d %d", &f, &t);
    f--;
    t--;
    ne[f].push_back(mpair(t, i));
    ne[t].push_back(mpair(f, i));
    edges.push_back(mpair(f, t));
  }

  vector<int> res(m, 0);

  vector<pair<int, int> > dad(n, pair<int, int>(-1, -1));
  dad[0] = mpair(0, -1);
  queue<int> q;
  q.push(0);

  vector<int> ordered;
  while (!q.empty()) {
    int c = q.front();
    q.pop();
    ordered.push_back(c);
    for (int i = 0; i < (int)ne[c].size() ;++i) {
      int v = ne[c][i].first;

      if (dad[v].first != -1) {
        continue;
      }
      dad[v] = mpair(c, ne[c][i].second);
      q.push(v);
    }
  }

  for (int i = (int)ordered.size() - 1; i >= 0; --i) {
    int v = ordered[i];

    int ei = dad[v].second;
    int nv = dad[v].first;
    if (edges[ei].second == v) {
       res[ei] = a[v];
    } else {
      res[ei] = -a[v];
    }
    if (nv >= 0) {
      a[nv] += a[v];
    }
  }
  cout << "Possible" << endl;
  for (int i = 0; i < (int)res.size(); ++i) {
    printf("%d\n", res[i]);
  }
  return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
int head[maxn],n,m,e;
int val[maxn];
bool vis[maxn];
struct Edge
{
    int u,v;
    int cap;
    int next;
}edge[maxn*2];
void addedge(int u,int v)
{
    edge[e].u=u;
    edge[e].v=v;
    edge[e].cap=0;
    edge[e].next=head[u];
    head[u]=e++;

    edge[e].u=v;
    edge[e].v=u;
    edge[e].cap=0;
    edge[e].next=head[v];
    head[v]=e++;
}
void dfs(int u)
{
    vis[u]=true;
    int i;
    for(i=head[u];i!=-1;i=edge[i].next)
    {
        int v=edge[i].v;
        if(!vis[v])
            dfs(v);
        edge[i].cap+=val[v];
        edge[i^1].cap+=-val[v];
        val[u]+=val[v];
        val[v]=0;
    }
    return;
}
int main()
{
    int n;
    scanf("%d",&n);
    int i;
    for(i=1;i<=n;i++)
    {
        vis[i]=false;
        head[i]=-1;
        scanf("%d",&val[i]);
    }
    scanf("%d",&m);
    e=0;
    for(i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b);
    }
    dfs(1);
    if(val[1]!=0)
        printf("Impossible\n");
    else
    {
        printf("Possible\n");
        for(i=0;i<2*m;i+=2)
            printf("%d\n",edge[i].cap);
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
const int inf = 0x3f3f3f3f<<1;
int n,m,S,T;
int e,head[maxn*2],cur[maxn*2];
int flow[maxn*2];
int low[maxn*2],gap[maxn*2],d[maxn*2],pre[maxn*2],pree[maxn*2];
struct Edge
{
    int u,v;
    int cap,next;
}edge[maxn*8];
void addedge(int u,int v,int c)
{
    edge[e].u=u;
    edge[e].v=v;
    edge[e].cap=c;
    edge[e].next=head[u];
    head[u]=e++;

    edge[e].u=v;
    edge[e].v=u;
    edge[e].cap=c;
    edge[e].next=head[v];
    head[v]=e++;
}
int sap(int ss,int tt,int all)
{
	int ret=0;
	bool fail;
	all+=ss;
	for(int i=ss;i<all;i++)
		cur[i]=head[i];
	low[ss]=inf;
	gap[ss]=all;
	int u=ss;
	while(d[ss]<all)
	{
		fail=true;
		for(int i=cur[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].v;
			cur[u]=i;
			if(edge[i].cap&&d[u]==d[v]+1)
			{
				pre[v]=u;
				pree[v]=i;
				low[v]=min(low[u],edge[i].cap);
				u=v;
				if(u==tt)
				{
					do
					{
						edge[pree[u]].cap-=low[tt];
						edge[pree[u]^1].cap+=low[tt];
						u=pre[u];
					}while(u!=ss);
					ret+=low[tt];
				}
				fail=false;
				break;
			}
		}
		if(fail)
		{
			gap[d[u]]--;
			if(!gap[d[u]])
				return ret;
			d[u]=all;
			for(int i=head[u];i!=-1;i=edge[i].next)
				if(edge[i].cap)
					d[u]=min(d[u],d[edge[i].v]+1);
			gap[d[u]]++;
			cur[u]=head[u];
			if(u!=ss)
				u=pre[u];
		}
	}
	return ret;
}
int main()
{
    scanf("%d",&n);
    int i,sum=0;
    for(i=1;i<=n;i++)
    {
        head[i]=-1;
        scanf("%d",&flow[i]);
        sum+=flow[i];
    }
    scanf("%d",&m);
    e=0;
    for(i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b,inf);
    }
    if(sum!=0)
        printf("Impossible\n");
    else
    {
        S=0;T=n+1;
        head[S]=head[T]=-1;
        int p_sum=0;
        for(i=1;i<=n;i++)
        {
            if(flow[i]>0)
            {
                addedge(i,T,flow[i]);
                p_sum+=flow[i];
            }
            if(flow[i]<0)
                addedge(S,i,-flow[i]);
        }
        int ret=sap(S,T,n+2);
        if(ret!=p_sum)
            printf("Impossible\n");
        else
        {
            printf("Possible\n");
            for(i=0;i<2*m;i+=2)
                printf("%d\n",inf-edge[i].cap);
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
const int inf = 0x3f3f3f3f<<1;
int n,m,S,T;
int e,head[maxn],cur[maxn];
int flow[maxn];
int low[maxn],gap[maxn],d[maxn],pre[maxn],pree[maxn];
struct Edge
{
    int u,v;
    int cap,next;
}edge[maxn*4];
void addedge(int u,int v,int c)
{
    edge[e].u=u;
    edge[e].v=v;
    edge[e].cap=c;
    edge[e].next=head[u];
    head[u]=e++;

    edge[e].u=v;
    edge[e].v=u;
    edge[e].cap=c;
    edge[e].next=head[v];
    head[v]=e++;
}
int sap(int ss,int tt,int all)
{
	int ret=0;
	bool fail;
	all+=ss;
	for(int i=ss;i<all;i++)
		cur[i]=head[i];
	low[ss]=inf;
	gap[ss]=all;
	int u=ss;
	while(d[ss]<all)
	{
		fail=true;
		for(int i=cur[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].v;
			cur[u]=i;
			if(edge[i].cap&&d[u]==d[v]+1)
			{
				pre[v]=u;
				pree[v]=i;
				low[v]=min(low[u],edge[i].cap);
				u=v;
				if(u==tt)
				{
					do
					{
						edge[pree[u]].cap-=low[tt];
						edge[pree[u]^1].cap+=low[tt];
						u=pre[u];
					}while(u!=ss);
					ret+=low[tt];
				}
				fail=false;
				break;
			}
		}
		if(fail)
		{
			gap[d[u]]--;
			if(!gap[d[u]])
				return ret;
			d[u]=all;
			for(int i=head[u];i!=-1;i=edge[i].next)
				if(edge[i].cap)
					d[u]=min(d[u],d[edge[i].v]+1);
			gap[d[u]]++;
			cur[u]=head[u];
			if(u!=ss)
				u=pre[u];
		}
	}
	return ret;
}
int main()
{
    scanf("%d",&n);
    int i,sum=0;
    for(i=1;i<=n;i++)
    {
        head[i]=-1;
        scanf("%d",&flow[i]);
        sum+=flow[i];
    }
    scanf("%d",&m);
    e=0;
    for(i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b,inf);
    }
    if(sum!=0)
        printf("Impossible\n");
    else
    {
        S=0;T=n+1;
        head[S]=head[T]=-1;
        int p_sum=0;
        for(i=1;i<=n;i++)
        {
            if(flow[i]>0)
            {
                addedge(i,T,flow[i]);
                p_sum+=flow[i];
            }
            if(flow[i]<0)
                addedge(S,i,-flow[i]);
        }
        int ret=sap(S,T,n+2);
        if(ret!=p_sum)
            printf("Impossible\n");
        else
        {
            printf("Possible\n");
            for(i=0;i<2*m;i+=2)
                printf("%d\n",inf-edge[i].cap);
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
const int inf = 1<<29;
int n,m,S,T;
int e,head[maxn],cur[maxn];
int flow[maxn];
int low[maxn],gap[maxn],d[maxn],pre[maxn],pree[maxn];
struct Edge
{
    int u,v;
    int cap,next;
}edge[maxn*4];
void addedge(int u,int v,int c)
{
    edge[e].u=u;
    edge[e].v=v;
    edge[e].cap=c;
    edge[e].next=head[u];
    head[u]=e++;

    edge[e].u=v;
    edge[e].v=u;
    edge[e].cap=c;
    edge[e].next=head[v];
    head[v]=e++;
}
int sap(int ss,int tt,int all)
{
	int ret=0;
	bool fail;
	all+=ss;
	memset(low,0,sizeof(low));
	memset(gap,0,sizeof(gap));
	memset(d,0,sizeof(d));
	for(int i=ss;i<all;i++)
		cur[i]=head[i];
	low[ss]=inf;
	gap[ss]=all;
	int u=ss;
	while(d[ss]<all)
	{
		fail=true;
		for(int i=cur[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].v;
			cur[u]=i;
			if(edge[i].cap&&d[u]==d[v]+1)
			{
				pre[v]=u;
				pree[v]=i;
				low[v]=min(low[u],edge[i].cap);
				u=v;
				if(u==tt)
				{
					do
					{
						edge[pree[u]].cap-=low[tt];
						edge[pree[u]^1].cap+=low[tt];
						u=pre[u];
					}while(u!=ss);
					ret+=low[tt];
				}
				fail=false;
				break;
			}
		}
		if(fail)
		{
			gap[d[u]]--;
			if(!gap[d[u]])
				return ret;
			d[u]=all;
			for(int i=head[u];i!=-1;i=edge[i].next)
				if(edge[i].cap)
					d[u]=min(d[u],d[edge[i].v]+1);
			gap[d[u]]++;
			cur[u]=head[u];
			if(u!=ss)
				u=pre[u];
		}
	}
	return ret;
}
int main()
{
    scanf("%d",&n);
    int i,sum=0;
    for(i=1;i<=n;i++)
    {
        head[i]=-1;
        scanf("%d",&flow[i]);
        sum+=flow[i];
    }
    scanf("%d",&m);
    e=0;
    for(i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b,inf);
    }
    if(sum!=0)
        printf("Impossible\n");
    else
    {
        S=0;T=n+1;
        head[S]=head[T]=-1;
        int p_sum=0;
        for(i=1;i<=n;i++)
        {
            if(flow[i]>0)
            {
                addedge(i,T,flow[i]);
                p_sum+=flow[i];
            }
            if(flow[i]<0)
                addedge(S,i,-flow[i]);
        }
        int ret=sap(S,T,n+2);
        if(ret!=p_sum)
            printf("Impossible\n");
        else
        {
            printf("Possible\n");
            for(i=0;i<2*m;i+=2)
                printf("%d\n",inf-edge[i].cap);
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
const int inf = 0x3f3f3f3f<<1;
int n,m,S,T;
int e,head[maxn],cur[maxn];
int flow[maxn];
int low[maxn],gap[maxn],d[maxn],pre[maxn],pree[maxn];
struct Edge
{
    int u,v;
    int cap,next;
}edge[maxn*8];
void addedge(int u,int v,int c)
{
    edge[e].u=u;
    edge[e].v=v;
    edge[e].cap=c;
    edge[e].next=head[u];
    head[u]=e++;

    edge[e].u=v;
    edge[e].v=u;
    edge[e].cap=c;
    edge[e].next=head[v];
    head[v]=e++;
}
int sap(int ss,int tt,int all)
{
	int ret=0;
	bool fail;
	all+=ss;
	for(int i=ss;i<all;i++)
		cur[i]=head[i];
	low[ss]=inf;
	gap[ss]=all;
	int u=ss;
	while(d[ss]<all)
	{
		fail=true;
		for(int i=cur[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].v;
			cur[u]=i;
			if(edge[i].cap&&d[u]==d[v]+1)
			{
				pre[v]=u;
				pree[v]=i;
				low[v]=min(low[u],edge[i].cap);
				u=v;
				if(u==tt)
				{
					do
					{
						edge[pree[u]].cap-=low[tt];
						edge[pree[u]^1].cap+=low[tt];
						u=pre[u];
					}while(u!=ss);
					ret+=low[tt];
				}
				fail=false;
				break;
			}
		}
		if(fail)
		{
			gap[d[u]]--;
			if(!gap[d[u]])
				return ret;
			d[u]=all;
			for(int i=head[u];i!=-1;i=edge[i].next)
				if(edge[i].cap)
					d[u]=min(d[u],d[edge[i].v]+1);
			gap[d[u]]++;
			cur[u]=head[u];
			if(u!=ss)
				u=pre[u];
		}
	}
	return ret;
}
int main()
{
    scanf("%d",&n);
    int i,sum=0;
    for(i=1;i<=n;i++)
    {
        head[i]=-1;
        scanf("%d",&flow[i]);
        sum+=flow[i];
    }
    scanf("%d",&m);
    e=0;
    for(i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b,inf);
    }
    if(sum!=0)
        printf("Impossible\n");
    else
    {
        S=0;T=n+1;
        head[S]=head[T]=-1;
        int p_sum=0;
        for(i=1;i<=n;i++)
        {
            if(flow[i]>0)
            {
                addedge(i,T,flow[i]);
                p_sum+=flow[i];
            }
            if(flow[i]<0)
                addedge(S,i,-flow[i]);
        }
        int ret=sap(S,T,n+2);
        if(ret!=p_sum)
            printf("Impossible\n");
        else
        {
            printf("Possible\n");
            for(i=0;i<2*m;i+=2)
                printf("%d\n",inf-edge[i].cap);
        }
    }
    return 0;
}


#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
const long long inf = 1ll<<60;
int n,m,S,T;
int e,head[maxn],cur[maxn];
int gap[maxn],d[maxn],pre[maxn],pree[maxn];
long long low[maxn],flow[maxn];
struct Edge
{
    int u,v;
    long long cap;
    int next;
}edge[maxn*4];
void addedge(int u,int v,long long c)
{
    edge[e].u=u;
    edge[e].v=v;
    edge[e].cap=c;
    edge[e].next=head[u];
    head[u]=e++;

    edge[e].u=v;
    edge[e].v=u;
    edge[e].cap=c;
    edge[e].next=head[v];
    head[v]=e++;
}
long long sap(int ss,int tt,int all)
{
	long long ret=0;
	bool fail;
	all+=ss;
	for(int i=ss;i<all;i++)
		cur[i]=head[i];
	low[ss]=inf;
	gap[ss]=all;
	int u=ss;
	while(d[ss]<all)
	{
		fail=true;
		for(int i=cur[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].v;
			cur[u]=i;
			if(edge[i].cap&&d[u]==d[v]+1)
			{
				pre[v]=u;
				pree[v]=i;
				low[v]=min(low[u],edge[i].cap);
				u=v;
				if(u==tt)
				{
					do
					{
						edge[pree[u]].cap-=low[tt];
						edge[pree[u]^1].cap+=low[tt];
						u=pre[u];
					}while(u!=ss);
					ret+=low[tt];
				}
				fail=false;
				break;
			}
		}
		if(fail)
		{
			gap[d[u]]--;
			if(!gap[d[u]])
				return ret;
			d[u]=all;
			for(int i=head[u];i!=-1;i=edge[i].next)
				if(edge[i].cap)
					d[u]=min(d[u],d[edge[i].v]+1);
			gap[d[u]]++;
			cur[u]=head[u];
			if(u!=ss)
				u=pre[u];
		}
	}
	return ret;
}
int main()
{
    scanf("%d",&n);
    int i;
    long long sum=0;
    for(i=1;i<=n;i++)
    {
        head[i]=-1;
        scanf("%I64d",&flow[i]);
        sum+=flow[i];
    }
    scanf("%d",&m);
    e=0;
    for(i=0;i<m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(a,b,inf);
    }
    if(sum!=0)
        printf("Impossible\n");
    else
    {
        S=0;T=n+1;
        head[S]=head[T]=-1;
        long long p_sum=0;
        for(i=1;i<=n;i++)
        {
            if(flow[i]>0)
            {
                addedge(i,T,flow[i]);
                p_sum+=flow[i];
            }
            if(flow[i]<0)
                addedge(S,i,-flow[i]);
        }
        long long ret=sap(S,T,n+2);
        if(ret!=p_sum)
            printf("Impossible\n");
        else
        {
            printf("Possible\n");
            for(i=0;i<2*m;i+=2)
                printf("%I64d\n",inf-edge[i].cap);
        }
    }
    return 0;
}


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

const int MAXN = 200005;
struct Edge { int to, next, id; } edge[MAXN << 1];
int dep[MAXN], s[MAXN], head[MAXN], ans[MAXN], n, m, tot;
void addedge(int u, int v, int id) {
	edge[++tot] = (Edge) { v, head[u], id };
	head[u] = tot;
}
int sta[MAXN], cir[MAXN], arr[MAXN], fr[MAXN], to[MAXN], flag;
void dfs(int u, int fa) {
	dep[u] = dep[fa] + 1;
	sta[++tot] = u;
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].to;
		if (dep[v]) {
			edge[i].to = 0; continue;
			if (flag) { edge[i].to = 0; continue; }
			while (sta[tot] != v) {
				cir[sta[tot]] = 1;
				--tot;
			}
			cir[v] = flag = 1;
		} else dfs(v, u);
	}
	--tot;
}
void dfs1(int u, int fa) {
	for (int i = head[u]; i; i = edge[i].next) {
		int v = edge[i].to;
		if (!v || v == fa || cir[v]) continue;
		dfs1(v, u);
		ans[edge[i].id] = s[v];
		if (fr[edge[i].id] == v) ans[edge[i].id] = -ans[edge[i].id];
		s[u] += s[v];
	}
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", s + i);
	scanf("%d", &m);
	for (int i = 1; i <= m; i++) {
		int u, v; scanf("%d%d", &u, &v);
		addedge(u, v, i), addedge(v, u, i);
		fr[i] = u, to[i] = v;
	}
	dfs(1, tot = 0);
	dfs1(1, 0);
	if (s[1]) return puts("Impossible") * 0;
	puts("Possible");
	for (int i = 1; i <= m; i++) printf("%d\n", ans[i]);
	return 0;
}//hello


/**************************************************************
    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[it->se]+=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+n));
	}
	dfs(1);
	rep(i,m) cout<<ans[i]-ans[i+1]<<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]<<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[it->se]=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+n));
	}
	dfs(1);
	rep(i,m) cout<<ans[i]-ans[i+1]<<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[it->se]+=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+n));
	}
	dfs(1);
	rep(i,m) cout<<ans[i]+ans[i+1]<<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\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;
}