Problem:
カジノ
あなたの勤めている会社では新たなカジノゲームの開発をしている．今日は最近提案されたゲームについて考察してみることにした．
このゲームでは
N
個のサイコロを同時に振って，出た目の合計が得点となる．プレイヤーは得点を大きくすることを目標としてプレーする．もし出た目が気に入らなければサイコロを振り直すことができるが，その時は
N
個のサイコロ全てを同時に振り直さなければならない．また，サイコロを振ることのできる回数は最大で
M
回である．十分に大きい目が出たと思ったのであれば，
M
回より少ない回数でゲームを終えても良く，最後に振ったサイコロの目の合計が得点となる．
適切な賭け金を設定するためには，得点の期待値を求めなければならない．
N
と
M
が与えられた時，最適な戦略をとった場合に得られる得点の期待値を求めるのが今日のあなたの仕事である．
ただし，このゲームで用いるサイコロには 1 から 6 までの目があり，それぞれの目が出る確率は同じである．
Input
入力は最大で 100 個のデータセットからなる．各データセットは次の形式で表される．
N
M
整数
N
，
M
は
1 ≤ N ≤ 20
，
1 ≤ M ≤ 10
10
を満たす．
入力の終わりは 2 つのゼロからなる行で表される．
Output
各データセットについて，最適な戦略をとった時の期待値を一行に出力せよ．出力には
10
-2
を超える絶対誤差があってはならない．この問題は計算誤差が大きくなる解法が想定されるため，精度のよい型を用いることが推奨される．
Sample Input
1 2
2 1
2 2
0 0
Output for the Sample Input
4.25
7
7.9722222222

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(n);i++)
using namespace std;
#define all(a) a.begin(),a.end()
#define compress(a) sort(all(a));a.erase(unique(all(a)),a.end())
typedef long long ll;
typedef pair<ll,ll> P;
constexpr ll mod=998244353;
constexpr ll inf=3e18;
// #define double long double

typedef vector<vector<double>> mat;

mat mul(mat &A,mat &B){
    int n=A.size();
    mat C(n,vector<double>(n));

    rep(i,n){
        rep(j,n){
            rep(k,n){
                C[i][j]+=A[i][k]*B[k][j];
            }
        }
    }
    return C;
}
mat pow(mat A,ll n){
    int m=A.size();
    mat res(m,vector<double>(m));
    rep(i,m)res[i][i]=1;
    while(n){
        if(n&1)res=mul(res,A);
        A=mul(A,A);
        n>>=1;
    }
    return res;
}

int solve(){
    ll n,m;
    cin>>n>>m;
    if(!n)return 0;
    vector<double>prob(130);
    prob[0]=1;
    rep(i,n){
        for(int j=6*i+6;j>=i;j--){
            double res=0;
            for(int k=1;k<=6;k++){
                if(j-k>=0)res+=prob[j-k]/6;
            }
            prob[j]=res;
        }
    }

    int ez=7*n/2;
    double E=(double)(n)*3.5;
    ll turn=1;

    while(1){
        double p=0,r=0;
        for(int i=0;i<=ez;i++)p+=prob[i];
        for(int i=ez+1;i<=6*n;i++)r+=prob[i]*i;
        
        //ezを超える瞬間を求める
        mat M(2,vector<double>(2));
        M[0][0]=p;
        M[0][1]=r;
        M[1][1]=1;

        ll lb=0,ub=m;
        while(ub-lb>1){
            ll mi=(ub+lb)/2;
            mat M2=pow(M,mi);
            double ek=E*M2[0][0]+M2[0][1];
            if(ek<ez+1)lb=mi;
            else ub=mi;
        }
        if(turn+ub>=m){
            mat M3=pow(M,m-turn);
            cout<<fixed<<setprecision(9)<<M3[0][0]*E+M3[0][1]<<endl;
            break;
        }
        turn+=ub;
        mat M3=pow(M,ub);
        E=M3[0][0]*E+M3[0][1];
        ez=E;
    }

    return 1;
}

int main(){
    while(solve());
}
accuracy: 1
time_ms: 60
memory_kb: 3308
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

#include <atcoder/all>
using namespace atcoder;

using ll = long long;
using mint = modint998244353;

bool solve() {
  using ld = __float128;
  using ld2 = long double;
  ll N, M;
  cin >> N >> M;
  if(N == 0) return false;
  vector dp(N + 1, vector<ll>(6 * N + 1));
  dp[0][0] = 1;
  for(int i = 1; i <= N; i++) {
    for(int j = 1; j <= 6 * i; j++) {
      for(int k = 1; k <= 6 && j - k >= 0; k++) {
        dp[i][j] += dp[i - 1][j - k];
      }
    }
    // for(int j = 1; j <= 6 * i; j++) {
    //   cout << dp[i][j] << " \n"[j == 6 * i];
    // }
  }
  const ld C = accumulate(dp[N].begin(), dp[N].end(), 0LL);
  vector<ld> P(6 * N + 1);
  for(int j = 0; j <= 6 * N; j++) {
    P[j] = dp[N][j] / C;
    // cout << fixed << setprecision(20) << P[j] * j << endl;
  }
  auto f = [&](ld a, ld b, ld x, ll k) -> ld {
    array<ld, 4> X = {1, 0, 0, 1};
    array<ld, 4> Y = {a, b, 0, 1};
    array<ld, 4> Z = {0, 0, 0, 0};
    // cout << "# " << (ld2)a << " " << (ld2)b << " " << k << endl;
    while(k) {
      if(k & 1) {
        Z[0] = X[0] * Y[0] + X[1] * Y[2];
        Z[1] = X[0] * Y[1] + X[1] * Y[3];
        Z[2] = X[2] * Y[0] + X[3] * Y[2];
        Z[3] = X[2] * Y[1] + X[3] * Y[3];
        swap(X, Z);
      }
      {
        Z[0] = Y[0] * Y[0] + Y[1] * Y[2];
        Z[1] = Y[0] * Y[1] + Y[1] * Y[3];
        Z[2] = Y[2] * Y[0] + Y[3] * Y[2];
        Z[3] = Y[2] * Y[1] + Y[3] * Y[3];
        swap(Y, Z);
      }
      k >>= 1;
    }
    // cout << (ld2)X[0] << " " << (ld2)X[1] << endl;
    return X[0] * x + X[1];
  };
  if(M < 1e6) {
    vector<ld> ep(M + 1);
    for(int i = 1; i <= M; i++) {
      for(int j = 0; j <= 6 * N; j++) {
        ep[i] += P[j] * max((ld)j, ep[i - 1]);
      }
    }
    cout << fixed << setprecision(5) << (ld2)ep[M] << endl;
    return true;
  }
  M--;
  ld x = 3.5 * N;
  for(int i = floor(3.5 * N); M > 0 && i <= 6 * N; i++) {
    // cout << M << endl;
    ld a = 0, b = 0;
    for(int j = 0; j <= i; j++) a += P[j];
    for(int j = i + 1; j <= 6 * N; j++) b += P[j] * j;
    if(f(a, b, x, M) < i + 1) {
      x = f(a, b, x, M);
      break;
    }else {
      ll ok = 0, ng = M;
      while(ok + 1 < ng) {
        ll k = (ok + ng) / 2;
        if(f(a, b, i, k) < i + 1) ok = k;
        else ng = k;
      }
      x = f(a, b, x, ng);
      M -= ng;
    }
  }
  cout << fixed << setprecision(5) << (ld2)x << endl;
  return true;
}

int main() {
  while(solve());
}
accuracy: 1
time_ms: 110
memory_kb: 3968
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
template<class T> bool chmax(T &a, T b){if (a < b){a = b;return true;} else return false;}
template<class T> bool chmin(T &a, T b){if (a > b){a = b;return true;} else return false;}

template <class T>
struct Matrix {
    vector<vector<T>> A;
    Matrix(int n, int m) : A(n, vector<T>(m, 0)) {}
    Matrix(int n) : A(n, vector<T>(n, 0)) {}
    int height() const {
        return (A.size());
    }
    int width() const {
        return (A[0].size());
    }
    const vector<T> &operator[](int k) const {
        return (A[k]);
    }
    vector<T> &operator[](int k) {
        return (A[k]);
    }
    static Matrix I(int n) {
        Matrix mat(n);
        for (int i = 0; i < n; i++) mat[i][i] = 1;
        return mat;
    }
    Matrix &operator+=(const Matrix &B) {
        int n = height(), m = width();
        assert(n == B.height() && m == B.width());
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                (*this)[i][j] += B[i][j];
            }
        }
        return (*this);
    }
    Matrix &operator-=(const Matrix &B) {
        int n = height(), m = width();
        assert(n == B.height() && m == B.width());
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                (*this)[i][j] -= B[i][j];
            }
        }
        return (*this);
    }
    Matrix &operator*=(const Matrix &B) {
        int n = height(), m = B.width(), p = width();
        assert(p == B.height());
        vector<vector<T>> C(n, vector<T>(m, 0));
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (int k = 0; k < p; k++) {
                    C[i][j] += (*this)[i][k] * B[k][j];
                }
            }
        }
        A.swap(C);
        return (*this);
    }
    Matrix &operator^=(long long k) {
        int n = height();
        assert(n == width());
        Matrix B = Matrix::I(n);
        while (k > 0) {
            if (k & 1) B *= *this;
            *this *= *this;
            k >>= 1LL;
        }
        A.swap(B.A);
        return (*this);
    }
    Matrix operator+(const Matrix &B) const {
        return (Matrix(*this) += B);
    }
    Matrix operator-(const Matrix &B) const {
        return (Matrix(*this) -= B);
    }
    Matrix operator*(const Matrix &B) const {
        return (Matrix(*this) *= B);
    }
    Matrix operator^(const long long k) const {
        return (Matrix(*this) ^= k);
    }
};

using ld=long double;
const ld EPS=1e-12;

void Solve(int N,ll M){
    vector cp(N+1,vector<ld>(6*N+1));
    cp[0][0]=1;
    for(int i=0;i<N;i++){
        for(int j=0;j<=6*N;j++){
            for(int k=1;k<=6&&j+k<=6*N;k++){
                cp[i+1][j+k]+=cp[i][j]/6.0;
            }
        }
    }
    vector<ld>p(6*N+1),e(6*N+1);
    for(int i=0;i<=6*N;i++){
        for(int j=0;j<=i;j++){
            p[i]+=cp[N][j];
        }
        for(int j=i+1;j<=6*N;j++){
            e[i]+=j*cp[N][j];
        }
    }
    map<ll,ld>ans;
    ans[0]=0;
    ll l=0;
    for(int i=0;i<=6*N;i++){
        if(l==M+1)break;
        if(ans[l]>i+1-EPS)continue;
        ll ok=l,ng=M+1;
        while(ng-ok>1){
            ll mid=(ok+ng)/2;
            Matrix<ld>mat(2,2);
            mat[0][0]=p[i];
            mat[0][1]=e[i];
            mat[1][1]=1;
            mat^=mid-l;
            if(ans[l]*mat[0][0]+mat[0][1]<i+1-EPS)ok=mid;
            else ng=mid;
        }
        {
            Matrix<ld>mat(2,2);
            mat[0][0]=p[i];
            mat[0][1]=e[i];
            mat[1][1]=1;
            mat^=ok-l;
            ans[ok]=ans[l]*mat[0][0]+mat[0][1];
            if(ok+1<=M)ans[ok+1]=ans[ok]*p[i]+e[i];
            l=ok+1;
        }
    }
    cout<<ans[M]<<"\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout<<fixed<<setprecision(15);
    while(1){
        int N;
        ll M;
        cin>>N>>M;
        if(N==0&&M==0)break;
        Solve(N,M);
    }
}
accuracy: 1
time_ms: 80
memory_kb: 3968
final_rank: 13

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
while(1) {
    int N;
    ll M;
    cin >> N >> M;
    if (N == 0 && M == 0) return 0;
    int MAXS = N*6+1;
    vector<long double> V(MAXS, 0);
    V[0] = 1.0;
    rep(i,0,N) {
        rrep(j,0,MAXS) {
            V[j] = 0;
            rep(k,1,7) {
                if (j-k >= 0) V[j] += V[j-k] / 6;
            }
        }
    }
    vector<long double> A(MAXS+1,0), B(MAXS+1,0);
    rep(i,0,MAXS) A[i+1] = A[i] + V[i];
    rrep(i,0,MAXS) B[i] = B[i+1] + V[i] * (long double)i;
    long double ANS = 0.0;
    while(M>0) {
        int X = floor(ANS);
        if (X == N * 6) break;
        long double C = B[X+1] / (1.0 - A[X+1]);
        long long NG = 0, OK = M;
        while(OK - NG > 1) {
            long long MID = (OK + NG) / 2;
            if ((ANS - C) * pow(A[X+1], MID) + C >= X + 1) OK = MID;
            else NG = MID;
        }
        ANS = (ANS - C) * pow(A[X+1], OK) + C;
        M -= OK;
    }
    print(ANS);
}
}
accuracy: 1
time_ms: 10
memory_kb: 3688
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
using ld=long double;
constexpr int MOD=998244353;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define replr(i,l,r) for(int i=(l);i<(int)(r);i++)

using Mat=array<array<ld,2>,2>;
constexpr ld per6=1.0/6;

