#include using namespace std; using ll = long long; #define rep(i, n) for (int i = 0; i < int(n); ++i) struct UnionFind { vector par, sizes; UnionFind(int n) : par(n), sizes(n, 1) { iota(begin(par), end(par), 0); } int root(int x) { if (x == par[x]) return x; return par[x] = root(par[x]); } void unite(int x, int y) { x = root(x); y = root(y); if (x == y) return; if (sizes[x] < sizes[y]) swap(x, y); par[y] = x; sizes[x] += sizes[y]; } bool same(int x, int y) { return root(x) == root(y); } int size(int x) { return sizes[root(x)]; } }; int main() { int n, m, q; cin >> n >> m >> q; vector s(n); rep(i, n) cin >> s[i]; vector> G(n); rep(i, m) { int a, b; cin >> a >> b; a--, b--; G[a].push_back(b); G[b].push_back(a); } UnionFind uf(n * 7); rep(i, n) rep(j, 7) { if (s[i][j] == '0') continue; for (auto to : G[i]) { if (s[to][j] == '1') uf.unite(i * 7 + j, to * 7 + j); } int up = (j + 1) % 7, down = (j - 1 + 7) % 7; if (s[i][up] == '1') uf.unite(i * 7 + j, i * 7 + up); if (s[i][down] == '1') uf.unite(i * 7 + j, i * 7 + down); } rep(qi, q) { int type, x, y; cin >> type >> x >> y; x--, y--; if (type == 1) { s[x][y] = '1'; for (auto to : G[x]) { if (s[to][y] == '1') uf.unite(x * 7 + y, to * 7 + y); } int up = (y + 1) % 7, down = (y - 1 + 7) % 7; if (s[x][up] == '1') uf.unite(x * 7 + y, x * 7 + up); if (s[x][down] == '1') uf.unite(x * 7 + y, x * 7 + down); } else { cout << uf.size(x * 7) << "\n"; } } }