#include <bits/stdc++.h>
using namespace std;
template <class T>
bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}
using ll = long long;
using R = long double;
const R EPS = 1e-9L;
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max(x, 0.0L)); }
const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int n, m;
const int limit = 200010;
int f[limit], a[limit], b[limit];
int e[limit];
struct Union_find {
  Union_find(int n) { data.assign(n, -1); }
  int find(int x) { return (data[x] < 0) ? x : data[x] = find(data[x]); }
  void unite(int a, int b) {
    a = find(a), b = find(b);
    if (a != b) {
      if (data[a] < data[b]) swap(a, b);
      data[a] += data[b], data[b] = a;
    }
  }
  bool same(int a, int b) { return find(a) == find(b); }
  int size(int x) { return -data[x]; }
  vector<int> data;
};
vector<int> tree[limit];
int dfs(int v, int p) {
  int ret = f[v];
  for (auto &i : tree[v]) {
    const int v2 = a[i] ^ b[i] ^ v;
    if (v2 == p) continue;
    const int val = dfs(v2, v);
    e[i] = val * ((v == a[i]) ? 1 : -1);
    ret += val;
  }
  return ret;
}
int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = int(0); i < int(n); ++i) cin >> f[i];
  cin >> m;
  for (int i = int(0); i < int(m); ++i) cin >> a[i] >> b[i], a[i]--, b[i]--;
  int total = 0;
  for (int i = int(0); i < int(n); ++i) total += f[i];
  if (total != 0) {
    cout << "Impossible" << endl;
    return 0;
  }
  cout << "Possible" << endl;
  Union_find uf(n);
  for (int i = int(0); i < int(m); ++i) {
    if (uf.same(a[i], b[i])) continue;
    tree[a[i]].push_back(i);
    tree[b[i]].push_back(i);
    uf.unite(a[i], b[i]);
  }
  dfs(0, -1);
  for (int i = int(0); i < int(m); ++i) cout << e[i] << endl;
  return 0;
}
