#include <bits/stdc++.h>
using namespace std;
const int maxn = 260;
struct node {
  int f, t, ft;
} a[maxn];
bool deploy[maxn], ct[maxn];
int has[8];
vector<pair<int, int> > edge;
int n;
bool solve() {
  has[7] = 1;
  vector<int> one(3);
  one[0] = 1;
  one[1] = 2;
  one[2] = 4;
  while (1) {
    bool update = 0;
    for (int i = 1; i <= 7; ++i) {
      if (!has[i]) continue;
      for (int j = 2; j <= n; ++j) {
        if (deploy[j] || i != a[j].f) continue;
        deploy[j] = ct[j] = update = 1;
        edge.push_back(make_pair(has[i], j));
        if (!has[a[j].ft]) has[a[j].ft] = j;
      }
    }
    if (update) continue;
    for (int j = 2; j <= n; ++j) {
      if (deploy[j] || __builtin_popcount(a[j].f) != 2) continue;
      int tmp = 0;
      for (int x : one) {
        if (has[x] && (x & a[j].f)) ++tmp;
      }
      if (tmp == 2) {
        deploy[j] = update = 1;
        for (int x : one) {
          if (has[x] && (x & a[j].f)) edge.push_back(make_pair(has[x], j));
        }
        has[a[j].f] = j;
      }
      if (update) break;
    }
    if (!update) break;
  }
  for (int i = 2; i <= n; ++i)
    if (!deploy[i] && a[i].f) return false;
  return true;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < 3; ++j) {
      int x;
      cin >> x;
      a[i].f |= x << j;
    }
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < 3; ++j) {
      int x;
      cin >> x;
      a[i].t |= x << j;
    }
    a[i].ft = a[i].f & a[i].t;
  }
  ct[1] = deploy[1] = 1;
  if (!solve())
    cout << "Impossible\n";
  else {
    cout << "Possible\n";
    for (int i = 1; i <= n; ++i) cout << ct[i] << " \n"[i == n];
    cout << edge.size() << '\n';
    for (auto x : edge) cout << x.first << ' ' << x.second << '\n';
  }
  return 0;
}
