#include <bits/stdc++.h>   using namespace std;   const int MOD = 1e9 + 7;   const int SIZE = 1e6 + 10;   using namespace std;   struct E {     int k, c;     E() {}     E(int _k, int _c) : k(_k), c(_c) {}   } es[4200010];   struct Flow {     int n, m, dis[500010];     int qq[500010], qr, ql;     vector<int> e[500010];     void init(int _n) {       n = _n;       m = 0;       for (int i = 0; i < n; i++) e[i] = vector<int>();     }     void add_edge(int a, int b, int c) {       e[a].push_back(m);       es[m] = E(b, c);       m++;       e[b].push_back(m);       es[m] = E(a, 0);       m++;     }     bool BFS() {       memset(dis, -1, n * sizeof(int));       ql = qr = 0;       qq[qr++] = 0;       dis[0] = 0;       while (ql != qr && dis[n - 1] == -1) {         int p = qq[ql++];         for (__typeof((e[p]).begin()) it = (e[p]).begin(); it != (e[p]).end();              it++) {           E ee = es[*it];           if (ee.c == 0 || dis[ee.k] != -1) continue;           dis[ee.k] = dis[p] + 1;           qq[qr++] = ee.k;         }       }       return dis[n - 1] != -1;     }     long long go(int p, long long c) {       if (p == n - 1) return c;       long long ret = 0, tmp;       for (__typeof((e[p]).begin()) it = (e[p]).begin(); it != (e[p]).end();            it++) {         E &ee = es[*it];         if (ee.c == 0 || dis[p] + 1 != dis[ee.k]) continue;         tmp = go(ee.k, min(c - ret, (long long)ee.c));         ret += tmp;         ee.c -= tmp;         es[(*it) ^ 1].c += tmp;         if (ret == c) break;       }       if (ret == 0) dis[p] = -1;       return ret;     }     long long maxflow() {       long long ret = 0;       while (BFS()) ret += go(0, 1LL << 60);       return ret;     }   } flow;   vector<int> cc[301][301], cn[301];   int need_id, an[301], xx[301], yy[301];   pair<int, int> need[1000001];   int to[301];   bool used[301];   bool match(pair<int, int> X, pair<int, int> Y) {     if (X.first != Y.first && Y.first != -1) return 0;     if (X.second != Y.second && Y.second != -1) return 0;     return 1;   }   void go(int ma_id, int ma_hi, int n) {     if (ma_id != 1 && ((int)(cc[ma_id][0]).size()) == 0) return;     vector<pair<int, int> > qq;     int oo = need_id;     for (int i = ma_hi; i >= 0; i--) {       if (((int)(cc[ma_id][i]).size()) == 0) {         need[++need_id] = make_pair(ma_id, i);         cc[ma_id][i].push_back(-need_id);         qq.push_back(make_pair(ma_id, i));       }     }     if (need_id > n) {       for (int i = 0; i < (((int)(qq).size())); ++i)         cc[qq[i].first][qq[i].second].pop_back();       need_id = oo;       return;     }     flow.init(need_id + n + 2);     for (int i = (1); i < (n + 1); ++i)       flow.add_edge(need_id + i, need_id + n + 1, 1);     for (int i = (1); i < (need_id + 1); ++i) {       flow.add_edge(0, i, 1);       for (int j = (1); j < (n + 1); ++j) {         if (used[j]) continue;         if (match(need[i], make_pair(yy[j], xx[j])))           flow.add_edge(i, need_id + j, 1);       }     }     if (flow.maxflow() != need_id) {       need_id = oo;       return;     }     for (int i = 0; i < flow.m; i += 2) {       if (es[i].k > need_id && es[i + 1].k <= need_id && es[i].c == 0) {         used[es[i].k - need_id] = 1;         to[es[i + 1].k] = es[i].k - need_id;       }     }     for (int i = (1); i < (n + 1); ++i) {       for (int j = 0; j < (n); ++j) {         for (int k = 0; k < (((int)(cc[i][j]).size())); ++k) {           if (cc[i][j][k] < 0) cc[i][j][k] = to[-cc[i][j][k]];         }       }     }     for (int i = (1); i < (n + 1); ++i) {       if (!used[i]) {         used[i] = 1;         if (xx[i] == -1 && yy[i] == -1)           cc[1][0].push_back(i);         else if (yy[i] != -1)           cc[yy[i]][1].push_back(i);         else if (xx[i] != -1) {           if (xx[i] == 0)             cc[1][0].push_back(i);           else             cc[ma_id][xx[i]].push_back(i);         }       }     }     for (int i = (1); i < (n + 1); ++i) {       for (int j = 0; j < (((int)(cc[i][0]).size())); ++j) {         if (j % i == 0)           an[cc[i][0][j]] = cc[i][0][j + i - 1];         else           an[cc[i][0][j]] = cc[i][0][j - 1];       }       for (int j = (1); j < (n); ++j) {         for (int k = 0; k < (((int)(cc[i][j]).size())); ++k)           an[cc[i][j][k]] = cc[i][j - 1][0];       }     }     for (int i = (1); i < (n + 1); ++i) printf( %d%c , an[i],    n [i == n]);     exit(0);   }   int main() {     int(n);     scanf( %d , &n);     int ma_hi = -1;     for (int i = (1); i < (n + 1); ++i) {       char s1[20], s2[20];       scanf( %s , (s1));       scanf( %s , (s2));       int x = -1, y = -1;       if (s1[0] !=  ? ) x = atoi(s1);       if (s2[0] !=  ? ) y = atoi(s2);       if (x != -1 && y != -1) {         cc[y][x].push_back(i);         used[i] = 1;       } else if (y != -1)         cn[y].push_back(i);       xx[i] = x;       yy[i] = y;       ma_hi = max(ma_hi, x);     }     int mi = 10000, ma_id = 1;     for (int i = (1); i < (n + 1); ++i) {       int hi = n - 1;       while (hi >= 0 && ((int)(cc[i][hi]).size()) == 0) hi--;       while (hi >= 0) {         if (!((int)(cc[i][hi]).size())) {           need[++need_id] = make_pair(i, hi);           cc[i][hi].push_back(-need_id);         }         hi--;       }       if (((int)(cn[i]).size()) && ((int)(cc[i][0]).size()) == 0) {         need[++need_id] = make_pair(i, 0);         cc[i][0].push_back(-need_id);       }       while (((int)(cc[i][0]).size()) % i) {         need[++need_id] = make_pair(i, 0);         cc[i][0].push_back(-need_id);       }     }     for (int ker = 1; ker <= n; ker++) {       go(ker, ma_hi, n);     }     return 0 * puts( -1 );   }