#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>

using namespace std;

typedef long long LL;

int n;
LL a[505][505];
LL b[1005][1005];

int q;
LL A[100005];
LL B[100005];
LL C[100005];
LL from[100005];
LL dest[100005];

int cnt = 0;
int idx[1005][1005];
int par[505 * 505];
int lvl[505 * 505];
LL sum[505 * 505];

int parent(int x) {
    return par[x] == -1 ? x : par[x] = parent(par[x]);
}

void Union(int a, int b) {
    int pa = parent(a);
    int pb = parent(b);
    if (pa == pb) return;
    if (lvl[pa] >= lvl[pb]) {
        lvl[pa] += lvl[pb];
        par[pb] = pa;
        sum[pa] += sum[pb];
    } else {
        lvl[pb] += lvl[pa];
        par[pa] = pb;
        sum[pb] += sum[pa];
    }
}

int mark[1005][1005];

int nxt = 0;
LL res[100005];

int am = 1;
map<LL, int> M;
vector<LL> V;

LL s[350005];

void update(int x, LL by) {
    for (int i = x; i < 350005; i += i & -i)
        s[i] += by;
}

LL getSum(int x) {
    LL res = 0;
    for (int i = x; i > 0; i -= i & -i)
        res += s[i];
    return res;
}

int t0[505];
int t1[505];
int t2[505];
int t3[505];

void go(int r, int c) {
    if (mark[r][c]) return;
    mark[r][c] = true;
    if (r > 0 && b[r - 1][c] == -1) {
        go(r - 2, c);
        Union(idx[r][c], idx[r - 2][c]);
    }
    if (r < 2 * n - 2 && b[r + 1][c] == -1) {
        go(r + 2, c);
        Union(idx[r][c], idx[r + 2][c]);
    }
    if (c > 0 && b[r][c - 1] == -1) {
        go(r, c - 2);
        Union(idx[r][c], idx[r][c - 2]);
    }
    if (c < 2 * n - 2 && b[r][c + 1] == -1) {
        go(r, c + 2);
        Union(idx[r][c], idx[r][c + 2]);
    }
}