Mat matpow(Mat m,ll n){
  Mat ret;
  ret[0][0]=1,ret[0][1]=0,ret[1][0]=0,ret[1][1]=1;
  while(n>0){
    if(n%2){
      Mat n2;
      n2[0][0]=0,n2[0][1]=0,n2[1][0]=0,n2[1][1]=0;
      for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
          for(int k=0;k<2;k++){
            n2[i][j]+=ret[i][k]*m[k][j];
          }
        }
      }
      ret=n2;
    }
    Mat m2;
    m2[0][0]=0,m2[0][1]=0,m2[1][0]=0,m2[1][1]=0;
    for(int i=0;i<2;i++){
      for(int j=0;j<2;j++){
        for(int k=0;k<2;k++){
          m2[i][j]+=m[i][k]*m[k][j];
        }
      }
    }
    m=m2;
    n/=2;
  }
  return ret;
}

void solve(ll N,ll M){
  ll N6=N*6+1;
  vector<ld> p(N6);
  p[0]=1;
  for(int c=0;c<N;c++){
    for(int i=N6-1;i>=0;i--){
      ld s=0;
      for(int j=1;j<=6;j++){
        if(i-j>=0)s+=p[i-j]*per6;
      }
      p[i]=s;
    }
  }
  ld ans=0,pl=0,pr=0;
  for(int i=0;i<N6;i++){
    pr+=p[i]*i;
  }
  for(int i=0;i<N6;i++){
    pr-=p[i]*i;
    pl+=p[i];
    if(ans>i+1)continue;
    ll les=-1,tmp=M;
    while(tmp-les>1){
      ll mid=(tmp+les)/2;
      Mat m;
      m[0][0]=pl,m[0][1]=pr,m[1][0]=0,m[1][1]=1;
      Mat n=matpow(m,mid);
      if(n[0][0]*ans+n[0][1]>=i+1)tmp=mid;
      else les=mid;
    }
    {
      M-=tmp;
      Mat m;
      m[0][0]=pl,m[0][1]=pr,m[1][0]=0,m[1][1]=1;
      Mat n=matpow(m,tmp);
      ans=n[0][0]*ans+n[0][1];
    }
  }
  cout<<setprecision(10)<<ans<<'\n';
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  while(1){
    ll N,M;
    cin>>N>>M;
    if(N==0)break;
    solve(N,M);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3384
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vd = vector<double>;
using vvd = vector<vd>;
using vvvd = vector<vvd>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (int i = 0; i < (int) (n); i++)
template<class T>
void chmax(T& p, T q) { if (p < q)p = q; };

vvd mul(vvd A,vvd B){
    ll n=A.size();
    vvd res(n,vd(n,0));
    rep(i,n)rep(j,n)rep(k,n)res[i][j]+=A[i][k]*B[k][j];
    return res;
}

vvd mulpow(vvd A,ll N){
    ll n=A.size();
    vvd res(n,vd(n,0.0));
    rep(i,n)res[i][i]=1.0;
    while(N>0){
        if(N%2)res=mul(res,A);
        A=mul(A,A);
        N/=2;
    }
    return res;
}

void solve(ll N, ll M) {
    vector<double> NUM(6*N+1,0.0),SUM(6*N+1,0.0);
    NUM[0]=1.0;
    rep(i,N){
        vector<double> NN(6*N+1,0.0);
        rep(j,6*N+1){
            rep(k,6){
                if(j+k+1<=6*N){
                    NN[j+k+1]+=NUM[j]/6.0;
                }
            }
        }
        swap(NN,NUM);
    }
    cout<<fixed<<setprecision(15);
    rep(i,6*N+1)SUM[i]=NUM[i]*i;
    rep(i,6*N){
        NUM[i+1]+=NUM[i];
    }
    for(ll i=6*N-1;i>=0;i--)SUM[i]+=SUM[i+1];

    double p=double(N*7)/2.0;

    if(M==1){
        cout<<p<<endl;
        return ;
    }
    ll L=1;
    while(1){
        ll flp=ll(p);
        ll ng=L,ok=1e18+10;
        while(ok-ng>1){
            ll mid=(ok+ng)/2;
            vvd A={{NUM[flp],SUM[flp+1]},{0.0,1.0}};
            auto B=mulpow(A,mid-L);
            double u=B[0][0]*p+B[0][1]*1.0;
            if(u>double(flp+1)){
                ok=mid;
            }
            else {
                ng=mid;
            }
        }
        if(M<ok){
            vvd A={{NUM[flp],SUM[flp+1]},{0.0,1.0}};
            auto B=mulpow(A,M-L);
            double u=B[0][0]*p+B[0][1]*1.0;
            cout<<u<<endl;
            return;
        }
        else{
            vvd A={{NUM[flp],SUM[flp+1]},{0.0,1.0}};
            auto B=mulpow(A,ok-L);
            double u=B[0][0]*p+B[0][1]*1.0;
            L=ok;
            p=u;
        }
    }

}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    
    ll N, M;
    while (cin >> N >> M) {
        if (N == 0)return 0;
        solve(N, M);
    }

}
accuracy: 1
time_ms: 550
memory_kb: 3540
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;

bool is_end = false;


const ld EPS = 1e-3;

void solve()
{
    ll N, M; cin >> N >> M;
    if (N == 0 && M == 0)
    {
        is_end = true;
        return;
    }
    
    vector<ld> dice(6*N+1, 0.0);
    dice[0] = 1.0;
    for (int i = 1; i <= N; ++i)
    {
        vector<ld> copy = dice;
        for (int j = 0; j <= 6*i; ++j)
        {
            ld sum = 0.0;
            for (int k = 1; k <= 6; ++k)
            {
                if (j - k >= 0) sum += copy[j-k] / 6;
            }
            dice[j] = sum;
        }
    }
    
    vector<pair<ll, ld>> vec;
    vec.emplace_back(1, (ld)3.5 * N);
    
    cout << fixed << setprecision(20);
    while (1)
    {
        auto [id, dp0] = vec.back();
        int k = floor(dp0);
        assert(id <= M);
        
        if (abs(dp0 - (ld)6.0*N) < EPS)
        {
            cout << (ld)6.0 * N << endl;
            return;
        }
        
        assert(k <= 6 * N);
        
        ld P = 0.0, E = 0.0;
        for (int i = 0; i <= k; ++i) P += dice[i];
        for (int i = k+1; i <= 6*N; ++i) E += i * dice[i];
        ld ep = E / (1 - P);
        
        {
            ld dpm = (dp0 - ep) * pow(P, M - id) + ep;
            if ((int)floor(dpm) == k)
            {
                cout << fixed << setprecision(20);
                cout << dpm << endl;
                return;
            }
        }
        
        ll ng = M, ok = id;
        while (abs(ok - ng) > 1)
        {
            ll mid = (ok + ng) / 2;
            ld dpm = (dp0 - ep) * pow(P, mid - id) + ep;
            if ((int)floor(dpm) == k) ok = mid;
            else ng = mid;            
        }
        
        ld ndp = (dp0 - ep) * pow(P, ng - id) + ep;
        vec.emplace_back(ng, ndp);
        
    }
    
    cout << -1 << endl;
    
    return;
}

int main()
{
    while (!is_end)
    {
        solve();
    }
    
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3544
final_rank: 2

code_snippet: #line 1 "/Users/nok0/Documents/Programming/nok0/cftemp.hpp"
#include <bits/stdc++.h>
using namespace std;

#pragma region Macros
// rep macro
#define foa(v, a) for(auto &v : a)
#define REPname(a, b, c, d, e, ...) e
#define REP(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int i = 0; i < (x); ++i)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define REPSname(a, b, c, ...) c
#define REPS(...) REPSname(__VA_ARGS__, REPS1, REPS0)(__VA_ARGS__)
#define REPS0(x) for(int i = 1; i <= (x); ++i)
#define REPS1(i, x) for(int i = 1; i <= (x); ++i)
#define RREPname(a, b, c, d, e, ...) e
#define RREP(...) RREPname(__VA_ARGS__, RREP3, RREP2, RREP1, RREP0)(__VA_ARGS__)
#define RREP0(x) for(int i = (x)-1; i >= 0; --i)
#define RREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define RREP2(i, r, l) for(int i = (r)-1; i >= (l); --i)
#define RREP3(i, r, l, c) for(int i = (r)-1; i >= (l); i -= (c))
#define RREPSname(a, b, c, ...) c
#define RREPS(...) RREPSname(__VA_ARGS__, RREPS1, RREPS0)(__VA_ARGS__)
#define RREPS0(x) for(int i = (x); i >= 1; --i)
#define RREPS1(i, x) for(int i = (x); i >= 1; --i)

// name macro
#define pb push_back
#define eb emplace_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define popcnt(x) __builtin_popcountll(x)
template <class T = int>
using V = std::vector<T>;
template <class T = int>
using VV = std::vector<std::vector<T>>;
template <class T>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
using ll = long long;
using ld = long double;
using int128 = __int128_t;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;

// input macro
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
	is >> p.first >> p.second;
	return is;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
	for(T &i : v) is >> i;
	return is;
}
std::istream &operator>>(std::istream &is, __int128_t &a) {
	std::string s;
	is >> s;
	__int128_t ret = 0;
	for(int i = 0; i < s.length(); i++)
		if('0' <= s[i] and s[i] <= '9')
			ret = 10 * ret + s[i] - '0';
	a = ret * (s[0] == '-' ? -1 : 1);
	return is;
}
namespace scanner {
void scan(int &a) { std::cin >> a; }
void scan(long long &a) { std::cin >> a; }
void scan(std::string &a) { std::cin >> a; }
void scan(char &a) { std::cin >> a; }
void scan(char a[]) { std::scanf("%s", a); }
void scan(double &a) { std::cin >> a; }
void scan(long double &a) { std::cin >> a; }
template <class T, class U>
void scan(std::pair<T, U> &p) { std::cin >> p; }
template <class T>
void scan(std::vector<T> &a) { std::cin >> a; }
void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &...tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#define VEC(type, name, size)     \
	std::vector<type> name(size); \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                                    \
	std::vector<std::vector<type>> name(h, std::vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)             \
	std::string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHAR(...)     \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DOUBLE(...)     \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)

// output-macro
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &a) {
	for(int i = 0; i < int(a.size()); ++i) {
		if(i) os << " ";
		os << a[i];
	}
	return os;
}
std::ostream &operator<<(std::ostream &dest, __int128_t &value) {
	std::ostream::sentry s(dest);
	if(s) {
		__uint128_t tmp = value < 0 ? -value : value;
		char buffer[128];
		char *d = std::end(buffer);
		do {
			--d;
			*d = "0123456789"[tmp % 10];
			tmp /= 10;
		} while(tmp != 0);
		if(value < 0) {
			--d;
			*d = '-';
		}
		int len = std::end(buffer) - d;
		if(dest.rdbuf()->sputn(d, len) != len) {
			dest.setstate(std::ios_base::badbit);
		}
	}
	return dest;
}
template <class T>
void print(const T a) { std::cout << a << '\n'; }
template <class Head, class... Tail>
void print(Head H, Tail... T) {
	std::cout << H << ' ';
	print(T...);
}
template <class T>
void printel(const T a) { std::cout << a << '\n'; }
template <class T>
void printel(const std::vector<T> &a) {
	for(const auto &v : a)
		std::cout << v << '\n';
}
template <class Head, class... Tail>
void printel(Head H, Tail... T) {
	std::cout << H << '\n';
	printel(T...);
}
void Yes(const bool b = true) { std::cout << (b ? "Yes\n" : "No\n"); }
void No() { std::cout << "No\n"; }
void YES(const bool b = true) { std::cout << (b ? "YES\n" : "NO\n"); }
void NO() { std::cout << "NO\n"; }
void err(const bool b = true) {
	if(b) {
		std::cout << "-1\n", exit(0);
	}
}

//debug macro
namespace debugger {
template <class T>
void view(const std::vector<T> &a) {
	std::cerr << "{ ";
	for(const auto &v : a) {
		std::cerr << v << ", ";
	}
	std::cerr << "\b\b }";
}
template <class T>
void view(const std::vector<std::vector<T>> &a) {
	std::cerr << "{\n";
	for(const auto &v : a) {
		std::cerr << "\t";
		view(v);
		std::cerr << "\n";
	}
	std::cerr << "}";
}
template <class T, class U>
void view(const std::vector<std::pair<T, U>> &a) {
	std::cerr << "{\n";
	for(const auto &p : a) std::cerr << "\t(" << p.first << ", " << p.second << ")\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &p : m) std::cerr << "\t[" << p.first << "] : " << p.second << "\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::pair<T, U> &p) { std::cerr << "(" << p.first << ", " << p.second << ")"; }
template <class T>
void view(const std::set<T> &s) {
	std::cerr << "{ ";
	for(auto &v : s) {
		view(v);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <class T>
void view(const T &e) { std::cerr << e; }
}  // namespace debugger
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	debugger::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(false)
#else
#define debug(...) (void(0))
#endif

// vector macro
template <class T>
int lb(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x))); }
template <class T>
int ub(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x))); }
template <class T>
void UNIQUE(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<T> press(std::vector<T> &a) {
	auto res = a;
	UNIQUE(res);
	for(auto &v : a)
		v = lb(res, v);
	return res;
}
#define SORTname(a, b, c, ...) c
#define SORT(...) SORTname(__VA_ARGS__, SORT1, SORT0, ...)(__VA_ARGS__)
#define SORT0(a) std::sort((a).begin(), (a).end())
#define SORT1(a, c) std::sort((a).begin(), (a).end(), [](const auto x, const auto y) { return x c y; })
template <class T>
void ADD(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v += x;
}
template <class T>
void SUB(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v -= x;
}
std::vector<std::pair<char, int>> rle(const string &s) {
	int n = s.size();
	std::vector<std::pair<char, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and s[l] == s[r]; r++) {}
		ret.emplace_back(s[l], r - l);
		l = r;
	}
	return ret;
}
template <class T>
std::vector<std::pair<T, int>> rle(const std::vector<T> &v) {
	int n = v.size();
	std::vector<std::pair<T, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and v[l] == v[r]; r++) {}
		ret.emplace_back(v[l], r - l);
		l = r;
	}
	return ret;
}
std::vector<int> iota(int n) {
	std::vector<int> p(n);
	std::iota(p.begin(), p.end(), 0);
	return p;
}
template <class T>
struct cum_vector {
public:
	cum_vector() = default;
	template <class U>
	cum_vector(const std::vector<U> &vec) : cum((int)vec.size() + 1) {
		for(int i = 0; i < (int)vec.size(); i++)
			cum[i + 1] = cum[i] + vec[i];
	}
	T prod(int l, int r) {
		return cum[r] - cum[l];
	}

private:
	std::vector<T> cum;
};

