#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; cerr<<endl; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
typedef pair<int, int> P;
typedef pair<P, P> S;
typedef pair<double, P> state;

int main(){
  int N, X;
  while(cin>>N>>X && N){
    set<int> r_set;
    r_set.insert(1); r_set.insert(2);
    set<S> damage;
    int sr, sp, gr, gp;
    cin>>sr>>sp>>gr>>gp;
    sp--; gp--;
    r_set.insert(sr);
    r_set.insert(gr);
    REP(i, X){
      int r1, p1, r2, p2;
      cin>>r1>>p1>>r2>>p2;
      p1--; p2--;
      damage.insert(S(P(r1, p1), P(r2, p2)));
      damage.insert(S(P(r2, p2), P(r1, p1)));
      r_set.insert(r1);
      r_set.insert(r2);
      r_set.insert(r1 + 1);
      r_set.insert(r2 + 1);
      if(r1 >= 2) r_set.insert(r1 - 1);
      else r_set.insert(2);
      if(r2 >= 2) r_set.insert(r2 - 1);
      else r_set.insert(2);
    }
    vector<int> rs(r_set.begin(), r_set.end());
    int R = rs.size();
    //double dist[1000][100] = {};
    //REP(i, R)REP(j, N) dist[i][j] = 1e16;
    bool dist[1000][100] = {};
    int s_ridx = lower_bound(rs.begin(), rs.end(), sr) - rs.begin();
    priority_queue<state, vector<state>, greater<state> > que;
    que.push(state(0, P(s_ridx, sp)));
    while(!que.empty()){
      state s = que.top(); que.pop();
      int r_idx = s.second.first;
      int p = s.second.second;
      double d = s.first;
      //printf("(rs[%d]=%d, %d) = %lf\n", r_idx, rs[r_idx], p, d);
      if(rs[r_idx] == gr && p == gp){
        printf("%.2lf\n", d);
        break;
      }
      //if(dist[r_idx][p] < d) continue;
      if(dist[r_idx][p]) continue; dist[r_idx][p] = true;
      REP(r, 4){
        if(r % 2){
          int nr_idx = r_idx + r - 2;
          double nd = d + abs(rs[nr_idx] - rs[r_idx]);
          /*
          if(nr_idx >= 0 && nr_idx < R && dist[nr_idx][p] > nd && !damage.count(S(P(rs[r_idx], p), P(rs[nr_idx], p)))){
          */
          if(nr_idx >= 0 && nr_idx < R && !dist[nr_idx][p] && !damage.count(S(P(rs[r_idx], p), P(rs[nr_idx], p)))){
            //dist[r_idx][np] = nd;
            que.push(state(nd, P(nr_idx, p)));
          }
        }else{
          int np = (p + r - 1 + N) % N;
          double nd = (double)d + 2.0 * rs[r_idx] * sin(M_PI/N);
          /*
          if(dist[r_idx][np] > nd && !damage.count(S(P(rs[r_idx], p), P(rs[r_idx], np)))){
          */
          if(!dist[r_idx][np] && !damage.count(S(P(rs[r_idx], p), P(rs[r_idx], np)))){
            //dist[r_idx][np] = nd;
            que.push(state(nd, P(r_idx, np)));
          }
        }
      }
    }
  }

  return 0;
}

Measured memory_bytes: 1420