#include <bits/stdc++.h>
using namespace std;
int a[270];
int b[270];
vector<int> aelements[270];
map<int, vector<int>> providers;
map<int, vector<int>> pending;
int CT[270];
vector<pair<int, int>> edges;
void AggregateProviders() {
  if (providers[110].empty() && !providers[100].empty() &&
      !providers[10].empty()) {
    providers[110] = {providers[100][0], providers[10][0]};
  }
  if (providers[101].empty() && !providers[100].empty() &&
      !providers[1].empty()) {
    providers[101] = {providers[100][0], providers[1][0]};
  }
  if (providers[11].empty() && !providers[10].empty() &&
      !providers[1].empty()) {
    providers[11] = {providers[10][0], providers[1][0]};
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    int t1, t2, t3;
    scanf("%d %d %d", &t1, &t2, &t3);
    a[i] = t1 * 100 + t2 * 10 + t3;
    aelements[i] = {t1, t2, t3};
    CT[i] = 1;
    if (i > 1 && a[i] > 0 && a[i] != 111) pending[a[i]].push_back(i);
  }
  for (int i = 1; i <= n; i++) {
    int t1, t2, t3;
    scanf("%d %d %d", &t1, &t2, &t3);
    t1 = min(t1, aelements[i][0]);
    t2 = min(t2, aelements[i][1]);
    t3 = min(t3, aelements[i][2]);
    b[i] = t1 * 100 + t2 * 10 + t3;
  }
  for (int i = 2; i <= n; i++) {
    if (a[i] == 111) {
      edges.push_back({1, i});
      providers[b[i]] = {i};
    }
  }
  bool ok = true;
  while (ok) {
    AggregateProviders();
    ok = false;
    for (auto& kv : pending) {
      int k = kv.first;
      vector<int>& v = kv.second;
      if (v.empty()) continue;
      if (providers[k].empty()) continue;
      ok = true;
      for (int idx : v) {
        for (int provider : providers[k]) {
          edges.push_back({provider, idx});
        }
        if (providers[b[idx]].empty()) {
          providers[b[idx]] = {idx};
        } else {
          if (providers[k].size() == 2) {
            CT[idx] = 0;
            providers[k] = {idx};
          }
        }
      }
      v.clear();
    }
  }
  for (auto& kv : pending) {
    int k = kv.first;
    vector<int>& v = kv.second;
    if (!v.empty()) {
      printf("Impossible\n");
      return 0;
    }
  }
  printf("Possible\n");
  for (int i = 1; i <= n; i++) {
    printf("%d ", CT[i]);
  }
  printf("\n%d\n", edges.size());
  for (pair<int, int> kv : edges) {
    printf("%d %d\n", kv.first, kv.second);
  }
  return 0;
}