// math macro
template <class T, class U>
inline bool chmin(T &a, const U &b) { return a > b ? a = b, true : false; }
template <class T, class U>
inline bool chmax(T &a, const U &b) { return a < b ? a = b, true : false; }
template <class T>
T divup(T x, T y) { return (x + y - 1) / y; }
template <class T>
T POW(T a, long long n) {
	T ret = 1;
	while(n) {
		if(n & 1) ret *= a;
		a *= a;
		n >>= 1;
	}
	return ret;
}
// modpow
long long POW(long long a, long long n, const int mod) {
	long long ret = 1;
	a = (a % mod + mod) % mod;
	while(n) {
		if(n & 1) (ret *= a) %= mod;
		(a *= a) %= mod;
		n >>= 1;
	}
	return ret;
}
template <class T, class F>
T bin_search(T ok, T ng, const F &f) {
	while(abs(ok - ng) > 1) {
		T mid = (ok + ng) >> 1;
		(f(mid) ? ok : ng) = mid;
	}
	return ok;
}
template <class T, class F>
T bin_search(T ok, T ng, const F &f, int loop) {
	for(int i = 0; i < loop; i++) {
		T mid = (ok + ng) / 2;
		(f(mid) ? ok : ng) = mid;
	}
	return ok;
}

// others
struct fast_io {
	fast_io() {
		ios::sync_with_stdio(false);
		cin.tie(nullptr);
		cout << fixed << setprecision(15);
	}
} fast_io_;
const int inf = 1e9;
const ll INF = 1e18;
#pragma endregion

void main_();

int main() {
	main_();
	return 0;
}
#line 5 "/Users/nok0/Documents/Programming/nok0/math/matrix.hpp"

template <class T>
struct matrix {
private:
	std::vector<std::vector<T>> A;

	static matrix I(size_t n) {
		matrix mat(n);
		for(int i = 0; i < n; i++) mat[i][i] = 1;
		return mat;
	}

public:
	matrix() = default;

	matrix(std::vector<std::vector<T>> &vvec) { A = vvec; }

	matrix(size_t n, size_t m) : A(n, std::vector<T>(m, 0)) {}

	matrix(size_t n, size_t m, T init) : A(n, std::vector<T>(m, init)) {}

	matrix(size_t n, std::vector<T> &vec) : A(n, vec) {}

	matrix(size_t n) : A(n, std::vector<T>(n, 0)) {}

	size_t height() const { return A.size(); }

	size_t width() const { return A[0].size(); }

	inline const std::vector<T> &operator[](int k) const {
		return A[k];
	}

	inline std::vector<T> &operator[](int k) {
		return A[k];
	}

	matrix &operator+=(const matrix &B) {
		size_t n = height(), m = width();
		assert(n == B.height() and m == B.width());
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] += B[i][j];
		return *this;
	}

	matrix &operator-=(const matrix &B) {
		size_t n = height(), m = width();
		assert(n == B.height() and m == B.width());
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] -= B[i][j];
		return *this;
	}

	matrix &operator*=(const matrix &B) {
		size_t n = height(), m = B.width(), p = width();
		assert(p == B.height());
		std::vector<std::vector<T>> C(n, std::vector<T>(m, 0));
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				for(int k = 0; k < p; k++)
					C[i][j] += (*this)[i][k] * B[k][j];
		A.swap(C);
		return *this;
	}

	matrix &operator^=(long long k) {
		matrix B = matrix::I(height());
		while(k > 0) {
			if(k & 1) B *= (*this);
			*this *= *this;
			k >>= 1ll;
		}
		A.swap(B.A);
		return *this;
	}

	bool operator==(const matrix &B) {
		size_t n = height(), m = width();
		if(n != B.height() or m != B.width()) return false;
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				if((*this)[i][j] != B[i][j]) return false;
		return true;
	}

	matrix operator+(const matrix &B) const {
		return (matrix(*this) += B);
	}

	matrix operator-(const matrix &B) const {
		return (matrix(*this) -= B);
	}

	matrix operator*(const matrix &B) const {
		return (matrix(*this) *= B);
	}

	matrix operator^(const long long &k) const {
		return (matrix(*this) ^= k);
	}

	matrix &operator+=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] += t;
		return *this;
	}

	matrix &operator-=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] -= t;
		return *this;
	}

	matrix &operator*=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] *= t;
		return *this;
	}

	matrix &operator/=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] /= t;
		return *this;
	}

	matrix operator+(const T &t) const {
		return (matrix(*this) += t);
	}

	matrix operator-(const T &t) const {
		return (matrix(*this) -= t);
	}

	matrix operator*(const T &t) const {
		return (matrix(*this) *= t);
	}

	matrix operator/(const T &t) const {
		return (matrix(*this) /= t);
	}

	friend std::ostream &operator<<(std::ostream &os, matrix &p) {
		size_t n = p.height(), m = p.width();
		for(int i = 0; i < n; i++) {
			os << '[';
			for(int j = 0; j < m; j++)
				os << p[i][j] << (j == m - 1 ? "]\n" : ",");
		}
		return (os);
	}

	T determinant() {
		matrix B(*this);
		size_t n = height(), m = width();
		assert(n == m);
		T ret = 1;
		for(int i = 0; i < n; i++) {
			int idx = -1;
			for(int j = i; j < n; j++)
				if(B[j][i] != 0) idx = j;
			if(idx == -1) return 0;
			if(i != idx) {
				ret *= -1;
				swap(B[i], B[idx]);
			}
			ret *= B[i][i];
			T vv = B[i][i];
			for(int j = 0; j < n; j++) B[i][j] /= vv;
			for(int j = i + 1; j < n; j++) {
				T a = B[j][i];
				for(int k = 0; k < n; k++) {
					B[j][k] -= B[i][k] * a;
				}
			}
		}
		return ret;
	}

	matrix inv() {
		int n = height();
		if(determinant() == T(0)) return matrix(0);
		matrix a(*(this)), l = I(n), u(n);
		for(int j = 0; j < n; j++) u[0][j] = a[0][j];
		for(int j = 1; j < n; j++) l[j][0] = a[j][0] / u[0][0];
		for(int k = 1; k < n; k++) {
			for(int j = k; j < n; j++)
				for(int i = 0; i < k; i++) a[j][k] -= l[j][i] * u[i][k];
			u[k][k] = a[k][k];
			for(int j = k + 1; j < n; j++) {
				u[k][j] = a[k][j];
				for(int i = 0; i < k; i++)
					u[k][j] -= l[k][i] * u[i][j];
			}
			for(int j = k + 1; j < n; j++) l[j][k] = a[j][k] / u[k][k];
		}
		matrix x(n), y = I(n);
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++) {
				for(int k = 0; k < j; k++) y[j][i] -= l[j][k] * y[k][i];
			}
		T sigma;
		for(int h = 0; h < n; h++)
			for(int i = n - 1; i >= 0; i--) {
				sigma = y[i][h];
				for(int j = i + 1; j < n; j++) {
					sigma -= u[i][j] * x[j][h];
				}
				x[i][h] = sigma / u[i][i];
			}
		return move(x);
	}
};
#line 3 "g.cpp"

int n;
ll m;
double solve() {
	//出目の和がpを求めるパート
	V<double> p(n * 6 + 1);

	V<double> saikoro = {1};
	for(int i = 0; i < n; i++) {
		vector<double> new_saikoro(saikoro.size() + 6);
		for(int j = 1; j <= 6; j++) {
			for(int k = 0; k < saikoro.size(); k++) {
				new_saikoro[k + j] += saikoro[k] / 6;
			}
		}
		saikoro = new_saikoro;
	}
	p = saikoro;

	//p1[i] = 1 ~ i の和
	vector<double> p1(6 * n + 1);
	REPS(i, 6 * n) {
		p1[i] = p1[i - 1] + p[i] * i;
	}
	cum_vector<double> p2(p);
	double ret = n * 3.5;
	ll nokori = m - 1;
	while(nokori > 0) {
		//(a_n ,1) にmul かけて (a_{n-1}, 1) を得る.
		int fl = floor(ret);
		matrix<double> def(1, 2);
		def[0][0] = ret;
		def[0][1] = 1;
		matrix<double> mul(2, 2);
		mul[0][0] = p2.prod(1, fl + 1);
		mul[0][1] = 0;
		mul[1][0] = p1[6 * n] - p1[fl];
		mul[1][1] = 1;
		double tmp = (def * (mul ^ nokori))[0][0];
		if(floor(tmp) == fl) {
			nokori = 0;
			ret = tmp;
		} else {
			//にぶたん？
			auto f = [&](ll mid) -> bool {
				return floor((def * (mul ^ mid))[0][0]) == fl;
			};
			auto cnt = bin_search(0ll, nokori, f) + 1;
			nokori -= cnt;
			ret = (def * (mul ^ cnt))[0][0];
		}
	}
	return ret;
}

void main_() {
	while(cin >> n >> m, n) {
		print(solve());
	}
}
accuracy: 1
time_ms: 60
memory_kb: 3648
final_rank: 9

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 510000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
//const int mod = 1e9 + 7;
const int mod = 998244353;

using ld = long double;
using VD = vector<vector<ld>>;

VD matmul(VD &a, VD &b){
	VD c(a.size(), vector<ld>(b[0].size()));
	for(int i=0; i<a.size(); i++){
		for(int k=0; k<b.size(); k++){
			for(int j=0; j<b[0].size(); j++){
				c[i][j] = c[i][j] + a[i][k] * b[k][j];
			}
		}
	}
	return c;
}

VD matpow(VD a, ll n){
	VD b(a.size(), vector<ld>(a.size()));
	for(int i=0; i<a.size(); i++) b[i][i] = 1;
	while(n > 0){
		if(n & 1) b = matmul(b,a);
		a = matmul(a,a);
		n >>= 1;
	}
	return b;
}

int main(){
	while(1){
		ll n,m; cin >> n >> m; m--;
		if(!n) break; 
		ll N = 6*n;
		vector<ld> dp(N+1);
		VD ep(n+1,vector<ld>(N+1,0));
		ep[0][0] = 1;
		rep(i,n){
			rep(j,N+1){
				REP(k,1,7){
					if(j+k > N) break;
					ep[i+1][j+k] += ep[i][j] / 6; 
				}
			}
		}
		ld s = 0;
		rep(i,N+1) dp[i] = ep[n][i] * i, s += dp[i];
		if(m == 0){
			printf("%.10Lf\n",s);
			continue;
		}
		m--;
		REP(j,1,N+1){
			if(s+eps >= j) continue;
			rep(i,j) dp[i] = max(dp[i], s * ep[n][i]);
			if(m == 0) break;
			s = 0;
			rep(i,N+1) s += dp[i];
			ld rest = s, pr = 0;
			rep(i,j) rest -= dp[i], pr += ep[n][i];
			ll ok = 0, ng = m;
			VD ma{
				{pr,1},
				{0,1}
			};
			while(ng-ok > 1){
				ll mid = (ok+ng) / 2;
				VD res = matpow(ma,mid);
				if(res[0][0]*s + res[0][1]*rest > j) ng = mid;
				else ok = mid;
			}
			VD res = matpow(ma,ok);
			s = res[0][0]*s + res[0][1]*rest;
			rep(i,j+1) dp[i] = max(s * ep[n][i], dp[i]);
			m -= ok+1;
		}
		s = 0;
		rep(i,N+1) s += dp[i];
		printf("%.10Lf\n",s);
	}
}
accuracy: 1
time_ms: 70
memory_kb: 3572
final_rank: 10

code_snippet: #line 1 "/Users/nok0/Documents/Programming/nok0/cftemp.hpp"
#include <bits/stdc++.h>
using namespace std;

