#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
mt19937 rnd(time(0) + (unsigned long long)new char);
struct point {
  int x, y, op, id;
  point(int x = 0, int y = 0, int op = 0, int id = 0)
      : x(x), y(y), op(op), id(id) {}
  bool operator<(const point& a) const {
    if (x != a.x) return x < a.x;
    return y < a.y;
  }
  point operator-(const point& a) const { return point(x - a.x, y - a.y); }
  int operator/(const point& a) const { return x * a.y - y * a.x; }
} a[N], b[N];
int n;
vector<pair<int, int> > edges, vec;
void solve() {
  edges.clear();
  for (int m = n; m >= 2; --m) {
    sort(a + 1, a + m + 1);
    int t = 0;
    for (int i = 1; i <= m; ++i) {
      for (; t >= 2 && (b[t] - b[t - 1]) / (a[i] - b[t]) < 0; --t)
        ;
      b[++t] = a[i];
    }
    int pr = t - 1;
    for (int i = m - 1; i; --i) {
      for (; t >= pr + 2 && (b[t] - b[t - 1]) / (a[i] - b[t]) < 0; --t)
        ;
      b[++t] = a[i];
    }
    vec.clear();
    for (int i = 1; i < t; ++i)
      if (b[i].op == b[i + 1].op) {
        int u = b[i].id, v = b[i + 1].id;
        if (u > v) swap(u, v);
        vec.emplace_back(u, v);
      }
    if (vec.empty()) {
      if (m == 2 && (a[1].op != a[2].op)) break;
      return;
    }
    shuffle(vec.begin(), vec.end(), rnd);
    int u = vec[0].first, v = vec[0].second;
    edges.emplace_back(u, v);
    if (rnd() & 1) swap(u, v);
    for (int i = 1; i <= m; ++i)
      if (a[i].id == u) swap(a[i], a[m]);
  }
  sort(edges.begin(), edges.end());
  cout << edges.size() << '\n';
  for (auto i : edges) cout << i.first << ' ' << i.second << '\n';
  exit(0);
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 1; i <= n; ++i)
    cin >> a[i].x >> a[i].y >> a[i].op, a[i].id = i - 1;
  for (double ti = clock(); (clock() - ti) < CLOCKS_PER_SEC * 0.4; solve())
    ;
  cout << "Impossible\n";
  return 0;
}
