#include <bits/stdc++.h>
using namespace std;
template <class T>
T By(T x, T y, T P) {
  T F1 = 0;
  while (y) {
    if (y & 1) {
      F1 += x;
      if (F1 < 0 || F1 >= P) F1 -= P;
    }
    x <<= 1;
    if (x < 0 || x >= P) x -= P;
    y >>= 1;
  }
  return F1;
}
template <class T>
T Mul(T x, T y, T P) {
  T F1 = 1;
  x %= P;
  while (y) {
    if (y & 1) {
      F1 = By(F1, x, P);
    }
    x = By(x, x, P);
    y >>= 1;
  }
  return F1;
}
template <class T>
T Gcd(T x, T y) {
  if (y == 0) return x;
  T z;
  while (z = x % y) {
    x = y, y = z;
  }
  return y;
}
template <class T>
void UpdateMin(T &x, T y) {
  if (y < x) {
    x = y;
  }
}
template <class T>
void UpdateMax(T &x, T y) {
  if (x < y) {
    x = y;
  }
}
template <class T>
T Sqr(const T x) {
  return x * x;
}
template <class T>
T Abs(const T x) {
  return x < 0 ? -x : x;
}
class ReadBuffer {
  char buff[20000000];
  char *buf;
  void init(int size = 20000000) { fread(buff, 1, size, stdin); }
  template <class T>
  bool readInterger(T &x) {
    x = 0;
    while (*buf && isspace(*buf)) ++buf;
    if (*buf == 0) return false;
    static bool flag;
    flag = 0;
    if (*buf == '-')
      flag = true;
    else
      x = *buf - '0';
    while (isdigit(*++buf)) x = x * 10 + *buf - '0';
    if (flag) x = -x;
    return true;
  }
  template <class T>
  bool readFloat(T &x) {
    long double nowpos = 0.1;
    x = 0;
    while (*buf && isspace(*buf)) ++buf;
    if (*buf == 0) return false;
    static bool flag, decimal;
    decimal = flag = 0;
    if (*buf == '-')
      flag = true, ++buf;
    else if (*buf == '.')
      decimal = true;
    while (isdigit(*buf) || *buf == '.') {
      if (*buf == '.')
        decimal = true;
      else {
        if (decimal) {
          x += nowpos * (*buf - '0');
          nowpos *= 0.1;
        } else {
          x = x * 10 + *buf - '0';
        }
      }
      ++buf;
    }
    return true;
  }
  bool readChar(char c) {
    if (*buf == 0) return 0;
    return c = *buf++, 1;
  }
  bool readString(char *s) {
    while (*buf && isspace(*buf)) ++buf;
    if (!*buf) return false;
    while (!isspace(*buf)) *s++ = *buf++;
    *s++ = 0;
    return true;
  }
  int countSpacetonext() {
    int total = 0;
    while (*buf && *buf == ' ') ++total, ++buf;
    return total;
  }
  bool splitBycharactor(char *s, char Split = '\n') {
    while (*buf && *buf != Split) *s++ = *buf++;
    *s++ = 0;
    return *buf != 0;
  }
};
struct EDGE {
  int T;
  EDGE *Nxt;
  void init(const int _S, const int _T);
} * V[100001 * 4], E[100001 * 4], *PE = E;
void EDGE::init(const int _S, const int _T) {
  T = _T, Nxt = V[_S], V[_S] = this;
}
int D[100001 * 4];
int n, m;
pair<int, int> P[100001];
queue<int> Q;
vector<int> ans;
int main() {
  cin >> n >> m;
  int newnode = m + 1;
  for (int i = 1; i <= (n); ++i) {
    int x;
    for (int j = 1; j <= (m); ++j) {
      cin >> x;
      P[j] = make_pair(x, j);
    }
    sort(P + 1, P + m + 1);
    for (int j = 1; j <= m; ++j) {
      if (P[j].first != -1) {
        int k = j;
        while (k <= m && P[k].first == P[j].first) {
          PE++->init(newnode, P[k].second);
          ++D[P[k].second];
          PE++->init(P[k].second, newnode + 1);
          ++D[newnode + 1];
          ++k;
        }
        ++newnode;
        j = k - 1;
      }
    }
    ++newnode;
  }
  for (int i = 1; i <= (newnode); ++i) {
    if (D[i] == 0) Q.push(i);
  }
  while (!Q.empty()) {
    int i = Q.front();
    if (i <= m) ans.push_back(i);
    Q.pop();
    PE = V[i];
    while (PE) {
      if (--D[PE->T] == 0) Q.push(PE->T);
      PE = PE->Nxt;
    }
  }
  if (int(ans.size()) != m)
    cout << "-1\n";
  else {
    for (int i = 0; i < (m); ++i) {
      cout << ans[i] << (i == m - 1 ? '\n' : ' ');
    }
  }
  cin >> n;
  return 0;
}