#pragma region Macros
// rep macro
#define foa(v, a) for(auto &v : a)
#define REPname(a, b, c, d, e, ...) e
#define REP(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int i = 0; i < (x); ++i)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define REPSname(a, b, c, ...) c
#define REPS(...) REPSname(__VA_ARGS__, REPS1, REPS0)(__VA_ARGS__)
#define REPS0(x) for(int i = 1; i <= (x); ++i)
#define REPS1(i, x) for(int i = 1; i <= (x); ++i)
#define RREPname(a, b, c, d, e, ...) e
#define RREP(...) RREPname(__VA_ARGS__, RREP3, RREP2, RREP1, RREP0)(__VA_ARGS__)
#define RREP0(x) for(int i = (x)-1; i >= 0; --i)
#define RREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define RREP2(i, r, l) for(int i = (r)-1; i >= (l); --i)
#define RREP3(i, r, l, c) for(int i = (r)-1; i >= (l); i -= (c))
#define RREPSname(a, b, c, ...) c
#define RREPS(...) RREPSname(__VA_ARGS__, RREPS1, RREPS0)(__VA_ARGS__)
#define RREPS0(x) for(int i = (x); i >= 1; --i)
#define RREPS1(i, x) for(int i = (x); i >= 1; --i)

// name macro
#define pb push_back
#define eb emplace_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define popcnt(x) __builtin_popcountll(x)
template <class T = int>
using V = std::vector<T>;
template <class T = int>
using VV = std::vector<std::vector<T>>;
template <class T>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
using ll = long long;
using ld = long double;
using int128 = __int128_t;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;

// input macro
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
	is >> p.first >> p.second;
	return is;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
	for(T &i : v) is >> i;
	return is;
}
std::istream &operator>>(std::istream &is, __int128_t &a) {
	std::string s;
	is >> s;
	__int128_t ret = 0;
	for(int i = 0; i < s.length(); i++)
		if('0' <= s[i] and s[i] <= '9')
			ret = 10 * ret + s[i] - '0';
	a = ret * (s[0] == '-' ? -1 : 1);
	return is;
}
namespace scanner {
void scan(int &a) { std::cin >> a; }
void scan(long long &a) { std::cin >> a; }
void scan(std::string &a) { std::cin >> a; }
void scan(char &a) { std::cin >> a; }
void scan(char a[]) { std::scanf("%s", a); }
void scan(double &a) { std::cin >> a; }
void scan(long double &a) { std::cin >> a; }
template <class T, class U>
void scan(std::pair<T, U> &p) { std::cin >> p; }
template <class T>
void scan(std::vector<T> &a) { std::cin >> a; }
void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &...tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#define VEC(type, name, size)     \
	std::vector<type> name(size); \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                                    \
	std::vector<std::vector<type>> name(h, std::vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)             \
	std::string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHAR(...)     \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DOUBLE(...)     \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)

// output-macro
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &a) {
	for(int i = 0; i < int(a.size()); ++i) {
		if(i) os << " ";
		os << a[i];
	}
	return os;
}
std::ostream &operator<<(std::ostream &dest, __int128_t &value) {
	std::ostream::sentry s(dest);
	if(s) {
		__uint128_t tmp = value < 0 ? -value : value;
		char buffer[128];
		char *d = std::end(buffer);
		do {
			--d;
			*d = "0123456789"[tmp % 10];
			tmp /= 10;
		} while(tmp != 0);
		if(value < 0) {
			--d;
			*d = '-';
		}
		int len = std::end(buffer) - d;
		if(dest.rdbuf()->sputn(d, len) != len) {
			dest.setstate(std::ios_base::badbit);
		}
	}
	return dest;
}
template <class T>
void print(const T a) { std::cout << a << '\n'; }
template <class Head, class... Tail>
void print(Head H, Tail... T) {
	std::cout << H << ' ';
	print(T...);
}
template <class T>
void printel(const T a) { std::cout << a << '\n'; }
template <class T>
void printel(const std::vector<T> &a) {
	for(const auto &v : a)
		std::cout << v << '\n';
}
template <class Head, class... Tail>
void printel(Head H, Tail... T) {
	std::cout << H << '\n';
	printel(T...);
}
void Yes(const bool b = true) { std::cout << (b ? "Yes\n" : "No\n"); }
void No() { std::cout << "No\n"; }
void YES(const bool b = true) { std::cout << (b ? "YES\n" : "NO\n"); }
void NO() { std::cout << "NO\n"; }
void err(const bool b = true) {
	if(b) {
		std::cout << "-1\n", exit(0);
	}
}

//debug macro
namespace debugger {
template <class T>
void view(const std::vector<T> &a) {
	std::cerr << "{ ";
	for(const auto &v : a) {
		std::cerr << v << ", ";
	}
	std::cerr << "\b\b }";
}
template <class T>
void view(const std::vector<std::vector<T>> &a) {
	std::cerr << "{\n";
	for(const auto &v : a) {
		std::cerr << "\t";
		view(v);
		std::cerr << "\n";
	}
	std::cerr << "}";
}
template <class T, class U>
void view(const std::vector<std::pair<T, U>> &a) {
	std::cerr << "{\n";
	for(const auto &p : a) std::cerr << "\t(" << p.first << ", " << p.second << ")\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &p : m) std::cerr << "\t[" << p.first << "] : " << p.second << "\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::pair<T, U> &p) { std::cerr << "(" << p.first << ", " << p.second << ")"; }
template <class T>
void view(const std::set<T> &s) {
	std::cerr << "{ ";
	for(auto &v : s) {
		view(v);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <class T>
void view(const T &e) { std::cerr << e; }
}  // namespace debugger
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	debugger::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(false)
#else
#define debug(...) (void(0))
#endif

// vector macro
template <class T>
int lb(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x))); }
template <class T>
int ub(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x))); }
template <class T>
void UNIQUE(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<T> press(std::vector<T> &a) {
	auto res = a;
	UNIQUE(res);
	for(auto &v : a)
		v = lb(res, v);
	return res;
}
#define SORTname(a, b, c, ...) c
#define SORT(...) SORTname(__VA_ARGS__, SORT1, SORT0, ...)(__VA_ARGS__)
#define SORT0(a) std::sort((a).begin(), (a).end())
#define SORT1(a, c) std::sort((a).begin(), (a).end(), [](const auto x, const auto y) { return x c y; })
template <class T>
void ADD(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v += x;
}
template <class T>
void SUB(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v -= x;
}
std::vector<std::pair<char, int>> rle(const string &s) {
	int n = s.size();
	std::vector<std::pair<char, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and s[l] == s[r]; r++) {}
		ret.emplace_back(s[l], r - l);
		l = r;
	}
	return ret;
}
template <class T>
std::vector<std::pair<T, int>> rle(const std::vector<T> &v) {
	int n = v.size();
	std::vector<std::pair<T, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and v[l] == v[r]; r++) {}
		ret.emplace_back(v[l], r - l);
		l = r;
	}
	return ret;
}
std::vector<int> iota(int n) {
	std::vector<int> p(n);
	std::iota(p.begin(), p.end(), 0);
	return p;
}
template <class T>
struct cum_vector {
public:
	cum_vector() = default;
	template <class U>
	cum_vector(const std::vector<U> &vec) : cum((int)vec.size() + 1) {
		for(int i = 0; i < (int)vec.size(); i++)
			cum[i + 1] = cum[i] + vec[i];
	}
	T prod(int l, int r) {
		return cum[r] - cum[l];
	}

private:
	std::vector<T> cum;
};

// math macro
template <class T, class U>
inline bool chmin(T &a, const U &b) { return a > b ? a = b, true : false; }
template <class T, class U>
inline bool chmax(T &a, const U &b) { return a < b ? a = b, true : false; }
template <class T>
T divup(T x, T y) { return (x + y - 1) / y; }
template <class T>
T POW(T a, long long n) {
	T ret = 1;
	while(n) {
		if(n & 1) ret *= a;
		a *= a;
		n >>= 1;
	}
	return ret;
}
// modpow
long long POW(long long a, long long n, const int mod) {
	long long ret = 1;
	a = (a % mod + mod) % mod;
	while(n) {
		if(n & 1) (ret *= a) %= mod;
		(a *= a) %= mod;
		n >>= 1;
	}
	return ret;
}
template <class T, class F>
T bin_search(T ok, T ng, const F &f) {
	while(abs(ok - ng) > 1) {
		T mid = (ok + ng) >> 1;
		(f(mid) ? ok : ng) = mid;
	}
	return ok;
}
template <class T, class F>
T bin_search(T ok, T ng, const F &f, int loop) {
	for(int i = 0; i < loop; i++) {
		T mid = (ok + ng) / 2;
		(f(mid) ? ok : ng) = mid;
	}
	return ok;
}

// others
struct fast_io {
	fast_io() {
		ios::sync_with_stdio(false);
		cin.tie(nullptr);
		cout << fixed << setprecision(15);
	}
} fast_io_;
const int inf = 1e9;
const ll INF = 1e18;
#pragma endregion

void main_();

int main() {
	main_();
	return 0;
}
#line 5 "/Users/nok0/Documents/Programming/nok0/math/matrix.hpp"

template <class T>
struct matrix {
private:
	std::vector<std::vector<T>> A;

	static matrix I(size_t n) {
		matrix mat(n);
		for(int i = 0; i < n; i++) mat[i][i] = 1;
		return mat;
	}

public:
	matrix() = default;

	matrix(std::vector<std::vector<T>> &vvec) { A = vvec; }

	matrix(size_t n, size_t m) : A(n, std::vector<T>(m, 0)) {}

	matrix(size_t n, size_t m, T init) : A(n, std::vector<T>(m, init)) {}

	matrix(size_t n, std::vector<T> &vec) : A(n, vec) {}

	matrix(size_t n) : A(n, std::vector<T>(n, 0)) {}

	size_t height() const { return A.size(); }

	size_t width() const { return A[0].size(); }

	inline const std::vector<T> &operator[](int k) const {
		return A[k];
	}

	inline std::vector<T> &operator[](int k) {
		return A[k];
	}

	matrix &operator+=(const matrix &B) {
		size_t n = height(), m = width();
		assert(n == B.height() and m == B.width());
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] += B[i][j];
		return *this;
	}

	matrix &operator-=(const matrix &B) {
		size_t n = height(), m = width();
		assert(n == B.height() and m == B.width());
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] -= B[i][j];
		return *this;
	}

	matrix &operator*=(const matrix &B) {
		size_t n = height(), m = B.width(), p = width();
		assert(p == B.height());
		std::vector<std::vector<T>> C(n, std::vector<T>(m, 0));
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				for(int k = 0; k < p; k++)
					C[i][j] += (*this)[i][k] * B[k][j];
		A.swap(C);
		return *this;
	}

	matrix &operator^=(long long k) {
		matrix B = matrix::I(height());
		while(k > 0) {
			if(k & 1) B *= (*this);
			*this *= *this;
			k >>= 1ll;
		}
		A.swap(B.A);
		return *this;
	}

	bool operator==(const matrix &B) {
		size_t n = height(), m = width();
		if(n != B.height() or m != B.width()) return false;
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				if((*this)[i][j] != B[i][j]) return false;
		return true;
	}

	matrix operator+(const matrix &B) const {
		return (matrix(*this) += B);
	}

	matrix operator-(const matrix &B) const {
		return (matrix(*this) -= B);
	}

	matrix operator*(const matrix &B) const {
		return (matrix(*this) *= B);
	}

	matrix operator^(const long long &k) const {
		return (matrix(*this) ^= k);
	}

	matrix &operator+=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] += t;
		return *this;
	}

	matrix &operator-=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] -= t;
		return *this;
	}

	matrix &operator*=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] *= t;
		return *this;
	}

	matrix &operator/=(const T &t) {
		int n = height(), m = width();
		for(int i = 0; i < n; i++)
			for(int j = 0; j < m; j++)
				(*this)[i][j] /= t;
		return *this;
	}

	matrix operator+(const T &t) const {
		return (matrix(*this) += t);
	}

	matrix operator-(const T &t) const {
		return (matrix(*this) -= t);
	}

	matrix operator*(const T &t) const {
		return (matrix(*this) *= t);
	}

	matrix operator/(const T &t) const {
		return (matrix(*this) /= t);
	}

	friend std::ostream &operator<<(std::ostream &os, matrix &p) {
		size_t n = p.height(), m = p.width();
		for(int i = 0; i < n; i++) {
			os << '[';
			for(int j = 0; j < m; j++)
				os << p[i][j] << (j == m - 1 ? "]\n" : ",");
		}
		return (os);
	}

	T determinant() {
		matrix B(*this);
		size_t n = height(), m = width();
		assert(n == m);
		T ret = 1;
		for(int i = 0; i < n; i++) {
			int idx = -1;
			for(int j = i; j < n; j++)
				if(B[j][i] != 0) idx = j;
			if(idx == -1) return 0;
			if(i != idx) {
				ret *= -1;
				swap(B[i], B[idx]);
			}
			ret *= B[i][i];
			T vv = B[i][i];
			for(int j = 0; j < n; j++) B[i][j] /= vv;
			for(int j = i + 1; j < n; j++) {
				T a = B[j][i];
				for(int k = 0; k < n; k++) {
					B[j][k] -= B[i][k] * a;
				}
			}
		}
		return ret;
	}

	matrix inv() {
		int n = height();
		if(determinant() == T(0)) return matrix(0);
		matrix a(*(this)), l = I(n), u(n);
		for(int j = 0; j < n; j++) u[0][j] = a[0][j];
		for(int j = 1; j < n; j++) l[j][0] = a[j][0] / u[0][0];
		for(int k = 1; k < n; k++) {
			for(int j = k; j < n; j++)
				for(int i = 0; i < k; i++) a[j][k] -= l[j][i] * u[i][k];
			u[k][k] = a[k][k];
			for(int j = k + 1; j < n; j++) {
				u[k][j] = a[k][j];
				for(int i = 0; i < k; i++)
					u[k][j] -= l[k][i] * u[i][j];
			}
			for(int j = k + 1; j < n; j++) l[j][k] = a[j][k] / u[k][k];
		}
		matrix x(n), y = I(n);
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++) {
				for(int k = 0; k < j; k++) y[j][i] -= l[j][k] * y[k][i];
			}
		T sigma;
		for(int h = 0; h < n; h++)
			for(int i = n - 1; i >= 0; i--) {
				sigma = y[i][h];
				for(int j = i + 1; j < n; j++) {
					sigma -= u[i][j] * x[j][h];
				}
				x[i][h] = sigma / u[i][i];
			}
		return move(x);
	}
};
#line 3 "g.cpp"

