#include <bits/stdc++.h>   using namespace std;   int get() {     char ch;     while (ch = getchar(), (ch <  0  || ch >  9 ) && ch !=  - )       ;     if (ch ==  - ) {       int s = 0;       while (ch = getchar(), ch >=  0  && ch <=  9 ) s = s * 10 + ch -  0 ;       return -s;     }     int s = ch -  0 ;     while (ch = getchar(), ch >=  0  && ch <=  9 ) s = s * 10 + ch -  0 ;     return s;   }   const int N = 1e3 + 5;   int n;   struct point {     int x, y, col, id;     void read() {       x = get();       y = get();       col = get();     }   } a[N];   int cross(point a, point b, point c) {     return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);   }   int operator*(point a, point b) { return a.x * b.y - a.y * b.x; }   point operator-(point a, point b) {     a.x -= b.x, a.y -= b.y;     return a;   }   point operator+(point a, point b) {     a.x += b.x, a.y += b.y;     return a;   }   int be[N];   point sta[N];   int top;   bool cmp(point a, point b) { return a.x == b.x ? a.y < b.y : a.x < b.x; }   struct edge {     int x, y;     edge(const int x_ = 0, const int y_ = 0) {       x = x_;       y = y_;     }   } ed[N];   int tot;   point que[N];   int k;   bool inside(point a, point b, point c, point q) {     return ((cross(a, b, q) >= 0) != (cross(a, c, q) >= 0)) &&            ((cross(b, a, q) >= 0) != cross(b, c, q) >= 0) &&            ((cross(c, a, q) >= 0) != (cross(c, b, q) >= 0));   }   void solve(point A, point B, point C) {     for (int i = 1; i <= n; i++)       if (a[i].col == C.col && inside(A, B, C, a[i])) {         ed[++tot] = edge(C.id, a[i].id);         solve(A, B, a[i]);         solve(a[i], C, A);         solve(a[i], C, B);         return;       }     for (int i = 1; i <= n; i++)       if (inside(A, B, C, a[i])) ed[++tot] = edge(A.id, a[i].id);   }   int main() {     n = get();     int all = 0;     for (int i = 1; i <= n; i++) {       a[i].read();       a[i].id = i;       all |= 1 << a[i].col;     }     if (all != 3) {       printf( %d n , n - 1);       for (int i = 1; i <= n - 1; i++) printf( %d %d n , 0, i);       return 0;     }     sort(a + 1, a + 1 + n, cmp);     top = 0;     for (int i = 1; i <= n; i++) {       if (top && sta[top].x == a[i].x) continue;       while (top > 1 && cross(sta[top - 1], a[i], sta[top]) >= 0) top--;       sta[++top] = a[i];     }     for (int i = 1; i <= top; i++) be[sta[i].id] = 1;     top = 0;     for (int i = n; i >= 1; i--) {       if (top && sta[top].x == a[i].x) continue;       while (top > 1 && cross(sta[top - 1], a[i], sta[top]) >= 0) top--;       sta[++top] = a[i];     }     for (int i = 1; i <= top; i++)       if (!be[sta[i].id]) be[sta[i].id] = 2;     k = 0;     for (int i = 1; i <= n; i++)       if (be[a[i].id] == 1) que[++k] = a[i];     for (int i = n; i >= 1; i--)       if (be[a[i].id] == 2) que[++k] = a[i];     int cnt = 0, keyw = 0;     for (int i = 1; i <= k; i++)       if (que[i].col != que[(i + k - 2) % k + 1].col) {         cnt++;         keyw = i;       }     if (cnt > 2) return printf( Impossible n ), 0;     if (cnt == 0) {       for (int i = 1; i <= k - 1; i++) ed[++tot] = edge(que[i].id, que[i + 1].id);       point other;       for (int i = 1; i <= n; i++)         if (a[i].col != que[1].col) {           other = a[i];           break;         }       for (int i = 1; i <= k - 1; i++) solve(que[i], que[i + 1], other);       solve(que[k], que[1], other);     } else {       int x = keyw;       for (; que[x].col == que[keyw].col; x = x % k + 1) {         if (que[x].col == que[x % k + 1].col) {           solve(que[x], que[x % k + 1], que[(keyw + k - 2) % k + 1]);           ed[++tot] = edge(que[x].id, que[x % k + 1].id);         }       }       int lst = (x + k - 2) % k + 1;       for (; x != keyw; x = x % k + 1) {         if (que[x].col == que[x % k + 1].col) {           solve(que[x], que[x % k + 1], que[lst]);           ed[++tot] = edge(que[x].id, que[x % k + 1].id);         }       }     }     printf( %d n , tot);     for (int i = 1; i <= tot; i++) printf( %d %d n , ed[i].x - 1, ed[i].y - 1);     return 0;   }