int main() {
    freopen("mrvice.in", "r", stdin);
    freopen("mrvice.out", "w", stdout);
    memset(b, -1, sizeof(b));
    scanf("%d%d", &n, &q);
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j) {
            scanf("%lld", &a[i][j]);
            b[2 * i][2 * j] = a[i][j];
        }
    for (int i = 0; i < 2 * n; ++i) {
        t0[i] = 0;
        t1[i] = 2 * n - 2;
        t2[i] = 2 * n - 2;
        t3[i] = 0;
    }
    for (int i = 0; i < q; ++i) {
        scanf("%lld%lld%lld", &A[i], &B[i], &C[i]);
        if (A[i] == 1) {
            --C[i];
            if (B[i] == 0) {
                int c = 2 * C[i] + 1;
                int r = t0[c];
                while (r < 2 * n && b[r][c] == -2) ++r;
                t0[c] = r;
                from[i] = r;
                while (r < 2 * n) {
                    if (b[r][c] == -2) break;
                    b[r][c] = -2;
                    ++r;
                }
                dest[i] = r;
            } else if (B[i] == 1) {
                int r = 2 * C[i] + 1;
                int c = t1[r];
                while (c >= 0 && b[r][c] == -2) --c;
                t1[r] = c;
                from[i] = c;
                while (c >= 0) {
                    if (b[r][c] == -2) break;
                    b[r][c] = -2;
                    --c;
                }
                dest[i] = c;
            } else if (B[i] == 2) {
                int c = 2 * C[i] + 1;
                int r = t2[c];
                while (r >= 0 && b[r][c] == -2) --r;
                t2[c] = r;
                from[i] = r;
                while (r >= 0) {
                    if (b[r][c] == -2) break;
                    b[r][c] = -2;
                    --r;
                }
                dest[i] = r;
            } else {
                int r = 2 * C[i] + 1;
                int c = t3[r];
                while (c < 2 * n && b[r][c] == -2) ++c;
                t3[r] = c;
                from[i] = c;
                while (c < 2 * n) {
                    if (b[r][c] == -2) break;
                    b[r][c] = -2;
                    ++c;
                }
                dest[i] = c;
            }
        }
    }
    {
        V.clear();
        memset(mark, 0, sizeof(mark));
        memset(par, -1, sizeof(par));
        memset(lvl, 0, sizeof(lvl));
        for (int i = 0; i < 2 * n; i += 2)
            for (int j = 0; j < 2 * n; j += 2) {
                idx[i][j] = cnt;
                sum[cnt] = b[i][j];
                ++cnt;
            }
        for (int i = 0; i < 2 * n; i += 2)
            for (int j = 0; j < 2 * n; j += 2)
                if (!mark[i][j]) {
                    go(i, j);
                }
        for (int i = 0; i < cnt; ++i)
            if (par[i] == -1)
                V.push_back(sum[i]);
        for (int t = q - 1; t >= 0; --t) {
            if (A[t] == 1) {
                int r, c;
                if (B[t] == 0) {
                    r = from[t];
                    c = 2 * C[t] + 1;
                    if (r < 0 || r >= 2 * n) continue;
                    Union(idx[r][c - 1], idx[r][c + 1]);
                    V.push_back(sum[parent(idx[r][c - 1])]);
                } else if (B[t] == 1) {
                    r = 2 * C[t] + 1;
                    c = from[t];
                    if (c < 0 || c >= 2 * n) continue;
                    Union(idx[r - 1][c], idx[r + 1][c]);
                    V.push_back(sum[parent(idx[r - 1][c])]);
                } else if (B[t] == 2) {
                    r = from[t];
                    c = 2 * C[t] + 1;
                    if (r < 0 || r >= 2 * n) continue;
                    Union(idx[r][c - 1], idx[r][c + 1]);
                    V.push_back(sum[parent(idx[r][c - 1])]);
                } else {
                    r = 2 * C[t] + 1;
                    c = from[t];
                    if (c < 0 || c >= 2 * n) continue;
                    Union(idx[r - 1][c], idx[r + 1][c]);
                    V.push_back(sum[parent(idx[r - 1][c])]);
                }
            } else {
                V.push_back(B[t]);
                V.push_back(C[t]);
            }
        }
        sort(V.begin(), V.end());
        for (int i = 0; i < V.size(); ++i)
            if (!M.count(V[i]))
                M[V[i]] = am++;
    }
    {
        cnt = 0;
        memset(s, 0, sizeof(s));
        memset(mark, 0, sizeof(mark));
        memset(par, -1, sizeof(par));
        memset(lvl, 0, sizeof(lvl));
        for (int i = 0; i < 2 * n; i += 2)
            for (int j = 0; j < 2 * n; j += 2) {
                idx[i][j] = cnt;
                sum[cnt] = b[i][j];
                ++cnt;
            }
        for (int i = 0; i < 2 * n; i += 2)
            for (int j = 0; j < 2 * n; j += 2)
                if (!mark[i][j]) {
                    go(i, j);
                }
        for (int i = 0; i < cnt; ++i)
            if (par[i] == -1)
                update(M[sum[i]], 1);
        for (int t = q - 1; t >= 0; --t) {
            if (A[t] == 1) {
                int r, c;
                if (B[t] == 0) {
                    r = from[t];
                    c = 2 * C[t] + 1;
                    if (r < 0 || r >= n) continue;
                    update(M[sum[parent(idx[r][c - 1])]], -1);
                    update(M[sum[parent(idx[r][c + 1])]], -1);
                    Union(idx[r][c - 1], idx[r][c + 1]);
                    update(M[sum[parent(idx[r][c - 1])]], 1);
                } else if (B[t] == 1) {
                    r = 2 * C[t] + 1;
                    c = from[t];
                    if (c < 0 || c >= n) continue;
                    update(M[sum[parent(idx[r - 1][c])]], -1);
                    update(M[sum[parent(idx[r + 1][c])]], -1);
                    Union(idx[r - 1][c], idx[r + 1][c]);
                    update(M[sum[parent(idx[r - 1][c])]], 1);
                } else if (B[t] == 2) {
                    r = from[t];
                    c = 2 * C[t] + 1;
                    if (r < 0 || r >= n) continue;
                    update(M[sum[parent(idx[r][c - 1])]], -1);
                    update(M[sum[parent(idx[r][c + 1])]], -1);
                    Union(idx[r][c - 1], idx[r][c + 1]);
                    update(M[sum[parent(idx[r][c - 1])]], 1);
                } else {
                    r = 2 * C[t] + 1;
                    c = from[t];
                    if (c < 0 || c >= n) continue;
                    update(M[sum[parent(idx[r - 1][c])]], -1);
                    update(M[sum[parent(idx[r + 1][c])]], -1);
                    Union(idx[r - 1][c], idx[r + 1][c]);
                    update(M[sum[parent(idx[r - 1][c])]], 1);
                }
            } else {
                res[nxt] = getSum(M[C[t]]) - getSum(M[B[t]] - 1);
                ++nxt;
            }
        }
    }
    for (int i = nxt - 1; i >= 0; --i)
        printf("%lld\n", res[i]);
    return 0;
}
