#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
bool Max(T1& a, T2 b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T1, typename T2>
bool Min(T1& a, T2 b) {
  return a > b ? a = b, 1 : 0;
}
const int N = 100021, inf = 1e9;
pair<int, int> a[N][12];
bitset<4096> bit[N];
void solve() {
  int n, k, q;
  cin >> n >> k >> q;
  for (int i = 0; i < (k); ++i)
    for (int j = 0; j < (n); ++j) {
      cin >> a[j][i].first;
      a[j][i].second = i;
    }
  for (int j = 0; j < (n); ++j) sort(a[j], a[j] + k);
  for (int i = 0; i < (k); ++i) {
    for (int j = 0; j < (1 << k); ++j) bit[i][j] = j >> i & 1;
  }
  int tot = k;
  while (q--) {
    int t, x, y;
    cin >> t >> x >> y;
    x--, y--;
    if (t == 1)
      bit[tot++] = bit[x] & bit[y];
    else if (t == 2)
      bit[tot++] = bit[x] | bit[y];
    else {
      int cur = 0;
      for (int i = 0; i < (k); ++i) {
        cur |= 1 << a[y][i].second;
        if (bit[x][cur]) {
          cout << a[y][i].first << '\n';
          break;
        }
      }
    }
  }
}
void init() {}
int main(void) {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(20);
  init();
  int TC = 1;
  for (int TI = 1; TI <= (TC); ++TI) {
    solve();
  }
  return 0;
}
