Go: package main

import (
	"fmt"
	"math"
)

type Position struct {
	X int64
	Y int64
}

func (one Position) Distance(another Position) int64 {
	return int64(math.Abs(float64(one.X-another.X)) + math.Abs(float64(one.Y-another.Y)))
}

type PersonPosition struct {
	Takayuki Position
	Kazuyuki Position
}

func (one PersonPosition) Distance() int64 {
	return one.Takayuki.Distance(one.Kazuyuki)
}

type Status struct {
	Person PersonPosition
	Turn   int64
}

type PQStatus []*Status

func (pq PQStatus) Len() int {
	return len(pq)
}
func (pq PQStatus) Less(i, j int) bool {
	if pq[i].Turn == pq[j].Turn {
		return pq[i].Person.Distance() < pq[j].Person.Distance()
	}
	return pq[i].Turn < pq[j].Turn
}

func (pq PQStatus) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PQStatus) Push(x interface{}) {
	item := x.(*Status)
	*pq = append(*pq, item)
}

func (pq *PQStatus) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	*pq = old[0 : n-1]
	return item
}

func solve(h, w int64) {
	var tx, ty, kx, ky int64
	fmt.Scan(&tx, &ty, &kx, &ky)
	tx--
	ty--
	kx--
	ky--
	m := make([][]int64, h)
	for i := range m {
		m[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			fmt.Scan(&m[i][j])
		}
	}
	start := &Status{Person: PersonPosition{Takayuki: Position{X: tx, Y: ty}, Kazuyuki: Position{X: kx, Y: ky}}, Turn: 0}
	pq := make(PQStatus, 0)
	//heap.Init(&pq)
	//heap.Push(&pq, start)
	pq.Push(start)
	dx := []int64{0, 1, 0, -1}
	dy := []int64{1, 0, -1, 0}
	memo := make(map[PersonPosition]int64, 0)
	ans := int64(101)
	for pq.Len() > 0 {
		//now := heap.Pop(&pq).(*Status)
		now := pq.Pop().(*Status)
		if now.Person.Distance() == 0 && ans > now.Turn {
			ans = now.Turn
		}
		if v, ok := memo[now.Person]; ok && v <= now.Turn {
			continue
		}
		memo[now.Person] = now.Turn
		for i := 0; i < 4; i++ {
			next := &Status{}
			*next = *now
			next.Person.Kazuyuki.X += dx[i]
			next.Person.Kazuyuki.Y += dy[i]
			if next.Person.Kazuyuki.X < 0 || next.Person.Kazuyuki.X >= w ||
				next.Person.Kazuyuki.Y < 0 || next.Person.Kazuyuki.Y >= h ||
				m[next.Person.Kazuyuki.Y][next.Person.Kazuyuki.X] == 1 {
				next.Person.Kazuyuki.X -= dx[i]
				next.Person.Kazuyuki.Y -= dy[i]
			}
			next.Person.Takayuki.X -= dx[i]
			next.Person.Takayuki.Y -= dy[i]
			if next.Person.Takayuki.X < 0 || next.Person.Takayuki.X >= w ||
				next.Person.Takayuki.Y < 0 || next.Person.Takayuki.Y >= h ||
				m[next.Person.Takayuki.Y][next.Person.Takayuki.X] == 1 {
				next.Person.Takayuki.X += dx[i]
				next.Person.Takayuki.Y += dy[i]
			}
			next.Turn += 1
			if next.Turn < 100 {
				//heap.Push(&pq, next)
				pq.Push(next)
			}
		}
	}
	if ans == 101 {
		fmt.Println("NA")
	} else {
		fmt.Println(ans)
	}
}

func main() {
	var h, w int64
	for {
		fmt.Scan(&h, &w)
		if h == 0 && w == 0 {
			break
		}
		solve(h, w)
	}
}

C++: #include<iostream>
#include<cstring>
#include<queue>
using namespace std;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define inRange(x,a,b) (a <= x && x < b)

bool visit[50][50][50][50];

int dx[4] = {0,-1,0,1};
int dy[4] = {-1,0,1,0};

typedef pair<pair<int,int>, pair<int,int>> P;

int main(){
    int w, h, tx, ty, hx, hy;
    while(cin >> w >> h, w){
        memset(visit, 0, sizeof(visit));
        cin >> tx >> ty >> hx >> hy;
        tx--, ty--, hx--, hy--;
        
        int mat[h][w];
        rep(i, h) rep(j, w) cin >> mat[i][j];

        queue<pair<P, int>> q;
        q.push({{{ty,tx},{hy,hx}}, 0});

        int ans = -1;
        while(!q.empty()){
            pair<P,int> p = q.front();  q.pop();
            if(p.second > 100)  break;
            int a = p.first.first.first, b = p.first.first.second;
            int c = p.first.second.first, d = p.first.second.second;
            if(a == c && b == d){
                ans = p.second;
                break;
            }
            if(visit[a][b][c][d])   continue;

            visit[a][b][c][d] = true;

            for(int k = 0; k < 4; k++){
                int na = a + dx[k], nb = b + dy[k];
                int nc = c + dx[(k+2)%4], nd = d + dy[(k+2)%4];
                /*
                cout << a << ", " << b << " -> " << na << ", " << nb << endl;
                cout << c << ", " << d << " -> " << nc << ", " << nd << endl;
*/
                if(!inRange(na,0,h) || !inRange(nb,0,w) || mat[na][nb] == 1){
                    na = a, nb = b;
                }
                if(!inRange(nc,0,h) || !inRange(nd,0,w) || mat[nc][nd] == 1){
                    nc = c, nd = d;
                }

                if(!visit[na][nb][nc][nd]){
                    q.push({{{na,nb},{nc,nd}}, p.second+1});
                }
            }
        }

        if(ans == -1)   cout << "NA" << endl;
        else            cout << ans << endl;
    }

    return 0;
}

