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 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)
	pq = append(pq, start)
	dx := []int64{0, 1, 0, -1}
	dy := []int64{1, 0, -1, 0}
	memo := make(map[PersonPosition]int64, 0)
	ans := int64(102)
	for len(pq) > 0 {
		now := pq[0]
		pq = pq[1:]
		if now.Person.Distance() == 0 && ans > now.Turn {
			ans = now.Turn
		}
		if ans <= now.Turn {
			continue
		}

		if _, ok := memo[now.Person]; ok {
			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++
			if next.Turn <= 100 {
				pq = append(pq, next)
			}
		}
	}
	if ans == 102 {
		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 <queue>
#include <set>

using namespace std;
typedef pair<int, int> Point;
typedef pair<pair<Point, Point>, int> Node;
int main() {
	int x;
	int y;
	int dx[] = { 0, 1, 0, -1 };
	int dy[] = { 1, 0, -1, 0 };
	while (cin >> x >> y, x | y) {
		int sax;
		int say;
		int sbx;
		int sby;
		cin >> sax >> say >> sbx >> sby;
		sax--;
		say--;
		sbx--;
		sby--;
		int map[y][x];
		for (int i = 0; i < y; i++) {
			for (int j = 0; j < x; j++) {
				cin >> map[i][j];
			}
		}
		queue<Node> q;
		Point sa = make_pair(sax, say);
		Point sb = make_pair(sbx, sby);
		q.push(make_pair(make_pair(sa, sb), 0));
		set<pair<Point, Point> > visited;
		while (1) {
			if (q.empty()) {
				cout << "NA" << endl;
				break;
			}
			Node tmp = q.front();
			q.pop();
			pair<Point, Point> ps = tmp.first;
			int t = tmp.second;
			int size = visited.size();
			visited.insert(ps);
			if (size == visited.size()) {
				continue;
			}
			Point a = ps.first;
			Point b = ps.second;
			int ax = a.first;
			int ay = a.second;
			int bx = b.first;
			int by = b.second;
			if (t > 100) {
				cout << "NA" << endl;
				break;
			}
			if (ax == bx && ay == by) {
				cout << t << endl;
				break;
			}
			for (int i = 0; i < 4; i++) {
				int nax = ax + dx[i];
				int nay = ay + dy[i];
				int nbx = bx - dx[i];
				int nby = by - dy[i];
				if (nax < 0 || nay < 0 || nax >= x || nay >= y
						|| map[nay][nax]) {
					nax = ax;
					nay = ay;
				}
				if (nbx < 0 || nby < 0 || nbx >= x || nby >= y
						|| map[nby][nbx]) {
					nbx = bx;
					nby = by;
				}
				Point na = make_pair(nax, nay);
				Point nb = make_pair(nbx, nby);
				q.push(make_pair(make_pair(na, nb), t + 1));
			}
		}
	}
	return 0;
}

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);
  }
}