#include <bits/stdc++.h>
using namespace std;
int ri() {
  int x;
  if (scanf(" %d", &x) == EOF) return -1;
  return x;
}
long long int rl() {
  long long int x;
  if (cin >> x) return x;
  return -1;
}
string rs() {
  string s;
  if (cin >> s) return s;
  return "";
}
template <size_t M>
int getTableInverse(long long x) {
  static vector<int> inv;
  if (!inv.empty()) return inv[x];
  inv = vector<int>(M, 0);
  inv[1] = 1;
  for (int i = 2; i < M; ++i) inv[i] = (M - (M / i) * inv[M % i] % M) % M;
  return inv[x];
}
template <size_t MOD, size_t INV_LIMIT>
struct ModInt {
  static const long long mod = MOD;
  long long x;

 public:
  inline ModInt() : ModInt(0) {}
  inline ModInt(long long _x) {
    x = _x;
    normalize();
  }
  ModInt<MOD, INV_LIMIT> inverse() const {
    if (MOD <= INV_LIMIT) return getTableInverse<MOD>(x);
    long long P, Q;
    euclideanInverse(x, mod, P, Q);
    return P;
  }
  bool hasInverse() const { return gcd(x, mod) == 1; }
  inline ModInt<MOD, INV_LIMIT>& operator+=(
      const ModInt<MOD, INV_LIMIT>& that) {
    x += that.x;
    if (x >= mod) x -= mod;
    return *this;
  }
  inline ModInt<MOD, INV_LIMIT>& operator-=(
      const ModInt<MOD, INV_LIMIT>& that) {
    x -= that.x;
    if (x < 0) x += mod;
    return *this;
  }
  inline ModInt<MOD, INV_LIMIT>& operator*=(
      const ModInt<MOD, INV_LIMIT>& that) {
    x = x * that.x % mod;
    return *this;
  }
  inline ModInt<MOD, INV_LIMIT>& operator/=(
      const ModInt<MOD, INV_LIMIT>& that) {
    x = that.inverse().x * x % mod;
    return *this;
  }
  inline ModInt<MOD, INV_LIMIT>& operator++() {
    (*this) += 1;
    return *this;
  }
  inline ModInt<MOD, INV_LIMIT>& operator++(int) {
    (*this) += 1;
    return *this;
  }
  inline ModInt<MOD, INV_LIMIT>& operator--() {
    (*this) -= 1;
    return *this;
  }
  inline ModInt<MOD, INV_LIMIT>& operator--(int) {
    (*this) -= 1;
    return *this;
  }
  template <size_t M, size_t I>
  friend ostream& operator<<(ostream& os, const ModInt<M, I>& that);

 private:
  long long gcd(long long a, long long b) const {
    return (a == 0) ? b : gcd(b % a, a);
  }
  inline void normalize() {
    if (x < 0 | x >= mod) x %= mod;
    if (x < 0) x += mod;
  }
  long long euclideanInverse(long long a, long long b, long long& X,
                             long long& Y) const {
    if (a == 0) {
      X = 1;
      Y = 1;
      return b;
    }
    long long g = euclideanInverse(b % a, a, X, Y);
    long long t = Y;
    Y = X;
    X = t - X * (b / a);
    return g;
  }
};
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ostream& operator<<(ostream& os,
                           const ModInt<MOD, INV_TABLE_LIMIT>& that) {
  os << that.x;
  return os;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator+(
    ModInt<MOD, INV_TABLE_LIMIT> A, const ModInt<MOD, INV_TABLE_LIMIT>& B) {
  return A.x + B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator+(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              long long b) {
  return A.x + b;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator+(long long a,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return a + B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator-(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return A.x - B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator-(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              long long b) {
  return A.x - b;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator-(long long a,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return a - B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator*(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return A.x * B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator*(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              long long b) {
  return A.x * b;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator*(long long a,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return a * B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator/(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return A.x * B.inverse().x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator/(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              long long b) {
  return A.x * ModInt<MOD, INV_TABLE_LIMIT>(b).inverse().x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator/(long long a,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return a * B.inverse().x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator%(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return A.x % B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator%(ModInt<MOD, INV_TABLE_LIMIT> A,
                                              long long b) {
  return A.x % b;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline ModInt<MOD, INV_TABLE_LIMIT> operator%(long long a,
                                              ModInt<MOD, INV_TABLE_LIMIT> B) {
  return a % B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline bool operator==(ModInt<MOD, INV_TABLE_LIMIT> A,
                       ModInt<MOD, INV_TABLE_LIMIT> B) {
  return A.x == B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline bool operator==(ModInt<MOD, INV_TABLE_LIMIT> A, long long b) {
  return A.x == ModInt<MOD, INV_TABLE_LIMIT>(b).x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline bool operator==(long long a, ModInt<MOD, INV_TABLE_LIMIT> B) {
  return ModInt<MOD, INV_TABLE_LIMIT>(a).x == B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline bool operator!=(ModInt<MOD, INV_TABLE_LIMIT> A,
                       ModInt<MOD, INV_TABLE_LIMIT> B) {
  return A.x != B.x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline bool operator!=(ModInt<MOD, INV_TABLE_LIMIT> A, long long b) {
  return A.x != ModInt<MOD, INV_TABLE_LIMIT>(b).x;
}
template <size_t MOD, size_t INV_TABLE_LIMIT>
inline bool operator!=(long long a, ModInt<MOD, INV_TABLE_LIMIT> B) {
  return ModInt<MOD, INV_TABLE_LIMIT>(a) != B.x;
}
const int PRIME = 998244353;
const int maxPresents = 1000000;
struct SingleCase {
  bool solveCase() {
    long long int n = ri();
    if (n < 0) return false;
    vector<int> inDegree(maxPresents, 0);
    vector<vector<int> > edges(n);
    for (int i = 0; i < n; ++i) {
      int k = ri();
      for (int j = 0; j < k; ++j) {
        int l = ri() - 1;
        edges[i].push_back(l);
        inDegree[l]++;
      }
    }
    ModInt<PRIME, 0> ret = 0;
    for (int i = 0; i < n; ++i) {
      long long int k = edges[i].size();
      ModInt<PRIME, 0> x = 0;
      for (auto p : edges[i]) x += inDegree[p];
      ret += x / n / k;
    }
    ret /= n;
    cout << ret << endl;
    return true;
  }
};
int main() {
  while (SingleCase().solveCase()) {
  };
  return 0;
}