C++: #include<iostream>
#include<set>
#include<queue>
#include<vector>
#include<sstream>
#include<algorithm>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
#define pb         push_back

class state{
public:
  short cost;
  char x1,y1,x2,y2;
  bool operator<(const state & a)const{
    if (y1 != a.y1)return y1 < a.y1;
    if (x1 != a.x1)return x1 < a.x1;
    if (x2 != a.x2)return x2 < a.x2;
    if (y2 != a.y2)return y2 < a.y2;
    return false;
  }
};

//bool vis[50][50][50][50];
bool m[100][100];

char dx[] ={0,0,1,-1};
char dy[] ={1,-1,0,0};
char dx2[]={0,0,-1,1};
char dy2[]={-1,1,0,0};

void bfs(int r,int c,char sy,char sx,char gy,char gx){
  set<state> S;
  queue<state> Q;
  S.insert((state){0,sy,sx,gy,gx});
  Q.push((state){0,sy,sx,gy,gx});
  while(!Q.empty()){
    state now = Q.front();Q.pop();
    if (now.cost >= 100)break;
    if (now.x1==now.x2 && now.y1==now.y2){
      cout << now.cost << endl;
      return;
    }

    rep(i,4){
      char nex =now.x1+dx[i] ,ney =now.y1+dy[i];
      char nnex=now.x2+dx2[i],nney=now.y2+dy2[i];
      if (nex ==-1||ney==-1 ||nex==c ||ney==r ||m[ney][nex]){
	nex=now.x1;
	ney=now.y1;
      }
      if (nnex==-1||nney==-1||nnex==c||nney==r||m[nney][nnex]){
	nnex=now.x2;
	nney=now.y2;
      }
      
      //      if (vis[ney][nex][nney][nnex]){
      //	continue;
      //      }
      //      vis[ney][nex][nney][nnex]=true;
      state next=(state){now.cost+1,ney,nex,nney,nnex};
      //Q.push((state){now.cost+1,ney,nex,nney,nnex});
      if (S.find(next) == S.end()){
	S.insert(next);
	Q.push(next);
      }
    }



  }
  cout <<"NA"<<endl;
}

main(){
  int c,r;
  while(cin>>c>>r&& c){
    int sy,sx,gy,gx;
    cin>>sx>>sy>>gx>>gy;
    sx--;sy--;gx--;gy--;
    rep(i,r){
      rep(j,c)cin>>m[i][j];
    }

    bfs(r,c,sy,sx,gy,gx);
  }
}

C++: //35
#include<iostream>
#include<queue>
#include<algorithm>

#define E(X,Y,Z,W) ((X)*52*52*52+(Y)*52*52+(Z)*52+(W))

using namespace std;

struct S{
  int x,y,xx,yy,t;
};

int main(){
  for(int x,y;cin>>x>>y,x|y;){
    S i;
    cin>>i.x>>i.y>>i.xx>>i.yy;
    int g[52][52];
    fill_n(g[0],52*52,1);
    for(int i=1;i<=y;i++){
      for(int j=1;j<=x;j++){
	cin>>g[i][j];
      }
    }
    i.t=0;
    static bool u[52*52*52*52];
    fill_n(u,sizeof(u)/sizeof(u[0]),false);
    queue<S> que;
    que.push(i);
    while(!que.empty()&&que.front().t<100){
      S c=que.front();
      if(c.x==c.xx&&c.y==c.yy)break;
      que.pop();
      if(u[E(c.x,c.y,c.xx,c.yy)]++)continue;
      for(int i=0;i<4;i++){
	int d[]={0,1,0,-1,0};
	S n=c;
	n.x+=d[i];
	n.y+=d[i+1];
	n.xx-=d[i];
	n.yy-=d[i+1];
	n.t++;
	if(g[n.y][n.x]){
	  n.x=c.x;
	  n.y=c.y;
	}
	if(g[n.yy][n.xx]){
	  n.xx=c.xx;
	  n.yy=c.yy;
	}
	que.push(n);
      }
    }
    if(!que.empty()&&que.front().t<100){
      cout<<que.front().t<<endl;
    }else{
      cout<<"NA"<<endl;
    }
  }
  return 0;
}