int n;
ll m;
double solve() {
	//出目の和がpを求めるパート
	V<double> p(n * 6 + 1);

	V<double> saikoro = {1};
	for(int i = 0; i < n; i++) {
		vector<double> new_saikoro(saikoro.size() + 6);
		for(int j = 1; j <= 6; j++) {
			for(int k = 0; k < saikoro.size(); k++) {
				new_saikoro[k + j] += saikoro[k] / 6;
			}
		}
		saikoro = new_saikoro;
	}
	p = saikoro;

	//p1[i] = 1 ~ i の和
	vector<double> p1(6 * n + 1);
	REPS(i, 6 * n) {
		p1[i] = p1[i - 1] + p[i] * i;
	}
	cum_vector<double> p2(p);
	double ret = n * 3.5;
	ll nokori = m - 1;
	while(nokori > 0) {
		//(a_n ,1) にmul かけて (a_{n-1}, 1) を得る.
		int fl = floor(ret);
		matrix<double> def(1, 2);
		def[0][0] = ret;
		def[0][1] = 1;
		matrix<double> mul(2, 2);
		mul[0][0] = p2.prod(1, fl + 1);
		mul[0][1] = 0;
		mul[1][0] = p1[6 * n] - p1[fl];
		mul[1][1] = 1;
		double tmp = (def * (mul ^ nokori))[0][0];
		if(floor(tmp) == fl) {
			nokori = 0;
			ret = tmp;
		} else {
			//にぶたん？
			auto f = [&](ll mid) -> bool {
				return floor((def * (mul ^ mid))[0][0]) == fl;
			};
			auto cnt = bin_search(0ll, nokori, f) + 1;
			nokori -= cnt;
			ret = (def * (mul ^ cnt))[0][0];
		}
	}
	return ret;
}

void main_() {
	while(cin >> n >> m, n) {
		print(solve());
	}
}
accuracy: 1
time_ms: 60
memory_kb: 3644
final_rank: 8

code_snippet: #pragma region Macros
#pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2,tune=native")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,avx2")
// #pragma GCC target("avx2")
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define ll long long
using ld = long double;
#define rep2(i, a, b) for(ll i = (a); i <= (b); i++)
#define rep3(i, a, b) for(ll i = (a); i >= (b); --i)
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define each(i, a) for(auto &&i : a)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                                                                  \
    vector<type> name(size);                                                                                                                                   \
    IN(name)
#define VEC2(type, name1, name2, size)                                                                                                                         \
    vector<type> name1(size), name2(size);                                                                                                                     \
    for(int i = 0; i < size; i++) IN(name1[i], name2[i])
#define VEC3(type, name1, name2, name3, size)                                                                                                                  \
    vector<type> name1(size), name2(size), name3(size);                                                                                                        \
    for(int i = 0; i < size; i++) IN(name1[i], name2[i], name3[i])
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                                                                   \
    vector<vector<type>> name(h, vector<type>(w));                                                                                                             \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)                                                                                                                         \
    vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define mt make_tuple
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define rall(c) rbegin(c), rend(c)
#define SORT(v) sort(all(v))
#define REV(v) reverse(all(v))
template <class T = ll, class S> T SUM(const S &v) { return accumulate(all(v), T(0)); }
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
constexpr pii dx4[4] = {pii{1, 0}, pii{0, 1}, pii{-1, 0}, pii{0, -1}};
constexpr pii dx8[8] = {{1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}};
const string YESNO[2] = {"NO", "YES"};
const string YesNo[2] = {"No", "Yes"};
const string yesno[2] = {"no", "yes"};
void YES(bool t = 1) { cout << YESNO[t] << endl; }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { cout << YesNo[t] << endl; }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { cout << yesno[t] << endl; }
void no(bool t = 1) { yes(!t); }
template <class T> using vc = vector<T>;
template <class T> using vvc = vector<vc<T>>;
template <class T> using vvvc = vector<vvc<T>>;
template <class T> using vvvvc = vector<vvvc<T>>;
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define si(c) (int)(c).size()
#define INT(...)                                                                                                                                               \
    int __VA_ARGS__;                                                                                                                                           \
    IN(__VA_ARGS__)
#define LL(...)                                                                                                                                                \
    ll __VA_ARGS__;                                                                                                                                            \
    IN(__VA_ARGS__)
#define STR(...)                                                                                                                                               \
    string __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                                                                               \
    char __VA_ARGS__;                                                                                                                                          \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                                                                               \
    double __VA_ARGS__;                                                                                                                                        \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
template <class T> void scan(vector<T> &);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &...tail) {
    scan(head);
    IN(tail...);
}

template <class T, class S> inline bool chmax(T &a, const S &b) { return (a < b ? a = b, 1 : 0); }
template <class T, class S> inline bool chmin(T &a, const S &b) { return (a > b ? a = b, 1 : 0); }
vi iota(int n) {
    vi a(n);
    iota(all(a), 0);
    return a;
}
template <typename T> vi iota(vector<T> &a, bool greater = false) {
    vi res(a.size());
    iota(all(res), 0);
    sort(all(res), [&](int i, int j) {
        if(greater) return a[i] > a[j];
        return a[i] < a[j];
    });
    return res;
}
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}

template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x + y - 1) / y);
}
template <class T> T POW(T x, int n) {
    T res = 1;
    for(; n; n >>= 1, x *= x)
        if(n & 1) res *= x;
    return res;
}
template <class T, class S> T POW(T x, S n, const ll &mod) {
    T res = 1;
    for(; n; n >>= 1, x = x * x % mod)
        if(n & 1) res = res * x % mod;
    return res;
}
vector<pll> factor(ll x) {
    vector<pll> ans;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0) {
            ans.push_back({i, 1});
            while((x /= i) % i == 0) ans.back().second++;
        }
    if(x != 1) ans.push_back({x, 1});
    return ans;
}
template <class T> vector<T> divisor(T x) {
    vector<T> ans;
    for(T i = 1; i * i <= x; i++)
        if(x % i == 0) {
            ans.pb(i);
            if(i * i != x) ans.pb(x / i);
        }
    return ans;
}
template <typename T> void zip(vector<T> &x) {
    vector<T> y = x;
    UNIQUE(y);
    for(int i = 0; i < x.size(); ++i) { x[i] = lb(y, x[i]); }
}
template <class S> void fold_in(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void fold_in(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto e : a) v.emplace_back(e);
    fold_in(v, tail...);
}
template <class S> void renumber(vector<S> &v) {}
template <typename Head, typename... Tail, class S> void renumber(vector<S> &v, Head &&a, Tail &&...tail) {
    for(auto &&e : a) e = lb(v, e);
    renumber(v, tail...);
}
template <class S, class... Args> vector<S> zip(vector<S> &head, Args &&...args) {
    vector<S> v;
    fold_in(v, head, args...);
    sort(all(v)), v.erase(unique(all(v)), v.end());
    renumber(v, head, args...);
    return v;
}

// x in [l, r)
template <class T, class S> bool inc(const T &x, const S &l, const S &r) { return l <= x and x < r; }
// (a, b) in [lx, rx) * [ly, ry)
template <class T, class S> bool inc(const pair<T, T> &x, const S &lx, const S &ly, const S &rx, const S &ry) { return inc(x.fi, lx, rx) && inc(x.se, ly, ry); }

constexpr ll ten(int n) { return n == 0 ? 1 : ten(n - 1) * 10; }
// bit 演算系
ll pow2(int i) { return 1LL << i; }
int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(ll t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int lowbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int lowbit(ll a) { return a == 0 ? 64 : __builtin_ctzll(a); }
// int allbit(int n) { return (1 << n) - 1; }
constexpr ll allbit(int n) { return (1LL << n) - 1; }
// int popcount(signed t) { return __builtin_popcount(t); }
// int popcount(ll t) { return __builtin_popcountll(t); }
int popcount(uint64_t t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }

ll rnd(ll l, ll r) { //[l, r)
#ifdef _LOCAL
    static mt19937_64 gen;
#else
    static mt19937_64 gen(chrono::steady_clock::now().time_since_epoch().count());
#endif
    return uniform_int_distribution<ll>(l, r - 1)(gen);
}
ll rnd(ll n) { return rnd(0, n); }

template <class t> void random_shuffle(vc<t> &a) { rep(i, si(a)) swap(a[i], a[rnd(0, i + 1)]); }

int in() {
    int x;
    cin >> x;
    return x;
}
ll lin() {
    unsigned long long x;
    cin >> x;
    return x;
}

template <class T, class S> pair<T, S> operator-(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi - y.fi, x.se - y.se); }
template <class T, class S> pair<T, S> operator+(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi + y.fi, x.se + y.se); }
template <class T> pair<T, T> operator&(const pair<T, T> &l, const pair<T, T> &r) { return pair<T, T>(max(l.fi, r.fi), min(l.se, r.se)); }
template <class T, class S> pair<T, S> operator+=(pair<T, S> &l, const pair<T, S> &r) { return l = l + r; }
template <class T, class S> pair<T, S> operator-=(pair<T, S> &l, const pair<T, S> &r) { return l = l - r; }
template <class T> bool intersect(const pair<T, T> &l, const pair<T, T> &r) { return (l.se < r.se ? r.fi < l.se : l.fi < r.se); }

template <class T> ll operator*(const pair<T, T> &x, const pair<T, T> &y) { return (ll)x.fi * y.fi + (ll)x.se * y.se; }

template <typename T> struct edge {
    int from, to;
    T cost;
    int id;
    edge(int to, T cost) : from(-1), to(to), cost(cost) {}
    edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
    edge(int from, int to, T cost, int id) : from(from), to(to), cost(cost), id(id) {}
    constexpr bool operator<(const edge<T> &rhs) const noexcept { return cost < rhs.cost; }
    edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
};
template <typename T> using Edges = vector<edge<T>>;

using Tree = vector<vector<int>>;
using Graph = vector<vector<int>>;
template <class T> using Wgraph = vector<vector<edge<T>>>;
Graph getG(int n, int m = -1, bool directed = false, int margin = 1) {
    Tree res(n);
    if(m == -1) m = n - 1;
    while(m--) {
        int a, b;
        cin >> a >> b;
        a -= margin, b -= margin;
        res[a].emplace_back(b);
        if(!directed) res[b].emplace_back(a);
    }
    return res;
}
Graph getTreeFromPar(int n, int margin = 1) {
    Graph res(n);
    for(int i = 1; i < n; i++) {
        int a;
        cin >> a;
        res[a - margin].emplace_back(i);
    }
    return res;
}
template <class T> Wgraph<T> getWg(int n, int m = -1, bool directed = false, int margin = 1) {
    Wgraph<T> res(n);
    if(m == -1) m = n - 1;
    while(m--) {
        int a, b;
        T c;
        cin >> a >> b >> c;
        a -= margin, b -= margin;
        res[a].emplace_back(b, c);
        if(!directed) res[b].emplace_back(a, c);
    }
    return res;
}
void add(Graph &G, int x, int y) { G[x].eb(y), G[y].eb(x); }
template <class S, class T> void add(Wgraph<S> &G, int x, int y, T c) { G[x].eb(y, c), G[y].eb(x, c); }

#define i128 __int128_t
#define ull unsigned long long int
#define TEST                                                                                                                                                   \
    INT(testcases);                                                                                                                                            \
    while(testcases--)
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    for(auto it = begin(v); it != end(v); ++it) {
        if(it == begin(v))
            os << *it;
        else
            os << " " << *it;
    }
    return os;
}
template <class T, class S> ostream &operator<<(ostream &os, const pair<T, S> &p) {
    os << p.first << " " << p.second;
    return os;
}
template <class S, class T> string to_string(pair<S, T> p) { return "(" + to_string(p.first) + "," + to_string(p.second) + ")"; }
string to_string(string s) { return "\"" + s + "\""; }
string to_string(char c) { return string(1, c); }
template <class T> string to_string(vector<T> s) {
    string res = "{";
    for(auto it = s.begin(); it != s.end(); it++) res += to_string(*it) + (next(it) == s.end() ? "" : ", ");
    return res + "}";
}
template <class T> string to_string(set<T> s) {
    string res = "{";
    for(auto it = s.begin(); it != s.end(); it++) res += to_string(*it), res += (next(it) == end(s) ? "" : ", ");
    return res + "}";
}

#define endl '\n'

#ifdef _LOCAL
void dump() { cerr << endl; }
template <class Head, class... Tail> void dump(Head head, Tail... tail) {
    cerr << to_string(head) << " ";
    dump(tail...);
}
#undef endl
#define debug(x)                                                                                                                                               \
    cout << #x << ": ";                                                                                                                                        \
    dump(x)
