#include <bits/stdc++.h>
using namespace std;
const long long mxN = 200000;
vector<array<long long, 2>> adj[mxN];
long long ans[mxN];
struct dsu {
  vector<long long> par;
  vector<long long> sz;
  dsu() { dsu(1); }
  dsu(long long size) {
    par.resize(size);
    sz.resize(size);
    iota((par).begin(), (par).end(), 0);
    fill((sz).begin(), (sz).end(), 1);
  }
  long long find(long long x) {
    if (par[x] == x) {
      return x;
    } else
      return x = find(par[x]);
  }
  bool merge(long long u, long long v) {
    u = find(u);
    v = find(v);
    if (u == v) return false;
    if (sz[u] > sz[v]) {
      swap(u, v);
    }
    par[u] = v;
    sz[v] += sz[u];
    return true;
  }
};
long long s[mxN], depth[mxN];
long long dfs(long long v, long long p, long long id) {
  for (auto [i, ind] : adj[v]) {
    if (i == p) continue;
    depth[i] = depth[v] + 1;
    s[v] += dfs(i, v, ind);
  }
  if (p != -1) {
    ans[id] = s[v];
    return s[v];
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  long long n, m;
  cin >> n;
  long long sum = 0;
  for (long long i = 0; i < n; ++i) {
    cin >> s[i];
    sum += s[i];
  }
  cin >> m;
  dsu mst(n);
  array<long long, 2> edges[m];
  for (long long i = 0; i < m; ++i) {
    long long a, b;
    cin >> a >> b;
    --a;
    --b;
    edges[i] = {a, b};
    if (mst.merge(a, b)) {
      adj[a].push_back({b, i});
      adj[b].push_back({a, i});
    }
  }
  if (sum != 0) {
    cout << "Impossible\n";
    return 0;
  }
  cout << "Possible\n";
  dfs(0, -1, -1);
  for (long long i = 0; i < m; ++i) {
    if (depth[edges[i][0]] > depth[edges[i][1]]) ans[i] = -ans[i];
    cout << ans[i] << "\n";
  }
}
