#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
void fastscan(int &number) {
  bool negative = false;
  register int c;
  number = 0;
  c = getchar();
  if (c == '-') {
    negative = true;
    c = getchar();
  }
  for (; (c > 47 && c < 58); c = getchar()) number = number * 10 + c - 48;
  if (negative) number *= -1;
}
vector<int> con[16];
vector<pair<int, pair<int, int> > > moves[(1 << 16)];
long long su[16];
int DP[(1 << 16)], DP2[(1 << 16)], previ[(1 << 16)];
int N, M, K;
void solve() {
  cin >> K;
  map<long long, int> rev;
  long long sum = 0ll;
  int x, y;
  for (int i = 0; i < K; i++) {
    cin >> x;
    for (int j = 0; j < x; j++) {
      cin >> y;
      con[i].push_back(y);
      su[i] += y;
      rev[y] = i + 1;
      sum += y;
    }
  }
  if (sum % K != 0) {
    cout << "NO" << endl;
    return;
  }
  sum /= K;
  for (int i = 0; i < K; i++) {
    for (int j = 0; j < con[i].size(); j++) {
      long long necessary = sum - (su[i] - con[i][j]);
      int cur = (1 << i);
      int p = i;
      map<int, bool> vis;
      vector<pair<int, pair<int, int> > > vc;
      vis[i] = true;
      bool flag = false;
      while (rev[necessary] > 0) {
        flag = true;
        if (necessary == con[i][j]) {
          vc.push_back(
              pair<int, pair<int, int> >(i, pair<int, int>(con[i][j], p)));
          break;
        }
        if (vis[rev[necessary] - 1]) {
          flag = false;
          break;
        }
        vis[rev[necessary] - 1] = true;
        vc.push_back(pair<int, pair<int, int> >(rev[necessary] - 1,
                                                pair<int, int>(necessary, p)));
        cur = (cur | (1 << (rev[necessary] - 1)));
        p = rev[necessary] - 1;
        necessary = sum - (su[rev[necessary] - 1] - necessary);
        flag = false;
      }
      if (flag) {
        DP[cur] = true;
        moves[cur].clear();
        for (int i = 0; i < vc.size(); i++) moves[cur].push_back(vc[i]);
      }
    }
  }
  DP2[0] = true;
  for (int i = 0; i < (1 << K); i++) {
    if (!DP2[i]) continue;
    vector<int> zeros;
    for (int j = 0; j < K; j++) {
      if (!(i & (1 << j))) zeros.push_back(j);
    }
    for (int j = 0; j < (1 << zeros.size()); j++) {
      int cur = 0;
      for (int k = 0; k < zeros.size(); k++) {
        if (j & (1 << k)) {
          cur = (cur | (1 << zeros[k]));
        }
      }
      if (DP[cur]) {
        DP2[i + cur] = true;
        previ[i + cur] = cur;
      }
    }
  }
  if (DP2[(1 << K) - 1]) {
    cout << "YES" << endl;
    vector<pair<int, pair<int, int> > > vc;
    int c = (1 << K) - 1;
    while (c > 0) {
      for (int i = 0; i < moves[previ[c]].size(); i++)
        vc.push_back(moves[previ[c]][i]);
      c -= previ[c];
    }
    sort(vc.begin(), vc.end());
    for (int i = 0; i < vc.size(); i++)
      cout << vc[i].second.first << " " << (vc[i].second.second + 1) << endl;
  } else {
    cout << "NO" << endl;
  }
}
int main() {
  int T;
  T = 1;
  for (int i = 0; i < T; i++) solve();
  return (0);
}
