#include <bits/stdc++.h>
using namespace std;
int N;
vector<int> G[1205];
pair<int, int> X[1205];
bool Exist[1205], A[1205][1205];
int Nb[1205], Max[1205], Map[1205][1205], Cnt[2][1205], Need[1205], nb;
pair<int, int> Inv[1205 * 1205];
int Res[1205], m;
int C[1205][1205], F[1205][1205], TT[1205], Use[1205];
char S[1205];
bool V[1205];
bool ok = 1;
int sink, res;
void Read() {
  cin >> N;
  cin.get();
  for (int i = 1; i <= N; i++) {
    cin.getline(S, 20);
    int val = 0;
    bool after = 0;
    for (int j = 0; S[j] != 0; j++) {
      if (S[j] >= '0' && S[j] <= '9') val = val * 10 + S[j] - '0';
      if (S[j] == ' ') {
        X[i].first = val;
        val = 0;
        while (S[j] == ' ') ++j;
        j--;
      }
      if (S[j] == '?') val = -1;
    }
    X[i].second = val;
  }
}
void buildG(int pos) {
  m = 0;
  for (int i = 1; i <= N; i++) {
    if (X[i].second == -1) m = max(m, X[i].first);
    if (X[i].second >= 0) Exist[X[i].second] = 1;
    if (X[i].second > 0 && X[i].first == 0) Nb[X[i].second]++;
    if (X[i].second > 0) {
      Max[X[i].second] = max(Max[X[i].second], X[i].first);
      if (X[i].first >= 0) A[X[i].second][X[i].first] = 1;
    }
  }
  if (Exist[pos] == 0 && pos > 1) {
    ok = 0;
    return;
  }
  Exist[pos] = 1;
  Max[pos] = max(Max[pos], m);
  int cnt = 0, aux = 0;
  for (int i = 1; i <= N; i++) {
    if (Exist[i] == 1) {
      int rem = Nb[i] % i;
      if (rem == 0 && Nb[i] > 0)
        Need[i] = 0;
      else
        Need[i] = i - rem;
    }
    int x = X[i].first, y = X[i].second;
    if (x == -1 && y > 0) Cnt[1][y]++;
    if (x >= 0 && y == -1) Cnt[0][x]++;
    if (x == -1 && y == -1) nb++;
  }
  sink = 3 * N;
  for (int i = 1; i <= N; i++) {
    if (Exist[i] == 0) continue;
    for (int j = 1; j <= Max[i]; j++)
      if (A[i][j] == 0) {
        Map[j][i] = ++aux;
        if (aux >= 3 * N) {
          ok = 0;
          return;
        }
        Inv[aux] = make_pair(j, i);
        G[sink].push_back(aux);
        G[aux].push_back(sink);
        C[aux][sink] = 1;
        C[sink][aux] = 0;
        F[aux][sink] = 0;
        F[sink][aux] = 0;
        res++;
      }
    if (Need[i] > 0) {
      int j = 0;
      Map[j][i] = ++aux;
      if (aux >= 3 * N) {
        ok = 0;
        return;
      }
      Inv[aux] = make_pair(j, i);
      G[sink].push_back(aux);
      G[aux].push_back(sink);
      C[aux][sink] = Need[i];
      C[sink][aux] = 0;
      F[aux][sink] = 0;
      F[sink][aux] = 0;
      res += Need[i];
    }
  }
  if (aux >= 3 * N) {
    ok = 0;
    return;
  }
  int last = aux;
  for (int i = 0; i <= N; i++) {
    if (Cnt[0][i] > 0) {
      Map[i][N + 3] = ++aux;
      if (aux >= 3 * N) {
        ok = 0;
        return;
      }
      Inv[aux] = make_pair(i, N + 3);
      C[0][aux] = Cnt[0][i];
      C[aux][0] = 0;
      G[0].push_back(aux);
      G[aux].push_back(0);
      F[0][aux] = F[aux][0] = 0;
      for (int j = 1; j <= last; j++) {
        int x = Inv[j].first, y = Inv[j].second;
        if (x != i) continue;
        C[aux][j] = 1000000;
        C[j][aux] = 0;
        F[aux][j] = F[j][aux] = 0;
        G[aux].push_back(j);
        G[j].push_back(aux);
      }
    }
    if (Cnt[1][i] > 0) {
      Map[N + 3][i] = ++aux;
      if (aux >= 3 * N) {
        ok = 0;
        return;
      }
      Inv[aux] = make_pair(N + 3, i);
      C[0][aux] = Cnt[1][i];
      C[aux][0] = 0;
      G[0].push_back(aux);
      G[aux].push_back(0);
      F[0][aux] = F[aux][0] = 0;
      for (int j = 1; j <= last; j++) {
        int x = Inv[j].first, y = Inv[j].second;
        if (y != i) continue;
        C[aux][j] = 1000000;
        C[j][aux] = 0;
        F[aux][j] = F[j][aux] = 0;
        G[aux].push_back(j);
        G[j].push_back(aux);
      }
    }
  }
  if (nb > 0) {
    Map[N + 3][N + 3] = ++aux;
    if (aux >= 3 * N) {
      ok = 0;
      return;
    }
    Inv[aux] = make_pair(N + 3, N + 3);
    C[0][aux] = nb;
    C[aux][0] = 0;
    G[0].push_back(aux);
    G[aux].push_back(0);
    F[0][aux] = F[aux][0] = 0;
    for (int j = 1; j <= last; j++) {
      int x = Inv[j].first, y = Inv[j].second;
      C[aux][j] = 1000000;
      C[j][aux] = 0;
      F[aux][j] = F[j][aux] = 0;
      G[aux].push_back(j);
      G[j].push_back(aux);
    }
  }
  if (aux >= 3 * N) {
    ok = 0;
    return;
  }
}
bool BFS(int node) {
  for (int i = 1; i <= sink; i++) TT[i] = -1, Use[i] = 0;
  queue<int> Q;
  Q.push(node);
  Use[node] = 1;
  while (!Q.empty()) {
    int node = Q.front();
    Q.pop();
    if (node == sink) continue;
    for (int i = 0; i < G[node].size(); i++) {
      int neighb = G[node][i];
      if (Use[neighb] == 0 && C[node][neighb] - F[node][neighb] > 0) {
        Use[neighb] = 1;
        TT[neighb] = node;
        Q.push(neighb);
      }
    }
  }
  return Use[sink] == 1;
}
void maxFlow() {
  int maxF = 0;
  while (BFS(0)) {
    for (int i = 0; i < G[sink].size(); i++) {
      int neighb = G[sink][i];
      if (Use[neighb] == 0 || C[neighb][sink] - F[neighb][sink] == 0) continue;
      TT[sink] = neighb;
      int fmin = 1000000;
      for (int i = sink; i != 0; i = TT[i])
        fmin = min(fmin, C[TT[i]][i] - F[TT[i]][i]);
      maxF += fmin;
      for (int i = sink; i != 0; i = TT[i]) {
        F[TT[i]][i] += fmin;
        F[i][TT[i]] -= fmin;
      }
    }
  }
  if (maxF != res) {
    ok = 0;
  }
}
void getSolution() {
  for (int i = 1; i <= N; i++) {
    int x = X[i].first, y = X[i].second;
    if (x != -1 && y != -1) continue;
    if (x == -1) x = N + 3;
    if (y == -1) y = N + 3;
    int node = Map[x][y];
    for (int j = 0; j < G[node].size(); j++) {
      int neighb = G[node][j];
      if (F[node][neighb] > 0) {
        --F[node][neighb];
        X[i] = Inv[neighb];
        break;
      }
    }
    if (X[i].first != -1 && X[i].second != -1) continue;
    if (X[i].first == -1 && X[i].second == -1)
      X[i] = make_pair(0, 1);
    else {
      if (X[i].first == -1)
        X[i].first = 1;
      else {
        if (X[i].first == 0)
          X[i].second = 1;
        else
          for (int j = 1; j <= N; j++) {
            if (Exist[j] == 1 && Max[j] >= X[i].first) X[i].second = j;
          }
      }
    }
  }
}
void Solve() {
  for (int i = 1; i <= N; i++) {
    if (X[i].first != 0 || V[X[i].second] == 1) continue;
    V[X[i].second] = 1;
    vector<int> V;
    V.push_back(i);
    for (int j = i + 1; j <= N; j++)
      if (X[j].second == X[i].second && X[j].first == 0) V.push_back(j);
    for (int j = 0; j < V.size(); j += X[i].second) {
      for (int k = j; k < j + X[i].second && k < V.size(); k++) {
        if (k < j + X[i].second - 1)
          Res[V[k]] = V[k + 1];
        else
          Res[V[k]] = V[j];
      }
    }
  }
  for (int i = 1; i <= N; i++) {
    if (X[i].first == 0) continue;
    for (int j = 1; j <= N; j++)
      if (X[i].first == X[j].first + 1 && X[i].second == X[j].second)
        Res[i] = j;
  }
}
int main() {
  Read();
  bool exist = 0;
  for (int i = 1; i <= N; i++) {
    ok = 1;
    res = 0;
    nb = 0;
    for (int j = 0; j <= N * 3; j++) G[j].clear();
    for (int j = 0; j <= N; j++) {
      Max[j] = 0;
      Nb[j] = 0;
      Need[j] = 0;
      Cnt[0][j] = Cnt[1][j] = 0;
      Exist[j] = 0;
      for (int k = 0; k <= N; k++) A[j][k] = 0;
    }
    buildG(i);
    if (ok == 0) {
      continue;
    }
    maxFlow();
    if (ok == 0) {
      continue;
    }
    getSolution();
    Solve();
    for (int i = 1; i <= N; i++) cout << Res[i] << " ";
    cout << "\n";
    return 0;
  }
  cout << "-1\n";
  return 0;
}