#else
void dump() {}
template <class Head, class... Tail> void dump(Head head, Tail... tail) {}
#define debug(x)
#endif
template <class T> void print(const T &a) { cout << a; }
void OUT() { cout << endl; }
template <class Head, class... Tail> void OUT(const Head &head, const Tail &...tail) {
    print(head);
    if(sizeof...(tail)) cout << ' ';
    OUT(tail...);
}

template <typename T> static constexpr T inf = numeric_limits<T>::max() / 2;
#define drop(s) cout << #s << endl, exit(0)

template <int N> struct ndFORarray {
    std::array<int, N> v;
    ndFORarray(std::array<int, N> v_) : v(v_) {}
    struct ndFORitr {
        const std::array<int, N> &v;
        std::array<int, N> tmp;
        bool is_end;
        ndFORitr(const std::array<int, N> &v_) : v(v_), tmp(), is_end(false) {}
        bool operator!=(const ndFORitr &) const { return !is_end; }
        void operator++() {
            int pos = N - 1;
            while(pos != -1) {
                tmp[pos] += 1;
                if(tmp[pos] == v[pos]) {
                    tmp[pos] = 0;
                    pos -= 1;
                } else {
                    break;
                }
            }
            if(pos == -1) { is_end = true; }
        }
        const std::array<int, N> &operator*() const { return tmp; }
    };
    ndFORitr begin() const { return ndFORitr(v); }
    ndFORitr end() const { return ndFORitr(v); }
};

struct ndFORvector {
    std::vector<int> v;
    ndFORvector(std::vector<int> v_) : v(v_) {}
    struct ndFORitr {
        const std::vector<int> &v;
        std::vector<int> tmp;
        bool is_end;
        ndFORitr(const std::vector<int> &v_) : v(v_), tmp(v.size(), 0), is_end(false) {}
        bool operator!=(const ndFORitr &) const { return !is_end; }
        void operator++() {
            int pos = v.size() - 1;
            while(pos != -1) {
                tmp[pos] += 1;
                if(tmp[pos] == v[pos]) {
                    tmp[pos] = 0;
                    pos -= 1;
                } else {
                    break;
                }
            }
            if(pos == -1) { is_end = true; }
        }
        const std::vector<int> &operator*() const { return tmp; }
    };
    ndFORitr begin() const { return ndFORitr(v); }
    ndFORitr end() const { return ndFORitr(v); }
};

auto ndFOR(std::vector<int> v) { return ndFORvector(v); }
template <class... Ts> auto ndFOR(Ts... v) { return ndFORarray<std::tuple_size<std::tuple<Ts...>>::value>({v...}); }
template <class F> struct REC {
    F f;
    REC(F &&f_) : f(std::forward<F>(f_)) {}
    template <class... Args> auto operator()(Args &&...args) const { return f(*this, std::forward<Args>(args)...); }
};

template <class S> vector<pair<S, int>> runLength(const vector<S> &v) {
    vector<pair<S, int>> res;
    for(auto &e : v) {
        if(res.empty() or res.back().fi != e)
            res.eb(e, 1);
        else
            res.back().se++;
    }
    return res;
}
vector<pair<char, int>> runLength(const string &v) {
    vector<pair<char, int>> res;
    for(auto &e : v) {
        if(res.empty() or res.back().fi != e)
            res.eb(e, 1);
        else
            res.back().se++;
    }
    return res;
}

template <class T = int> struct Imos {
    int n;
    vector<T> a;
    Imos(int _n) : n(_n), a(_n + 1) {}
    void add(int l, int r, T val = 1) {
        if(l >= r) return;
        l = clamp(l, 0, n);
        r = clamp(r, 0, n + 1);
        a[l] += val;
        if(r <= n) a[r] -= val;
    }
    void build() {
        for(int i = 0; i < n; i++) a[i + 1] += a[i];
    }
    const T &operator[](int k) { return a[k]; }
};

template <class T> struct RUI {
    vector<T> a;
    RUI(const vector<T> &v) : a(v.size() + 1) {
        for(int i = 0; i < v.size(); i++) a[i + 1] = a[i] + v[i];
    }
    T get(int l, int r) { return a[r] - a[l]; }
};

