#include <bits/stdc++.h>
#define endl '\n';
#define fastio ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int INF=1e9;
int dx[]={0,-1,1,0,0}, dy[]={0,0,0,-1,1};
map<int,pii> num; // 구슬의 와 위치를 저장

void move(vector<vector<int>>& v, vector<vector<int>>& v2) {
    // 구슬의 이동
    int x=v.size()/2, y=v.size()/2-1;
    for(auto [idx, spot] : num) {
        auto [x,y]=spot;
        if(!idx) continue;
        if(!v[x][y]) {
            bool flag=0;
            for(int i=idx+1;i<v.size()*v.size();i++) {
                int nx=num[i].first, ny=num[i].second;
                if(v[nx][ny]) {
                    swap(v[x][y],v[nx][ny]);
                    flag=1;
                    break;
                }
            }
            if(!flag) return;
        }
    }
}

int explode(vector<vector<int>>& v) {
    // 4개 이상의 연속된 구슬이 있는 경우 폭발
    vector<int> t(4);
    for(int i=1;i<v.size()*v.size();i++) {
        int target=v[num[i].first][num[i].second], cnt=1;
        if(!target) continue;
        for(int j=i+1;j<v.size()*v.size();j++) {
            if(target==v[num[j].first][num[j].second]) cnt++;
            else break;
        }
        if(cnt>=4) {
            for(int j=i;j<i+cnt;j++)
                if(target==v[num[j].first][num[j].second])
                    v[num[j].first][num[j].second]=0;
            t[target]+=cnt;
        }
    }
    return t[1]+t[2]*2+t[3]*3;
}

vector<vector<int>> make_bids(vector<vector<int>>& v) {
    // 구슬 변화 함수, 새로운 공간에 저장하여 리턴
    vector<vector<int>> temp(v.size(),vector<int>(v.size()));
    vector<vector<int>> visit(v.size(),vector<int>(v.size()));
    int iidx=1;
    for(int i=1;i<v.size()*v.size();i++) {
        if(visit[num[i].first][num[i].second]) continue;
        int target=v[num[i].first][num[i].second], cnt=1;
        visit[num[i].first][num[i].second]=1;
        if(!target) continue;
        // 연속적인 구슬의 번호와 개수 카운트
        for(int j=i+1;j<v.size()*v.size();j++) {
            if(target==v[num[j].first][num[j].second])
                cnt++, visit[num[j].first][num[j].second]=1;
            else break;
        }
        // 배열 크기를 넘어가지 않을 때까지 새로운 공간에 구슬 배치
        if(iidx<v.size()*v.size())
            temp[num[iidx].first][num[iidx].second]=cnt;
        if(iidx+1<v.size()*v.size())
            temp[num[iidx+1].first][num[iidx+1].second]=target;
        iidx+=2;
    }
    return temp;
}

int main(){
    fastio
    //freopen("input.txt","r",stdin);
    int n,m; cin>>n>>m;
    vector<vector<int>> v(n,vector<int>(n));
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>v[i][j];
    int sx=n/2, sy=n/2;
    vector<vector<int>> v2(n,vector<int>(n));
    int x=n/2,y=n/2,idx=0;
    v2[x][y]=idx;
    num[idx]={x,y};
    int dir[4]={3,2,4,1}, dist=1, didx=0;
    // 구슬마다 인덱스 저장
    while(idx!=n*n) {
        for(int i=0;i<2;i++) {
            if(idx==n*n) break;
            for(int j=0;j<dist;j++) {
                idx++;
                if(idx==n*n) break;
                int nx=x+dx[dir[didx]], ny=y+dy[dir[didx]];
                v2[nx][ny]=idx;
                num[idx]={nx,ny};
                x=nx, y=ny;
            }
            didx++;
            didx%=4;
        }
        dist++;
    }
    int ans=0;
    while(m--) {
        // 블리자드 마법의 방향과 거리를 입력받고 시뮬레이션
        int a,b; cin>>a>>b;
        // 구슬 파괴
        for(int k=1;k<=b;k++) {
            int nx=sx+dx[a]*k, ny=sy+dy[a]*k;
            if(nx>=0 && nx<n && ny>=0 && ny<n) v[nx][ny]=0;
        }
        // 구슬 이동
        move(v,v2);
        // 구슬 폭발 후 이동을 변화가 없을 때까지 반복
        int ret=explode(v);
        move(v,v2);
        ans+=ret;
        while(ret!=0) {
            ret=explode(v);
            ans+=ret;
            move(v,v2);
        }
        // 구슬 
        v=make_bids(v);
    }
    cout<<ans;
    return 0;
}