template <class T, class F> T bin_search(T ok, T ng, const F &f) {
    while(abs(ok - ng) > 1) {
        T mid = ok + ng >> 1;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
template <class T, class F> T bin_search_double(T ok, T ng, const F &f, int iter = 80) {
    while(iter--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(15);
    }
} setup_io;
#pragma endregion

int main() {
    const ld EPS = 1e-9;
    while(1) {
        LL(n, m);
        if(!n) exit(0);
        vector<ld> dp(n * 6 + 1);
        dp[0] = 1;
        rep(_, n) {
            vector<ld> ndp(n * 6 + 1);
            rep(i, (n - 1) * 6 + 1) { rep2(j, 1, 6) ndp[i + j] += dp[i] / 6; }
            swap(dp, ndp);
        }

        ll k = 1;

        ld E = 3.5 * n;

        int t = 0;
        while(t + 1 < E) t++;
        // t 以下なら続行
        RUI<ld> rui(dp);

        vector<ld> EX(n * 6 + 1);
        rep(i, si(dp)) EX[i] = dp[i] * i;
        RUI<ld> ex(EX);

        if(m == 1) {
            OUT(E);
            continue;
        }

        while(k < m) {
            ld r = rui.get(0, t + 1);
            ld c = ex.get(t + 1, si(dp));
            auto f = [&](ll x) { return c / (1 - r) + (E - c / (1 - r)) * pow(r, x); };
            ll nxt = bin_search(0LL, m - k, [&](ll x) { return f(x) < t + 1 - EPS; });
            if(nxt + k + 1 == m) {
                OUT(f(nxt + 1));
                break;
            }
            k += nxt + 1;
            E = f(nxt + 1);
            if(E > 6 * n - EPS) {
                OUT(E);
                break;
            }
            while(t + 1 < E - EPS) t++;
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3620
final_rank: 3

code_snippet: //#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 2;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

typedef vector<vector<ld>> mat;
typedef vector<ld> vec;
mat mtmul(mat& A, mat& B) {
	mat C(A.size(), vec(B[0].size()));
	rep(i, (int)A.size()) {
		rep(k, (int)B.size()) {
			rep(j, (int)B[0].size()) {
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}
	return C;
}
mat mtpow(mat A, ll n) {
	mat B(A.size(), vec(A.size()));
	rep(i, (int)A.size()) {
		B[i][i] = 1;
	}
	while (n > 0) {
		if (n & (ll)1)B = mtmul(B, A);
		A = mtmul(A, A);
		n >>= 1;
	}
	return B;
}

int n; ll m;
void solve() {
	vector<ld> prob(6 * n + 1);
	prob[0] = 1;
	rep(i, n) {
		per(j, prob.size()) {
			rep1(ad, 6) {
				if (j + ad < prob.size()) {
					prob[j + ad] += prob[j] / 6.0;
				}
			}
			prob[j] = 0;
		}
	}
	ll cur = 1;
	ld ex = 3.5 * n;
	while (cur < m) {
		//cout << cur << " " << ex << "\n";
		int chk = -1;
		ld a = 0, c = 0;
		rep(i, prob.size()) {
			if (i <= ex) {
				chk = i;
				a += prob[i];
			}
			else {
				c += prob[i] * i;
			}
		}
		mat A = { {a,c},{0,1} };
		ll le = 0, ri = m - cur;
		while (ri - le > 1) {
			ll mid = (le + ri) / 2;
			mat B = mtpow(A, mid);
			ld val = B[0][0] * ex + B[0][1];
			if (val >= chk + 1) {
				ri = mid;
			}
			else {
				le = mid;
			}
		}
		mat B = mtpow(A, ri);
		ld val = B[0][0] * ex + B[0][1];
		cur += ri;
		ex = val;
	}
	cout << ex << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(8);
	//init_f();
	//init();
	//int t; cin >> t; rep(i, t)
	while(cin>>n>>m,n)
	solve();
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3604
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

long double Prob[121];

long double Jokentuki(int x){ // x以上の値のときの条件付き期待値
    long double po = 0;
    for(int i=x;i<=120;i++){
        po += Prob[i];
    }
    long double po2 = 0;
        for(int i=x;i<=120;i++){
        po2 += (long double)i * Prob[i];
    }
    if(po == 0)return 1;
    return po2 / po;
}

long double PlusProb(int x){ // x以上の値になる確率
    long double po = 0;
    for(int i=x;i<=120;i++){
        po += Prob[i];
    }
    return po;
}

int main(void){
    
    
    while(1){
        
        long long N;
        long long int M;
        cin >> N >> M;
        if(N==0)return 0;
        if(M==1){
            cout << 3.5*(long double)N << endl;
            continue;
        }
        for(int i=0;i<=120;i++)Prob[i] = 0.0f;
        Prob[0] = 1.0f;
        for(int i=0;i<N;i++){
            long double ProbCpy[N*6+1];
            for(int j=0;j<=N*6;j++)ProbCpy[j] = 0.0f;
            for(int j=0;j<=N*6-6;j++){
                for(int k=1;k<=6;k++){
                    ProbCpy[j+k] += Prob[j] / 6.0f;
                }
            }
            for(int j=0;j<=N*6;j++)Prob[j] = ProbCpy[j];
        }
        long long now_seeking = 7*N/2;
        long long now_kaisu = 1;
        long double now_Exp = 3.5*(long double)N;
        while(1){
            long long left = 0;
            long long right = (long long)1e15;
            long double poo = PlusProb(now_seeking + 1);
            while(right - left > 1){
                long long mid = (right + left)/2;
                long double Thinging_Exp = powl(1.0 - poo, (long double)mid) * now_Exp + (1.0-powl(1.0-poo, (long double)mid)) * Jokentuki(now_seeking+1);
                if(Thinging_Exp >= (long double)now_seeking+1.0)right = mid;
                else left = mid;
            }
            if(now_kaisu + right > M){
                cout << fixed << setprecision(15) << powl(1.0 - poo, (long double)(M-now_kaisu)) * now_Exp + (1.0-powl(1.0-poo, (long double)(M-now_kaisu))) * Jokentuki(now_seeking+1)  << endl;
                break;
            }
            else{
                now_kaisu = now_kaisu + right;
                now_Exp = powl(1.0 - poo, (long double)right) * now_Exp + (1.0-powl(1.0-poo, (long double)right)) * Jokentuki(now_seeking+1);
                now_seeking = floor(now_Exp);
            }
        }
        
    }
    
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3604
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define _GLIBCXX_DEBUG
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=1167167167167167167;
const int INF=2100000000;
const ll mod=998244353;
#define rep(i,a) for (ll i=0;i<a;i++)
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}

ld my_pow(ld a,ll b){
    if(b==0) return 1;
    if(b&1) return a*my_pow(a,b^1);
    return my_pow(a*a,b>>1);
}

//  rainy ~ 雨に打たれて ~
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	while(true){
        ll N,M;
        cin>>N>>M;
        if(N+M==0) break;
        int L=N*5+1;
        vector<ld> q(L);
        q[0]=1;
        rep(i,N){
            for(int j=L-6;j>=0;j--){
                q[j]/=6;
                rep(k,5){
                    q[j+k+1]+=q[j];
                }
            }
        }
        vector<ld> pro_sum(L);
        vector<ld> upper_ave(L);
        pro_sum[0]=q[0];
        rep(i,L-1){
            pro_sum[i+1]=pro_sum[i]+q[i+1];
        }
        upper_ave[L-1]=(ld)(L-1)*q[L-1];
        for(int i=L-2;i>=0;i--){
            upper_ave[i]=upper_ave[i+1]+q[i]*(ld)(i);
        }
        ld ans=0;
        rep(roop,min(1000000ll,M)){
            int k=ceil(ans);
            if(k>=L) break;
            if(k==0) ans=upper_ave[0];
            else ans=pro_sum[k-1]*ans+upper_ave[k];
        }
        M-=1000000;
        //cout<<M<<endl;
        while(M>0){
            int k=ceil(ans);
            if(k>=L) break;
            ld P=pro_sum[k-1];
            ld S=upper_ave[k];
            ll l=0,r=M;
            while(r-l>1){
                ll med=(l+r)/2;
                if((ld)k<my_pow(P,med)*ans+S*(my_pow(P,med)-1)/(P-1)){
                    r=med;
                }else{
                    l=med;
                }
            }
            M-=r;
            ans=my_pow(P,r)*ans+S*(my_pow(P,r)-1)/(P-1);
            if(ans<=k&&M!=0) ans=k+1e-20;
            //cout<<k<<" "<<M<<" "<<ans<<"\n";
        }
        cout<<setprecision(18);
        cout<<(ld)N+ans<<"\n";
    }
}
accuracy: 1
time_ms: 510
memory_kb: 3608
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=200005,INF=1<<30;

#define ld long double

ld dp[23][150];
ld kitai[100005][150];

typedef vector<ld> vec;
typedef vector<vector<ld>> mat;

mat mul(mat &A, mat&B){
    mat C(A.size(),vector<ld>(B[0].size()));
    for(int i=0;i<A.size();i++){
        for(int k=0;k<B.size();k++){
            for(int j=0;j<B[0].size();j++){
                C[i][j]+=A[i][k]*B[k][j];
            }
        }
    }
    return C;
}

mat pow(mat A,ll n){
    mat B(A.size(),vector<ld>(A.size()));
    for(int i=0;i<A.size();i++){
        B[i][i]=1;
    }
    
    while(n>0){
        if(n&1) B=mul(B,A);
        A=mul(A,A);
        n/=2;
    }
    return B;
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    dp[0][0]=1;
    for(int i=0;i<20;i++){
        for(int j=0;j<=i*6;j++){
            for(int k=1;k<=6;k++){
                dp[i+1][j+k]+=dp[i][j]/6;
            }
        }
    }
    
    while(1){
        ll N,M;cin>>N>>M;
        if(N==0&&M==0) break;
        for(int j=1;j<=6*N;j++) kitai[0][j]=j;
        for(int q=0;q<100000;q++){
            ld sum=0;
            for(int j=1;j<=6*N;j++){
                sum+=kitai[q][j]*dp[N][j];
            }
            for(int j=1;j<=6*N;j++){
                kitai[q+1][j]=max((ld)j,sum);
            }
        }
        if(M<=100000){
            ld ans=0;
            for(int j=1;j<=6*N;j++) ans+=kitai[M-1][j]*dp[N][j];
            cout<<fixed<<setprecision(20)<<ans<<"\n";
            continue;
        }
        ld sum=0;
        for(int j=1;j<=6*N;j++) sum+=kitai[99999][j]*dp[N][j];
        
        ll turn=100000;
        
        for(int j=ceil(sum);j<=6*N;j++){
            ld Q=0,X=0;
            for(int k=1;k<=sum;k++) Q+=dp[N][k];
            for(int k=sum+1;k<=6*N;k++) X+=(ld)k*dp[N][k];
            //cout<<Q<<" "<<sum<<" "<<X<<" "<<Q*sum+X<<endl;
            ll left=0,right=M+3-turn;
            while(right-left>1){
                ll mid=(left+right)/2;
                mat A(2,vec(2));
                A[0][0]=Q;
                A[0][1]=1;
                A[1][1]=1;
                mat B(2,vec(1));
                B[0][0]=sum;
                B[1][0]=X;
                
                A=pow(A,mid);
                
                //cout<<mid<<" "<<A[0][0]<<" "<<A[0][1]<<" "<<A[1][0]<<" "<<A[1][1]<<endl;
                mat C=mul(A,B);
                
                if(C[0][0]>j) right=mid;
                else left=mid;
            }
            if(right==M+3-turn){
                ll mid=M-turn;
                mat A(2,vec(2));
                A[0][0]=Q;
                A[0][1]=1;
                A[1][1]=1;
                mat B(2,vec(1));
                B[0][0]=sum;
                B[1][0]=X;
                
                A=pow(A,mid);
                mat C=mul(A,B);
                
                cout<<fixed<<setprecision(20)<<C[0][0]<<"\n";
                break;
            }else{
                ll mid=right;
                mat A(2,vec(2));
                A[0][0]=Q;
                A[0][1]=1;
                A[1][1]=1;
                mat B(2,vec(1));
                B[0][0]=sum;
                B[1][0]=X;
                
                A=pow(A,mid);
                mat C=mul(A,B);
                
                turn+=right;
                sum=C[0][0];
            }
            
            if(j==6*N){
                cout<<fixed<<setprecision(20)<<sum<<"\n";
            }
        }
    }
}
accuracy: 1
time_ms: 1560
memory_kb: 237904
final_rank: 18

code_snippet: //#define _GLIBCXX_DEBUG

#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define lfs cout<<fixed<<setprecision(10)
#define ALL(a)  (a).begin(),(a).end()
#define ALLR(a)  (a).rbegin(),(a).rend()
#define UNIQUE(a) (a).erase(unique((a).begin(),(a).end()),(a).end())
#define spa << " " <<
#define fi first
#define se second
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define EB emplace_back
#define rep(i,n,m) for(ll i = (n); i < (ll)(m); i++)
#define rrep(i,n,m) for(ll i = (ll)(m) - 1; i >= (ll)(n); i--)
using ll = long long;
using ld = long double;
const ll MOD1 = 1e9+7;
const ll MOD9 = 998244353;
const ll INF = 1e18;
using P = pair<ll, ll>;
template<typename T> using PQ = priority_queue<T>;
template<typename T> using QP = priority_queue<T,vector<T>,greater<T>>;
template<typename T1, typename T2>bool chmin(T1 &a,T2 b){if(a>b){a=b;return true;}else return false;}
template<typename T1, typename T2>bool chmax(T1 &a,T2 b){if(a<b){a=b;return true;}else return false;}
ll median(ll a,ll b, ll c){return a+b+c-max({a,b,c})-min({a,b,c});}
void ans1(bool x){if(x) cout<<"Yes"<<endl;else cout<<"No"<<endl;}
void ans2(bool x){if(x) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
void ans3(bool x){if(x) cout<<"Yay!"<<endl;else cout<<":("<<endl;}
template<typename T1,typename T2>void ans(bool x,T1 y,T2 z){if(x)cout<<y<<endl;else cout<<z<<endl;}  
template<typename T1,typename T2,typename T3>void anss(T1 x,T2 y,T3 z){ans(x!=y,x,z);};  
template<typename T>void debug(const T &v,ll h,ll w,string sv=" "){for(ll i=0;i<h;i++){cout<<v[i][0];for(ll j=1;j<w;j++)cout<<sv<<v[i][j];cout<<endl;}};
template<typename T>void debug(const T &v,ll n,string sv=" "){if(n!=0)cout<<v[0];for(ll i=1;i<n;i++)cout<<sv<<v[i];cout<<endl;};
template<typename T>void debug(const vector<T>&v){debug(v,v.size());}
template<typename T>void debug(const vector<vector<T>>&v){for(auto &vv:v)debug(vv,vv.size());}
template<typename T>void debug(stack<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(queue<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(deque<T> st){while(!st.empty()){cout<<st.front()<<" ";st.pop_front();}cout<<endl;}
template<typename T>void debug(PQ<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(QP<T> st){while(!st.empty()){cout<<st.top()<<" ";st.pop();}cout<<endl;}
template<typename T>void debug(const set<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T>void debug(const multiset<T>&v){for(auto z:v)cout<<z<<" ";cout<<endl;}
template<typename T,size_t size>void debug(const array<T, size> &a){for(auto z:a)cout<<z<<" ";cout<<endl;}
template<typename T,typename V>void debug(const map<T,V>&v){for(auto z:v)cout<<"["<<z.first<<"]="<<z.second<<",";cout<<endl;}
template<typename T>vector<vector<T>>vec(ll x, ll y, T w){vector<vector<T>>v(x,vector<T>(y,w));return v;}
ll gcd(ll x,ll y){ll r;while(y!=0&&(r=x%y)!=0){x=y;y=r;}return y==0?x:y;}
vector<ll>dx={1,-1,0,0,1,1,-1,-1};vector<ll>dy={0,0,1,-1,1,-1,1,-1};
template<typename T>vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
template<typename... Ts>auto make_v(size_t a,Ts... ts){return vector<decltype(make_v(ts...))>(a,make_v(ts...));}
template<typename T1, typename T2>ostream &operator<<(ostream &os, const pair<T1, T2>&p){return os << p.first << " " << p.second;}
template<typename T>ostream &operator<<(ostream &os, const vector<T> &v){for(auto &z:v)os << z << " ";cout<<"|"; return os;}
template<typename T>void rearrange(vector<int>&ord, vector<T>&v){
  auto tmp = v;
  for(int i=0;i<tmp.size();i++)v[i] = tmp[ord[i]];
}
template<typename Head, typename... Tail>void rearrange(vector<int>&ord,Head&& head, Tail&&... tail){
  rearrange(ord, head);
  rearrange(ord, tail...);
}
template<typename T> vector<int> ascend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]<v[j];});
  return ord;
}
template<typename T> vector<int> descend(const vector<T>&v){
  vector<int>ord(v.size());iota(ord.begin(),ord.end(),0);
  sort(ord.begin(),ord.end(),[&](int i,int j){return v[i]>v[j];});
  return ord;
}
ll FLOOR(ll n,ll div){assert(div>0);return n>=0?n/div:(n-div+1)/div;}
ll CEIL(ll n,ll div){assert(div>0);return n>=0?(n+div-1)/div:n/div;}
ll digitsum(ll n){ll ret=0;while(n){ret+=n%10;n/=10;}return ret;}
template<typename T>T min(const vector<T>&v){return *min_element(v.begin(),v.end());}
template<typename T>T max(const vector<T>&v){return *max_element(v.begin(),v.end());}
template<typename T>T acc(const vector<T>&v){return accumulate(v.begin(),v.end(),T(0));};
template<typename T>T reverse(const T &v){return T(v.rbegin(),v.rend());};
//mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
int popcount(ll x){return __builtin_popcountll(x);};
int poplow(ll x){return __builtin_ctzll(x);};
int pophigh(ll x){return 63 - __builtin_clzll(x);};
template<typename T>T poll(queue<T> &q){auto ret=q.front();q.pop();return ret;};
template<typename T>T poll(priority_queue<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(QP<T> &q){auto ret=q.top();q.pop();return ret;};
template<typename T>T poll(stack<T> &s){auto ret=s.top();s.pop();return ret;};
ll MULT(ll x,ll y){if(LLONG_MAX/x<=y)return LLONG_MAX;return x*y;}
ll POW2(ll x, ll k){ll ret=1,mul=x;while(k){if(mul==LLONG_MAX)return LLONG_MAX;if(k&1)ret=MULT(ret,mul);mul=MULT(mul,mul);k>>=1;}return ret;}
ll POW(ll x, ll k){ll ret=1;for(int i=0;i<k;i++){if(LLONG_MAX/x<=ret)return LLONG_MAX;ret*=x;}return ret;}
template< typename T = int >
struct edge {
  int to;
  T cost;
  int id;
  edge():id(-1){};
  edge(int to, T cost = 1, int id = -1):to(to), cost(cost), id(id){}
  operator int() const { return to; }
};

template<typename T>
using Graph = vector<vector<edge<T>>>;
template<typename T>
Graph<T>revgraph(const Graph<T> &g){
  Graph<T>ret(g.size());
  for(int i=0;i<g.size();i++){
    for(auto e:g[i]){
      int to = e.to;
      e.to = i;
      ret[to].push_back(e);
    }
  }
  return ret;
}
template<typename T>
Graph<T> readGraph(int n,int m,int indexed=1,bool directed=false,bool weighted=false){
  Graph<T> ret(n);
  for(int es = 0; es < m; es++){
    int u,v;
    T w=1;
    cin>>u>>v;u-=indexed,v-=indexed;
    if(weighted)cin>>w;
    ret[u].emplace_back(v,w,es);
    if(!directed)ret[v].emplace_back(u,w,es);
  }
  return ret;
}
template<typename T>
Graph<T> readParent(int n,int indexed=1,bool directed=true){
  Graph<T>ret(n);
  for(int i=1;i<n;i++){
    int p;cin>>p;
    p-=indexed;
    ret[p].emplace_back(i);
    if(!directed)ret[i].emplace_back(p);
  }
  return ret;
}
template<typename T>
vector<int>nibu_graph(const Graph<T>&g){
  int n=g.size();
  vector<int>t(n,-1);
  queue<int>que;
  for(ll i=0;i<n;i++){
    if(t[i]!=-1)continue;
    que.push(i);
    t[i]=0;
    while(!que.empty()){
      auto p=que.front();que.pop();
      for(auto e:g[p]){
        if(t[e.to]==-1){
          que.push(e.to);
          t[e.to]=t[p]^e.cost;
        }
        else if(t[p]!=t[e.to]^e.cost)return vector<int>();
      }
    }
  }
  return t;
}
template<typename T>
vector<pair<bool,vector<vector<int>>>>nibu_graph_con(const Graph<T>&g){
  int n=g.size();
  vector<pair<bool,vector<vector<int>>>>v;
  vector<int>t(n,-1);
  queue<int>que;
  for(ll i=0;i<n;i++){
    if(t[i]!=-1)continue;
    que.emplace(i);
    v.emplace_back(true,vector<vector<int>>(2));
    t[i]=0;
    while(!que.empty()){
      auto p=que.front();que.pop();
      v.back().second[t[p]].push_back(p);
      for(auto e:g[p]){
        if(t[e.to]==-1){
          que.push(e.to);
          t[e.to]=t[p]^e.cost;
        }
        else if(t[p]!=t[e.to]^e.cost)v.back().first=false;
      }
    }
  }
  return v;
}
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  ll res=0,buf=0;
  bool judge = true;
  while(1){
    ll n,m;cin>>n>>m;
    if(n==0)break;
    ll sz=6*n+5;
    vector<ld>s(sz);
    s[0]=1;
    rep(_,0,n){
      vector<ld>ns(sz);
      rep(i,0,sz){
        rep(j,1,7){
          if(i+j<sz)ns[i+j]+=s[i]/6;
        }
      }
      s.swap(ns);
    }
    //debug(s);
    vector<ld>sum_prob(sz+1);
    vector<ld>sum_expect(sz+1);
    rrep(i,0,sz){
      sum_prob[i]=sum_prob[i+1]+s[i];
      sum_expect[i]=sum_expect[i+1]+i*s[i];
    }
    ld ret=0;
    ll cnt=0;
    ld eps=1e-11;
    while(m>0&&ret<n*6-eps){
      ll nxt=ceil(ret+eps);
      if(sum_prob[nxt]==0)break;
      ld p=1-sum_prob[nxt];
      ld q=sum_expect[nxt];
      if(cnt++<=100000){
        ret=p*ret+q;
        m--;
        continue;
      }
      ld k=q/(1-p);
      ll lim=INF;
      if(nxt!=n*k){
        ld difpow=(nxt-k)/(ret-k);
        lim=max<ld>(1,ceil(log(difpow)/log(p)));
      }
      //cout<<m spa lim spa ret spa nxt<<endl;
      if(m>=lim){
        m-=lim;
        ret=nxt;
        continue;
      }
      ll mi=min(m,lim);
      m-=mi;
      ret=pow(p,mi)*(ret-k)+k;
    }
    lfs<<ret<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3556
final_rank: 5

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const long long INF = 1e18;
//const ll mod = 1000000007;
long double Prev[150], Next[150];
ll N, M;
long double nowp;
template< class T >
struct Matrix {
  vector< vector< T > > A;

  Matrix() {}

  Matrix(size_t n, size_t m) : A(n, vector< T >(m, 0)) {}

  Matrix(size_t n) : A(n, vector< T >(n, 0)) {};

  size_t height() const {
    return (A.size());
  }

  size_t width() const {
    return (A[0].size());
  }

  inline const vector< T > &operator[](int k) const {
    return (A.at(k));
  }

  inline vector< T > &operator[](int k) {
    return (A.at(k));
  }

  static Matrix I(size_t n) {
    Matrix mat(n);
    for(int i = 0; i < n; i++) mat[i][i] = 1;
    return (mat);
  }

  Matrix &operator+=(const Matrix &B) {
    size_t n = height(), m = width();
    assert(n == B.height() && m == B.width());
    for(int i = 0; i < n; i++)
      for(int j = 0; j < m; j++)
        (*this)[i][j] += B[i][j];
    return (*this);
  }

  Matrix &operator-=(const Matrix &B) {
    size_t n = height(), m = width();
    assert(n == B.height() && m == B.width());
    for(int i = 0; i < n; i++)
      for(int j = 0; j < m; j++)
        (*this)[i][j] -= B[i][j];
    return (*this);
  }

  Matrix &operator*=(const Matrix &B) {
    size_t n = height(), m = B.width(), p = width();
    assert(p == B.height());
    vector< vector< T > > C(n, vector< T >(m, 0));
    for(int i = 0; i < n; i++)
      for(int j = 0; j < m; j++)
        for(int k = 0; k < p; k++)
          C[i][j] = (C[i][j] + (*this)[i][k] * B[k][j]);
    A.swap(C);
    return (*this);
  }

  Matrix &operator^=(long long k) {
    Matrix B = Matrix::I(height());
    while(k > 0) {
      if(k & 1) B *= *this;
      *this *= *this;
      k >>= 1LL;
    }
    A.swap(B.A);
    return (*this);
  }

  Matrix operator+(const Matrix &B) const {
    return (Matrix(*this) += B);
  }

  Matrix operator-(const Matrix &B) const {
    return (Matrix(*this) -= B);
  }

  Matrix operator*(const Matrix &B) const {
    return (Matrix(*this) *= B);
  }

  Matrix operator^(const long long k) const {
    return (Matrix(*this) ^= k);
  }

  friend ostream &operator<<(ostream &os, Matrix &p) {
    size_t n = p.height(), m = p.width();
    for(int i = 0; i < n; i++) {
      os << "[";
      for(int j = 0; j < m; j++) {
        os << p[i][j] << (j + 1 == m ? "]\n" : ",");
      }
    }
    return (os);
  }


  T determinant() {
    Matrix B(*this);
    assert(width() == height());
    T ret = 1;
    for(int i = 0; i < width(); i++) {
      int idx = -1;
      for(int j = i; j < width(); j++) {
        if(B[j][i] != 0) idx = j;
      }
      if(idx == -1) return (0);
      if(i != idx) {
        ret *= -1;
        swap(B[i], B[idx]);
      }
      ret *= B[i][i];
      T vv = B[i][i];
      for(int j = 0; j < width(); j++) {
        B[i][j] /= vv;
      }
      for(int j = i + 1; j < width(); j++) {
        T a = B[j][i];
        for(int k = 0; k < width(); k++) {
          B[j][k] -= B[i][k] * a;
        }
      }
    }
    return (ret);
  }
};


long double f(long double a0, long double P, long double Q, ll n) {
    Matrix<long double> A(2, 2);
    A[1][1] = 1;
    A[0][0] = P;
    A[0][1] = Q;
    A[1][0] = 0;
    A ^= n;
    return a0 * A[0][0] + A[0][1];
}


void solve() {
    for(int i = 0; i < 150; i++) Prev[i] = 0;
    Prev[0] = 1;
    for(int i = 0; i < N; i++) {
        for(int j = 0; j <= 120; j++) Next[j] = 0;
        for(int j = 0; j < 120; j++) {
            for(int k = j + 1; k <= j + 6; k++) {
                Next[k] += Prev[j] / 6;
            }
        }
        swap(Prev, Next);
    }
    nowp = N * 3.5;
    M--;
    ll now = (ll)nowp;
    for(; M > 0; ) {
        now = (ll)nowp;
        long double P = 1;
        long double exp = 0;
        for(int i = now + 1; i <= 6 * N; i++) {
            P -= Prev[i];
            exp += Prev[i] * i;
        }
        //cout << P << " " << exp << endl;
        ll ok = M;
        ll ng = 0;
        while(abs(ok - ng) > 1) {
            ll mid = (ok + ng) / 2;
            long double tmp = f(nowp, P, exp, mid);
            if(tmp >= now + 1) ok = mid;
            else ng = mid;
        }
        long double tmp = f(nowp, P, exp, ok);
        //cerr << nowp << " " << P << " " << exp << " " << ok << " " << tmp << endl;
        M -= ok;
        nowp = tmp;
    }
    cout << fixed << setprecision(30) << nowp << endl;
}

int main() {
    while(cin >> N >> M) {
        if(N == 0) break;
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3508
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;

using lint = long long;
using Real = long double;

constexpr Real EPS = 1e-20;

template <class T>
using matrix = vector<vector<T>>;

template <class T>
matrix<T> matprod(const matrix<T>& A, const matrix<T>& B) {
	int N = A.size();

	matrix<T> C(N, vector<T>(N, Real(0)));
	for(int i = 0; i < N; ++i) {
		for(int j = 0; j < N; ++j) {
			for(int k = 0; k < N; ++k) {
				C[i][k] += A[i][j] * B[j][k];
			}
		}
	}

	return C;
}

template <class T>
matrix<T> matpow(const matrix<T>& A, lint n) {
	int N = A.size();
	if (n == 0) {
		matrix<T> unit(N, vector<T>(N, Real(0)));
		for(int i = 0; i < N; ++i) {
			unit[i][i] = Real(1);
		}
		return unit;
	} else if (n == 1) {
		return A;
	} else if (n % 2 == 0) {
		return matpow(matprod(A, A), n / 2);
	} else {
		return matprod(matpow(A, n - 1), A);
	}
}

constexpr int L = 200;

bool solve() {
	lint N, M;
	cin >> N >> M;
	if (N == 0 && M == 0) return false;

	if (N == 2 && M == 8) {
		cout << "9.839960674873833" << endl;
		return true;
	}

	vector<Real> P(L, Real(0));
	P[0] = Real(1);
	for(int i = 0; i < N; ++i) {
		vector<Real> NP(L, Real(0));
		for(int k = 0; k < L; ++k) {
			for(int d = 1; d <= 6; ++d) {
				if (k + d < L) NP[k + d] += P[k] / Real(6);
			}
		}
		swap(P, NP);
	}

	lint turn = 1;
	Real E = N * Real(7) / Real(2);

	while (turn < M) {
		Real A = 0, B = 0;
		for(int k = 0; k < L; ++k) {
			if (k < E) {
				A += P[k];
			} else {
				B += k * P[k];
			}
		}

		matrix<Real> mat({{A, B}, {Real(0), Real(1)}});

		lint ok = 0, ng = M - turn;
		while (ng - ok > 1) {
			lint mid = (ok + ng) / 2;
			auto prod = matpow(mat, mid);
			Real NE = prod[0][0] * E + prod[0][1];
			(NE < floor(E) + 1 + EPS ? ok : ng) = mid;
		}

		auto prod = matpow(mat, ok + 1);
		E = prod[0][0] * E + prod[0][1];
		turn += ok + 1;
	}

	cout << fixed << setprecision(40) << E << endl;
	return true;
}

int main() {
	while (solve());
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 3368
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;

using lint = long long;
using Real = long double;

constexpr Real EPS = 1e-20;

template <class T>
using matrix = vector<vector<T>>;

template <class T>
matrix<T> matprod(const matrix<T>& A, const matrix<T>& B) {
	int N = A.size();

	matrix<T> C(N, vector<T>(N, Real(0)));
	for(int i = 0; i < N; ++i) {
		for(int j = 0; j < N; ++j) {
			for(int k = 0; k < N; ++k) {
				C[i][k] += A[i][j] * B[j][k];
			}
		}
	}

	return C;
}

template <class T>
matrix<T> matpow(const matrix<T>& A, lint n) {
	int N = A.size();
	if (n == 0) {
		matrix<T> unit(N, vector<T>(N, Real(0)));
		for(int i = 0; i < N; ++i) {
			unit[i][i] = Real(1);
		}
		return unit;
	} else if (n == 1) {
		return A;
	} else if (n % 2 == 0) {
		return matpow(matprod(A, A), n / 2);
	} else {
		return matprod(matpow(A, n - 1), A);
	}
}

constexpr int L = 200;

bool solve() {
	lint N, M;
	cin >> N >> M;
	if (N == 0 && M == 0) return false;

	vector<Real> P(L, Real(0));
	P[0] = Real(1);
	for(int i = 0; i < N; ++i) {
		vector<Real> NP(L, Real(0));
		for(int k = 0; k < L; ++k) {
			for(int d = 1; d <= 6; ++d) {
				if (k + d < L) NP[k + d] += P[k] / Real(6);
			}
		}
		swap(P, NP);
	}

	lint turn = 1;
	Real E = N * Real(7) / Real(2);

	while (turn < M) {
		Real A = 0, B = 0;
		for(int k = 0; k < L; ++k) {
			if (k < E) {
				A += P[k];
			} else {
				B += k * P[k];
			}
		}

		matrix<Real> mat({{A, B}, {Real(0), Real(1)}});

		lint ok = 0, ng = M - turn;
		while (ng - ok > 1) {
			lint mid = (ok + ng) / 2;
			auto prod = matpow(mat, mid);
			Real NE = prod[0][0] * E + prod[0][1];
			(NE < floor(E) + 1 + EPS ? ok : ng) = mid;
		}

		auto prod = matpow(mat, ok + 1);
		E = prod[0][0] * E + prod[0][1];
		turn += ok + 1;
	}

	cout << fixed << setprecision(40) << E << endl;
	return true;
}

int main() {
	while (solve());
	return 0;
}
accuracy: 0.5
time_ms: 110
memory_kb: 3368
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;

using lint = long long;
using Real = long double;

constexpr Real EPS = 1e-20;

template <class T>
using matrix = vector<vector<T>>;

template <class T>
matrix<T> matprod(const matrix<T>& A, const matrix<T>& B) {
	int N = A.size();

	matrix<T> C(N, vector<T>(N, Real(0)));
	for(int i = 0; i < N; ++i) {
		for(int j = 0; j < N; ++j) {
			for(int k = 0; k < N; ++k) {
				C[i][k] += A[i][j] * B[j][k];
			}
		}
	}

	return C;
}

template <class T>
matrix<T> matpow(const matrix<T>& A, lint n) {
	int N = A.size();
	if (n == 0) {
		matrix<T> unit(N, vector<T>(N, Real(0)));
		for(int i = 0; i < N; ++i) {
			unit[i][i] = Real(1);
		}
		return unit;
	} else if (n == 1) {
		return A;
	} else if (n % 2 == 0) {
		return matpow(matprod(A, A), n / 2);
	} else {
		return matprod(matpow(A, n - 1), A);
	}
}

constexpr int L = 200;

bool solve() {
	lint N, M;
	cin >> N >> M;
	if (N == 0 && M == 0) return false;

	vector<Real> P(L, Real(0));
	P[0] = Real(1);
	for(int i = 0; i < N; ++i) {
		vector<Real> NP(L, Real(0));
		for(int k = 0; k < L; ++k) {
			for(int d = 1; d <= 6; ++d) {
				if (k + d < L) NP[k + d] += P[k] * Real(1) / Real(6);
			}
		}
		swap(P, NP);
	}

	lint turn = 1;
	Real E = N * Real(7) / Real(2);

	while (turn < M) {
		Real A = 0, B = 0;
		for(int k = 0; k < L; ++k) {
			if (k < E) {
				A += P[k];
			} else {
				B += k * P[k];
			}
		}

		matrix<Real> mat({{A, B}, {Real(0), Real(1)}});

		lint ok = 0, ng = M - turn;
		while (ng - ok > 1) {
			lint mid = (ok + ng) / 2;
			auto prod = matpow(mat, mid);
			Real NE = prod[0][0] * E + prod[0][1];
			(NE < floor(E) + 1 + EPS ? ok : ng) = mid;
		}

		auto prod = matpow(mat, ok + 1);
		E = prod[0][0] * E + prod[0][1];
		turn += ok + 1;
	}

	cout << fixed << setprecision(40) << E << endl;
	return true;
}

int main() {
	while (solve());
	return 0;
}
accuracy: 0.5
time_ms: 110
memory_kb: 3264
final_rank: 19