#include <cstdio>
#include <cstring>
#include <algorithm>
const int MAXN = 50 + 10;
const int MOD = 1e9 + 7;
typedef long long LL;

LL n;
int k;
namespace {
  inline int add(int x) { return x >= MOD ? x - MOD : x; }
  inline int sub(int x) { return x < 0 ? x + MOD : x; }
  inline int mul(int x, int y) { return (long long) x * y % MOD; }
}
namespace solver1 {
  struct Matrix {
    int a[MAXN][MAXN];
    int n;
    void init() { memset(a, 0, sizeof a); }
    void set() {
      init() ;
      for (int i = 1; i <= n; i++) {
        a[i][i] = 1;
      }
    }
    Matrix operator * (const Matrix &rhs) const {
      Matrix ans;
      ans.n = n;
      static long long tmp[MAXN][MAXN];
      static const long long MODLL = (LL) MOD * MOD;
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          tmp[i][j] = 0;
        }
      }
      for (int i = 1; i <= n; i++) {
        for (int k = 1; k <= n; k++) {
          for (int j = 1; j <= n; j++) {
            tmp[i][j] += (LL) a[i][k] * rhs.a[k][j];
            if (tmp[i][j] >= MODLL) tmp[i][j] -= MODLL;
          }
        }
      }

      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
          ans.a[i][j] = tmp[i][j] % MOD;
        }
      }

      return ans;
    }
  };
  Matrix f[80][MAXN], sump[80][MAXN], sums[80][MAXN];
  void main() {
    static int num[80], cnt = 0;

    while(n) {
      num[++cnt] = n % k;
      n /= k;
    }

    for (int i = 0; i < k; i++) {
      f[0][i].n = k + 1;
      f[0][i].init();
      for (int j = 1; j <= k + 1; j++) {
        f[0][i].a[j][j] = 1;
        f[0][i].a[i + 1][j] = 1;
      }
    }
    sump[0][0] = f[0][0];
    sums[0][k - 1] = f[0][k - 1];

    for (int i = 1; i < k; i++) {
      sump[0][i] = f[0][i] * sump[0][i - 1];
    }

    for (int i = k - 2; i >= 0; i--) {
      sums[0][i] = sums[0][i + 1] * f[0][i];
    }

    for (int i = 1; i < cnt; i++) {
      for (int j = 0; j < k; j++) {
        f[i][j] = j == 0 ? sums[i - 1][j] : sump[i - 1][j - 1] * sums[i - 1][j];
      }

      sump[i][0] = f[i][0];
      sums[i][k - 1] = f[i][k - 1];
      for (int j = 1; j < k; j++) {
        sump[i][j] = f[i][j] * sump[i][j - 1];
      }

      for (int j = k - 2; j >= 0; j--) {
        sums[i][j] = sums[i][j + 1] * f[i][j];
      }
    }

    Matrix ans;
    ans.n = k + 1;
    ans.set();

    int sum = 0;
    for (int i = cnt; i >= 1; i--) {
      for (int j = 0; j < num[i]; j++) {
        ans = f[i - 1][(sum + j) % k] * ans;
      }
      sum += num[i];
      sum %= k;
    }
    //ans = f[0][(sum + num[1]) % k] * ans;

    int res = 0;
    for (int i = 1; i <= k + 1; i++) {
      res = add(res + ans.a[i][k + 1]);
    }

    printf("%d\n", res);

  }
}
int main() {
  scanf("%lld%d", &n, &k);

  solver1::main();
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cassert>
#include<cctype>
#include<climits>
#include<bitset>
#include<deque>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<complex>
#include<functional>
#include<utility>
#include<sstream>
#include<fstream>
using namespace std;

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

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

typedef long long LL;

inline LL gint() {
    char c=getchar();
    int f=1;
    while(c<'0'||c>'9') {
        if(c=='-') {
            f=-1;
        }
        c=getchar();
    }
    LL a=c-'0';
    while((c=getchar())>='0'&&c<='9') {
        a=a*10+c-'0';
    }
    return a*f;
}

#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define foreach(it,x) for(typeof((x).begin()) it=(x).begin(),_end_=(x).end();it!=_end_;++it)
#define REP(i,n) for(int i=0,_end_=(n);i<_end_;i++)
#define FOR(i,l,r) for(int i=(l),_end_=(r);i<=_end_;i++)
#define PER(i,r,l) for(int i=(r),_beg_=(l);i>=_beg_;i--)
#define Sz(x) (int((x).size()))
#define Al(x) (x).begin(),(x).end()
#define wa(x) cerr<<#x<<" "<<x<<endl
#define _Poi const Poi&
#define _Vec const Vec&
#define _Line const Line&
#define clr(x) memset((x),0,sizeof((x)))
#define low(x) ((x)&(-(x)))
#define Ret(x,y) if(x<y)return 1; else if(x>y)return 0

const int maxk=31,MOD=int(1e9+7);

typedef int Mat[maxk][maxk];

int kb;

inline void mat_mul(Mat A,Mat B,Mat res) {
    static Mat C;
    memset(C,0,sizeof(C));
    REP(i,kb+1)REP(k,kb+1)REP(j,kb+1) {
        C[i][j]=(C[i][j]+(LL)A[i][k]*B[k][j])%MOD;
    }
    memcpy(res,C,sizeof(C));
}

Mat A[70][maxk],pre[maxk],suf[maxk],ans,I;
void init_I() {
    clr(I);
    REP(i,kb+1)I[i][i]=1;
}

int dig[70],len;

void prepocess() {
    REP(i,kb) {
        REP(j,kb+1) {
            A[0][i][j][j]=A[0][i][i][j]=1;
        }
    }
    FOR(i,1,len-1) {
        memcpy(pre[0],A[i-1][0],sizeof(A[i-1][0]));
        FOR(j,1,kb-1) {
            mat_mul(A[i-1][j],pre[j-1],pre[j]);
        }
        memcpy(suf[kb-1],A[i-1][kb-1],sizeof(A[i-1][kb-1]));
        PER(j,kb-2,0) {
            mat_mul(suf[j+1],A[i-1][j],suf[j]);
        }
        REP(j,kb) {
            mat_mul(j?pre[j-1]:I,suf[j],A[i][j]);
        }
    }
}

int main() {
    LL n=gint();
    kb=gint();
    init_I();
    while(n) {
        dig[len++]=n%kb;
        n/=kb;
    }
    prepocess();
    ans[kb][0]=1;
    int x=0;
    PER(i,len-1,0) {
        REP(j,dig[i]) {
            mat_mul(A[i][(j+x)%kb],ans,ans);
        }
        x=(x+dig[i])%kb;
    }
    int res=0;
    for(int i=0;i<kb;i++) {
        res=(res+ans[i][0])%MOD;
    }
    printf("%d\n",res+1);
    return 0;
}


#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<math.h>
#include<complex>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<functional>
#include<assert.h>
#include<numeric>
using namespace std;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
using ll = long long;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;
const ll mod=1e9+7 ;

template<typename T>
struct Matrix{
    int h,w;
    vector<T> a;
    Matrix(int n_=0):h(n_),w(n_),a(n_*n_){}
    Matrix(int n_, int m_):h(n_),w(m_),a(n_*m_){}
    Matrix(int n_, int m_, vector<T> a_):h(n_),w(m_),a(a_){}
    T& get(int r,int c){return a[r*w+c];}
    T get(int r,int c)const{return a[r*w+c];}

    Matrix& operator+=(const Matrix& m) {
        assert(h == m.h && w == m.w);
        for (int i = 0; i < w*h; ++i)a[i] += m.a[i];
    }
    Matrix& operator-=(const Matrix& m) {
        assert(h == m.h && w == m.w);
        for (int i = 0; i < w*h; ++i)a[i] -= m.a[i];
    }
    Matrix& operator*=(const Matrix& m) {
        assert(w == m.h);
        Matrix ret(h, m.w);
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < m.w; ++j) {
                for (int k = 0; k < w; ++k) {
                    ret.a[i * m.w + j] += a[i * w + k] * m.a[k * m.w + j]%mod;
                }
            ret.a[i * m.w + j] %= mod;
            }
        }
        return (*this) = ret;
    }
    Matrix operator+(const Matrix& m) const { return Matrix(*this) += m; }
    Matrix operator-(const Matrix& m) const { return Matrix(*this) -= m; }
    Matrix operator*(const Matrix& m) const { return Matrix(*this) *= m; }
};
template<typename T>
Matrix<T> unit(int n){
    Matrix<T> ret(n);
    rep(i,n)ret.get(i,i)=1;
    return ret;
}
template<typename T>
Matrix<T> matpow(Matrix<T> a,int n){
    assert(a.h==a.w);
    Matrix<T> ret=unit<T>(a.h);
    while(n){
        if(n&1)ret*=a;
        a*=a;
        n>>=1;
    }
    return ret;
}

Matrix<ll> a[65];
Matrix<ll> calc(int i, int k){
    return matpow(a[i+k],k-i)*matpow(a[i],i);
}
ll solve(ll n,ll k){
    ll cnt = 0;
    ll tmp = n;
    while(tmp){
        tmp/=k;
        ++cnt;
    }
    Matrix<ll> b[cnt+5],c[cnt+5],d[k+1];
    b[0]=a[k-1];
    c[0]=matpow(b[0],k-1);
    b[1] = calc(k-1, k);
    c[1] = matpow(b[1],k-1);
    Matrix<ll> s = unit<ll>(2*k+1);
    REP(j,2,cnt+2){
        b[j] = calc(k-j%k, k);
        s *= c[j-1];
        b[j] *= s;
        c[j] = matpow(b[j],k-1);
    }
    int idx = 1;
    int rem = n%k;
    n-=rem;
    int q = 0;
    tmp = n;
    if(tmp){while(tmp%k==0){
        ++q;
        tmp/=k;
    }
    }
    q=(k-q%k)%k;
    Matrix<ll> ans = unit<ll>(2*k+1);
    ans = matpow(a[q],rem)*matpow(a[q+k],max(rem-q,0));
    n/=k;
    if(!n){
        return (ans.get(2*k,0)+ans.get(0,0))%mod;
    }
    --n;
    while(n){
        ll t = n%k;
        if(t){
            ans *= matpow(b[idx],t);
        }
        n/=k;
        ++idx;
    }
    ans *= b[1];

    return (ans.get(2*k,0)+ans.get(0,0))%mod;
}
int main(){
    ll n,k;
    cin>>n>>k;
    rep(i,2*k+1){
        a[i]=Matrix<ll>(2*k+1);
        rep(j,i)a[i].get(0,j)=1;
        rep(j,2*k-1)a[i].get(j+1,j)=1;
        a[i].get(2*k,0)=1;
        a[i].get(2*k,2*k)=1;
    }
    cout<<solve(n,k)<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
typedef long long ll;
inline int read(){
	int x;
	char c;
	int f=1;
	while((c=getchar())!='-' && (c<'0' || c>'9'));
	if(c=='-') c=getchar(),f=-1;
	x=c^'0';
	while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
	return x*f;
}
inline ll readll(){
	ll x;
	char c;
	ll f=1;
	while((c=getchar())!='-' && (c<'0' || c>'9'));
	if(c=='-') c=getchar(),f=-1;
	x=c^'0';
	while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
	return x*f;
}
const int maxn=32,mod=1e9+7;
inline void add(int &x,int y){
	x+=y;
	if(x>=mod) x-=mod;
}
int n;
struct Matrix{
	int a[maxn][maxn];
	void clear(){
		memset(a,0,sizeof(a));
	}
	void output(){
		REP(i,1,n+1) REP(j,1,n+1) printf("%d%c",a[i][j],j==jend?'\n':' ');
		putchar('\n');
	}
	Matrix operator *(const Matrix &rhs) const{
		Matrix B;
		B.clear();
		REP(i,1,n+1) REP(j,1,n+1) REP(k,1,n+1) add(B.a[i][j],1ll*a[i][k]*rhs.a[k][j]%mod);
		return B;
	}
};
Matrix ans,E,A[maxn],pre[maxn],suf[maxn];
int main(){
#ifndef ONLINE_JUDGE
	freopen("matrix.in","r",stdin);
	freopen("matrix.out","w",stdout);
#endif
	ll m=readll();
	n=read();E.clear();
	REP(i,1,n+1) E.a[i][i]=1;
	ans=E;
	REP(i,1,n){
		A[i]=E;
		REP(j,1,n+1) A[i].a[j][i]=1;
	}
	pre[0]=suf[n+1]=E;
	for(;m;m/=n){
		ll u=m%n;
		if(u){
			ll s=0;
			for(ll v=m;v;v/=n) s=(s+v/n)%n;
			u=(s+u-1)%n+1;
			for(;u!=s;--u){
				if(u<=0) u+=n;
				ans=A[u]*ans;
			}
		}
		REP(i,1,n) pre[i]=pre[i-1]*A[i];
		DREP(i,n,1) suf[i]=A[i]*suf[i+1];
		REP(i,1,n) A[i]=suf[i]*pre[i-1];
	}
	int num=1;
	REP(i,1,n) add(num,ans.a[n+1][i]);
	printf("%d\n",num);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Mod=1e9+7;
typedef long long ll;
ll n;
int m,K,sum,now,a[110];
void ADD(int &x,int y,int m){
	x+=y; if (x>=m) x-=m;
}
struct Matrix{
	int v[35][35];
	Matrix(){ memset(v,0,sizeof(v));}
	Matrix operator*(const Matrix &a) const{
		Matrix res;
		for (int k=0;k<=K;k++)
			for (int i=0;i<=K;i++)
				if (v[i][k])
					for (int j=0;j<=K;j++)
						if (a.v[k][j])
							res.v[i][j]=(1ll*v[i][k]*a.v[k][j]+res.v[i][j])%Mod;
		return res;
	}
} ans,/*hanhan,*/s[75][35],pre[75][35],suf[75][35];
void work(ll n){
	ll tmp=n;
	while (tmp){
		a[++m]=tmp%K;
		tmp/=K;
	}
	reverse(a+1,a+m+1);
}
int main(){
	scanf("%lld%d",&n,&K);
//	n++;
	work(n);
	for (int i=0;i<K;i++){
		for (int j=0;j<=K;j++) s[0][i].v[j][j]=1;
		for (int j=0;j<=K;j++) s[0][i].v[i][j]=1;
	}
//	hanhan=s[0][0]*s[0][1]*s[0][2]*s[0][3]*s[0][4]*s[0][5]*s[0][6];
	for (int i=1;i<=m;i++){
		pre[i-1][0]=s[i-1][0]; suf[i-1][K-1]=s[i-1][K-1];
		for (int j=1;j<K;j++) pre[i-1][j]=pre[i-1][j-1]*s[i-1][j];
		for (int j=K-2;j>=0;j--) suf[i-1][j]=s[i-1][j]*suf[i-1][j+1];
		for (int j=0;j<K;j++)
			if (j) s[i][j]=suf[i-1][j]*pre[i-1][j-1];
			else s[i][j]=suf[i-1][j];
	}
	for (int i=0;i<=K;i++)
		for (int j=0;j<=K;j++)
			ans.v[i][j]=(i==j);
	now=0;
	for (int i=1;i<=m;i++){
		//now+0,now+1,...,now+a[i]-1
		if (a[i]){
			if (now+a[i]-1>=K){
				for (int j=now;j<K;j++) ans=ans*s[m-i][j];
				for (int j=0;j<=(now+a[i]-1)-K;j++) ans=ans*s[m-i][j];
			} else
				for (int j=now;j<=now+a[i]-1;j++) ans=ans*s[m-i][j];
			ADD(now,a[i],K);
		}
	}
	for (int i=0;i<=K;i++) ADD(sum,ans.v[i][K],Mod);
	printf("%d\n",sum);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define N 33
#define int long long
int bin[N*2],n,m;
struct matrix{
    int mat[N][N];
    inline matrix operator * (const matrix &a) const {
        matrix res;
        memset(res.mat,0,sizeof(res.mat));
        for (int i=0;i<=m;++i){
            for (int j=0;j<=m;++j){
                for (int k=0;k<=m;++k){
                    res.mat[i][j]=(res.mat[i][j]+mat[i][k]*a.mat[k][j])%mod;
                }
            }
        }
        return res;
    }
}ans,P[N*2][N],S[N*2][N],A[N*2][N];
int read(){
    int x=0,f=1;
    char ch=getchar();
    while (ch<'0' || ch>'9'){
        if (ch=='-') f=-1;
        ch=getchar();
    }
    while (ch>='0' && ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }
    return x*f;
}
signed main(){
    n=read(),m=read();
    int n2=n,len=-1;
    while (n2){
        len++;bin[len]=n2%m;n2=n2/m;
    }
    len++;
    for (int i=0;i<=m;++i) ans.mat[0][i]=1;
    for (int i=0;i<len;++i){
        for (int j=0;j<=m;++j) A[i][0].mat[j][j]=1;
        if (!i){
            for (int j=0;j<m;++j){
                A[i][j].mat[m][m]=1;
                for (int k=0;k<m;++k){
                    if (k!=j){
                        A[i][j].mat[k][k]=1;
                        continue;
                    }
                    for (int l=0;l<=m;++l) A[i][j].mat[k][l]=1;
                }
            }
        }else{
            for (int j=0;j<m;++j){
                if (!j) A[i][j]=S[i-1][0];
                else A[i][j]=S[i-1][j]*P[i-1][j-1];
            }
        }
        P[i][0]=A[i][0];
        for (int j=1;j<m;++j) P[i][j]=P[i][j-1]*A[i][j];
        S[i][m-1]=A[i][m-1];
        for (int j=m-2;j>=0;--j) S[i][j]=A[i][j]*S[i][j+1];
    }
    int j=0;
    for (int i=len-1;i>=0;--i){
        while (bin[i] --> 0){
            ans=ans*A[i][j];j++;if (j==m) j=0;
        }
    }
    cout<<ans.mat[0][m]<<endl;
}


#define _CRT_SECURE_NO_WARNINGS
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <set>
#include <map>
#include <queue>
#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <cctype>
#include <cassert>
#include <limits>
#include <functional>
#include <complex>
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
#if defined(_MSC_VER) || __cplusplus > 199711L
#define aut(r,v) auto r = (v)
#else
#define aut(r,v) typeof(v) r = (v)
#endif
#define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)
#define all(o) (o).begin(), (o).end()
#define pb(x) push_back(x)
#define mp(x,y) make_pair((x),(y))
#define mset(m,v) memset(m,v,sizeof(m))
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
using namespace std;
typedef vector<int> vi; typedef pair<int,int> pii; typedef vector<pair<int,int> > vpii;
typedef long long ll; typedef vector<long long> vl; typedef pair<long long,long long> pll; typedef vector<pair<long long,long long> > vpll;
typedef vector<string> vs; typedef long double ld;
template<typename T, typename U> inline void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> inline void amax(T &x, U y) { if(x < y) x = y; }

template<int MOD>
struct ModInt {
	static const int Mod = MOD;
	unsigned x;
	ModInt(): x(0) { }
	ModInt(signed sig) { int sigt = sig % MOD; if(sigt < 0) sigt += MOD; x = sigt; }
	ModInt(signed long long sig) { int sigt = sig % MOD; if(sigt < 0) sigt += MOD; x = sigt; }
	int get() const { return (int)x; }

	ModInt &operator+=(ModInt that) { if((x += that.x) >= MOD) x -= MOD; return *this; }
	ModInt &operator-=(ModInt that) { if((x += MOD - that.x) >= MOD) x -= MOD; return *this; }
	ModInt &operator*=(ModInt that) { x = (unsigned long long)x * that.x % MOD; return *this; }

	ModInt operator+(ModInt that) const { return ModInt(*this) += that; }
	ModInt operator-(ModInt that) const { return ModInt(*this) -= that; }
	ModInt operator*(ModInt that) const { return ModInt(*this) *= that; }
};
typedef ModInt<1000000007> mint;

struct Matrix {
	typedef mint Num;
	vector<vector<Num> > v, w;
	Matrix() {}
	Matrix(int n, int m): v(n, vector<Num>(m)) { }
	inline int height() const { return (int)v.size(); }
	inline int width() const { return (int)v[0].size(); }
	inline Num& at(int i, int j) { return v[i][j]; }
	inline const Num& at(int i, int j) const { return v[i][j]; }
	static Matrix identity(int n) {
		Matrix A(n, n);
		rep(i, n) A.at(i, i) = 1;
		return A;
	}
	inline static Matrix identity(const Matrix& A) { return identity(A.height()); }
	Matrix& operator*=(const Matrix& B) {
		int n = height(), m = B.width(), p = B.height();
		assert(p == width());
		w.assign(n, vector<Num>(m, 0));
		rep(i, n) rep(j, m) {
			Num x = 0;
			rep(k, p) x += at(i, k) * B.at(k, j);
			w[i][j] = x;
		}
		v.swap(w);
		return *this;
	}
};
Matrix operator^(const Matrix& t, ll k) {
	Matrix A = t, B = Matrix::identity(t);
	while(k) {
		if(k & 1) B *= A;
		A *= A;
		k >>= 1;
	}
	return B;
}

Matrix getRotateMatrix(int k, int t) {
	t = (t % k + k) % k;
	Matrix A(k + 3, k + 3);
	rep(i, k)
		A.at(i, (i + t) % k) = 1;
	A.at(k, k) = A.at(k+1, k+1) = A.at(k+2, k+2) = 1;
	return A;
}

Matrix getSingletonMatrix(int k, int j) {
	assert(0 <= j && j < k);
	Matrix A(k + 3, k + 3);
	rep(i, k) if(i != j)
		A.at(i, i) += 1;
	A.at(k + 1, k + 1) = A.at(k + 2, k + 2) = 1;

	A.at(k, k + 1) += 1;
//	A.at(k + 2, k + 1) += 1;
	A.at(j, k + 1) -= 1;

	A.at(k, k) += 2;
//	A.at(k + 2, k) += 1;
	A.at(j, k) -= 1;

	A.at(k, j) += 1;
//	A.at(k + 2, j) += 1;
//	A.at(j, j) -= 1;
	return A;
}

int s_k(int k, long long j) {
	long long t = j; int u = 0;
	while(t > 0) {
		(u += t % k) %= k;
		t /= k;
	}
	return u;
}

int main() {
	long long n; int k;
	while(cin >> n >> k) {
	Matrix b(1, k + 3);
	b.at(0, k) = 1;
	b.at(0, k + 1) = b.at(0, k + 2) = 1;
	/*
	{
		Matrix bb = b;
			rep(i, k+3) cerr << bb.at(0, i).get() << ", "; cerr << endl;
		for(int j = 0; j < n; ++ j) {
			int u = s_k(k, j);
			Matrix A = getSingletonMatrix(k, u);
			bb *= A;
			rep(i, k+3) cerr << bb.at(0, i).get() << ", "; cerr << endl;
		}
		rep(j, n) cerr << s_k(k, j) << ", "; cerr << endl;
		mint ans2 = bb.at(0, k + 1);
		cerr << "ans2 = " << ans2.get() << endl;
	}
//	*/
	long long powk = 1; int digits = 0;
	while(powk <= n / k) powk *= k, ++ digits;

	vector<Matrix> P(digits + 1);
	P[0] = getSingletonMatrix(k, 0);
	rer(i, 1, digits) {
		P[i] = Matrix::identity(k + 3);
		rep(j, k) {
			P[i] *= P[i-1];
			P[i] *= getRotateMatrix(k, -1);
		}
	}

	long long offset = 0;
	while(powk > 0) {
		int t = (int)((n - offset) / powk);
		rep(j, t) {
			int s = s_k(k, offset);
			b *= getRotateMatrix(k, -s);
			b *= P[digits];
			b *= getRotateMatrix(k, +s);
			offset += powk;
		}
		powk /= k;
		-- digits;
	}

	mint ans = b.at(0, k + 1);
	cout << ans.get() << endl;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
typedef long long ll;
inline int read(){
	int x;
	char c;
	int f=1;
	while((c=getchar())!='-' && (c<'0' || c>'9'));
	if(c=='-') c=getchar(),f=-1;
	x=c^'0';
	while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
	return x*f;
}
inline ll readll(){
	ll x;
	char c;
	ll f=1;
	while((c=getchar())!='-' && (c<'0' || c>'9'));
	if(c=='-') c=getchar(),f=-1;
	x=c^'0';
	while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
	return x*f;
}
const int maxn=32,mod=1e9+7;
inline void add(int &x,int y){
	x+=y;
	if(x>=mod) x-=mod;
}
int n;
struct Matrix{
	int a[maxn][maxn];
	void clear(){
		memset(a,0,sizeof(a));
	}
	void output(){
		REP(i,1,n+1) REP(j,1,n+1) printf("%d%c",a[i][j],j==jend?'\n':' ');
		putchar('\n');
	}
	Matrix operator *(const Matrix &rhs) const{
		Matrix B;
		B.clear();
		REP(i,1,n+1) REP(j,1,n+1) REP(k,1,n+1) add(B.a[i][j],1ll*a[i][k]*rhs.a[k][j]%mod);
		return B;
	}
};
Matrix ans,E,A[maxn],pre[maxn],suf[maxn];
int main(){
#ifndef ONLINE_JUDGE
	freopen("matrix.in","r",stdin);
	freopen("matrix.out","w",stdout);
#endif
	ll m=readll();
	n=read();E.clear();
	REP(i,1,n+1) E.a[i][i]=1;
	ans=E;
	REP(i,1,n){
		A[i]=E;
		REP(j,1,n+1) A[i].a[j][i]=1;
	}
	pre[0]=suf[n+1]=E;
	for(;m;m/=n){
		ll u=m%n;
		if(u){
			ll s=0;
			for(ll v=m/n;v;v/=n) s=(s+v%n)%n;
			u=(s+u-1)%n+1;
			for(;u!=s;--u){
				if(u<=0) u+=n;
				ans=A[u]*ans;
			}
		}
		REP(i,1,n) pre[i]=pre[i-1]*A[i];
		DREP(i,n,1) suf[i]=A[i]*suf[i+1];
		REP(i,1,n) A[i]=suf[i]*pre[i-1];
	}
	int num=1;
	REP(i,1,n) add(num,ans.a[n+1][i]);
	printf("%d\n",num);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll L[1050];
int num=0;
void dfs(int len,int p,int v)
{
    if(p==len)
    {
        L[++num]=v;
        return;
    }
    dfs(len,p+1,v*10+4);
    dfs(len,p+1,v*10+7);
}

ll contain(ll x1,ll y1,ll x2,ll y2)
{
    ll l=max(x1,x2);
    ll r=min(y1,y2);
    return r-l+1>0?r-l+1:0;
}

int main()
{
    for(int len=1;len<=9;len++) dfs(len,0,0);
    L[0]=0;
    L[++num]=1000000000;
    //for(int i=1;i<=num;i++) printf("%d  %lld\n",i,L[i]);
    ll Pl,Pr,Vl,Vr;
    int k;
    scanf("%lld%lld%lld%lld%d",&Pl,&Pr,&Vl,&Vr,&k);
    ll sum=0;
    for(int i=1;i<=1022-k+1;i++)
    {
        int j=i+k-1;
        sum+=contain(L[i-1]+1,L[i],Pl,Pr)*contain(L[j],L[j+1]-1,Vl,Vr);
        if(L[i]>Pr) break;
    }

    for(int i=1;i<=1022-k+1;i++)
    {
        int j=i+k-1;
        sum+=contain(L[i-1]+1,L[i],Vl,Vr)*contain(L[j],L[j+1]-1,Pl,Pr);
        if(L[i]>Vr) break;
    }

    if(k==1)
    {
        for(int i=1;i<=1022;i++)
        {
            if(contain(L[i],L[i],Pl,Pr)&&contain(L[i],L[i],Vl,Vr)) sum--;
        }
    }

    printf("%.10f\n",sum*1.0/(Vr-Vl+1)/(Pr-Pl+1));
}


#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <string>
#include <cassert>

using namespace std;

class Solution {
public:
	vector<pair<int,int>> construct(string& s, string& t) {
		deque<pair<char,int>> qs;
		deque<pair<char,int>> qt;

		int n = s.length();
		int m = t.length();

		for (int i = 0; i < n; ++i) {
			char c = s[i];
			int cnt = 1;
			while (i + 1 < n && s[i + 1] == c) {
				++i;
				++cnt;
			}

			qs.emplace_back(c, cnt);
		}

		for (int i = 0; i < m; ++i) {
			char c = t[i];
			int cnt = 1;
			while (i + 1 < m && t[i + 1] == c) {
				++i;
				++cnt;
			}
			qt.emplace_back(c, cnt);
		}

		vector<pair<int,int>> res;
		res.reserve(n + m + 1000);

		//wa : ba, ababa
		//answer 3 : (b)a, (aba)ba => (a)ba, (b)a => (b)a, a => a, b
		//got 4
		while (qs.size() != 1 || qt.size() != 1) {
			// cout << qs.size() << " " << qt.size() << endl;
			assert(qs.size() > 0 && qt.size() > 0);
			if (qs.empty()) {
				// res.emplace_back(0, qt.front().second);

				// qs.push(qt.front());
				// qt.pop();
				int n = qt.size() / 2;
				if (n % 2 == 0 && n + 1 < qt.size()) {
					++n;
				}
				int cnt = 0;

				while (n-- > 0) {
					cnt += qt.front().second;
					qs.push_back(qt.front());
					qt.pop_front();
				}

				res.emplace_back(0, cnt);

			} else if (qt.empty()) {
				// res.emplace_back(qs.front().second, 0);

				// qt.push(qs.front());
				// qs.pop();

				int n = qs.size() / 2;
				if (n % 2 == 0 && n + 1 < qs.size()) {
					++n;
				}

				int cnt = 0;

				while (n-- > 0) {
					cnt += qs.front().second;
					qt.push_back(qs.front());
					qs.pop_front();
				}

				res.emplace_back(cnt, 0);
			} else if (qs.size() == 1) {
				int n = qt.size() / 2;
				if (n % 2 == 0 && n + 1 < qt.size()) {
					++n;
				}
				int cnt = 0;

				char c = qs.front().first;
				int cnt1 = qs.front().second;
				qs.pop_front();
				while (n-- > 0) {
					cnt += qt.front().second;
					if (n == 0) {
						if (c == qt.front().first) {
							qs.emplace_back(c, qt.front().second + cnt1);
							qt.pop_front();
							cnt1 = 0;
						} else {
							qs.push_back(qt.front());
							qt.pop_front();
							qt.front().second += cnt1;
						}
						break;
					} else {
						qs.push_back(qt.front());
					}
					qt.pop_front();
				}

				res.emplace_back(cnt1, cnt);
			} else if (qt.size() == 1) {
				int n = qs.size() / 2;
				if (n % 2 == 0 && n + 1 < qs.size()) {
					++n;
				}
				int cnt = 0;

				char c = qt.front().first;
				int cnt1 = qt.front().second;
				qt.pop_front();

				while (n-- > 0) {
					cnt += qs.front().second;

					if (n == 0) {
						if (qs.front().first == c) {
							qt.emplace_back(c, qs.front().second + cnt1);
							qs.pop_front();
							cnt1 = 0;
						} else {
							qt.push_back(qs.front());
							qs.pop_front();
							qs.front().second += cnt1;
						}
						break;
					} else {
						qt.push_back(qs.front());
					}
					qs.pop_front();
				}

				res.emplace_back(cnt, cnt1);
			}
			else if (qs.front().first == qt.front().first) {
					// if (qs.size() >= qt.size()) {
					// 	res.emplace_back(qs.front().second, 0);
					// 	qt.front().second += qs.front().second;
					// 	qs.pop();
					// } else {
					// 	res.emplace_back(0, qt.front().second);
					// 	qs.front().second += qt.front().second;
					// 	qt.pop();
					// }

					if (qs.size() >= 2 && qt.size() >= 2) {
						if (qs.size() >= qt.size()) {
							auto p1 = qs.front();
							qs.pop_front();
							auto p2 = qs.front();
							qs.pop_front();

							auto p3 = qt.front();
							qt.pop_front();

							if (qs.empty()) {
								qs.push_front(p3);
							} else {
								qs.front().second += p3.second;
							}
							qt.front().second += p2.second;
							qt.push_front(p1);

							res.emplace_back(p1.second + p2.second, p3.second);

						} else {
							auto p1 = qs.front();
							qs.pop_front();

							auto p2 = qt.front();
							qt.pop_front();
							auto p3 = qt.front();
							qt.pop_front();

							qs.front().second += p3.second;
							qs.push_front(p2);

							qt.front().second += p1.second;

							res.emplace_back(p1.second, p2.second + p3.second);
						}
					} else {
						if (qs.size() >= qt.size()) {
							res.emplace_back(qs.front().second, 0);
							qt.front().second += qs.front().second;
							qs.pop_front();
						} else {
							res.emplace_back(0, qt.front().second);
							qs.front().second += qt.front().second;
							qt.pop_front();
						}
					}
				} else {
					// res.emplace_back(qs.front().second, qt.front().second);

					// char c = qs.front().first;
					// int cnt1 = qs.front().second;
					// int cnt2 = qt.front().second;
					// qs.pop();
					// qt.pop();

					// if (qs.empty()) {
					// 	qs.emplace(c, cnt2);
					// } else {
					// 	qs.front().second += cnt2;
					// }

					// if (qt.empty()) {
					// 	qt.emplace(c, cnt1);
					// } else {
					// 	qt.front().second += cnt1;
					// }

					if (qs.size() > 3 && qt.size() == 2) {
						auto p1 = qs.front(); qs.pop_front();
						auto p2 = qs.front(); qs.pop_front();
						auto p3 = qs.front(); qs.pop_front();

						auto p4 = qt.front(); qt.pop_front();

						res.emplace_back(p1.second + p2.second + p3.second, p4.second);
						qs.front().second += p4.second;

						qt.front().second += p3.second;
						qt.push_front(p2);
						qt.push_front(p1);
						continue;
					} else if (qs.size() == 2 && qt.size() > 3) {
						auto p1 = qs.front(); qs.pop_front();

						auto p2 = qt.front(); qt.pop_front();
						auto p3 = qt.front(); qt.pop_front();
						auto p4 = qt.front(); qt.pop_front();

						res.emplace_back(p1.second, p2.second + p3.second + p4.second);

						qs.front().second += p4.second;
						qs.push_front(p3);
						qs.push_front(p2);

						qt.front().second += p1.second;

						continue;
					}

					int cnt = qs.front().second;
					int cnt1 = qt.front().second;

					res.emplace_back(cnt, cnt1);
					qs.pop_front();
					qt.pop_front();

					qs.front().second += cnt1;
					qt.front().second += cnt;
				}
		}
		return res;
	}
};

int main(int argc, char** argv) {
	ios::sync_with_stdio(false);
	cin.tie(0);

	// int n;
	// cin >> n;

	string s, t;
	cin >> s;
	cin >> t;

	Solution sol;

	auto res = sol.construct(s, t);

	cout << res.size() << endl;
	for (auto& p : res) {
		cout << p.first << " " << p.second << endl;
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN=5e5+5;

struct K{
    int col,len;
    K(int _c=0,int _l=0){
        col=_c,len=_l;
    }
    bool operator ==(const K &b)const{
        return col==b.col;
    }
};
struct ANS{
    int l,r;
    ANS(int _l=0,int _r=0){
        l=_l,r=_r;
    }
}a[MAXN];
int acnt;
deque<K> Ks[4];
char s[4][MAXN];
int slen[4];
void cal(int id){
    int last=0,lcol=s[id][0]-'a';
    for(int i=1;i<slen[id];i++){
        if(s[id][i]!=s[id][i-1]){
            Ks[id].push_back(K(lcol,i-last));
            last=i,lcol=s[id][i]-'a';
        }
    }
    Ks[id].push_back(K(lcol,slen[id]-last));
}
deque<K> tmp[4];
void change(int l,int r){
    for(int i=0;i<l;i++){
        a[acnt].l+=Ks[0].front().len;
        tmp[0].push_back(Ks[0].front());
        Ks[0].pop_front();
    }
    for(int i=0;i<r;i++){
        a[acnt].r+=Ks[1].front().len;
        tmp[1].push_back(Ks[1].front());
        Ks[1].pop_front();
    }
    acnt++;
    while(!tmp[0].empty()){
        if(!Ks[1].empty()&&tmp[0].back()==Ks[1].front())
            Ks[1].front().len+=tmp[0].back().len;
        else
            Ks[1].push_front(tmp[0].back());
        tmp[0].pop_back();
    }
    while(!tmp[1].empty()){
        if(!Ks[0].empty()&&tmp[1].back()==Ks[0].front())
            Ks[0].front().len+=tmp[1].back().len;
        else
            Ks[0].push_front(tmp[1].back());
        tmp[1].pop_back();
    }
}
int main(){
    for(int i=0;i<2;i++){
        scanf("%s",s[i]);
        slen[i]=strlen(s[i]);
        cal(i);
    }
    while(1){
    //    printf("Ks[0] = %d, Ks[1] = %d\n",Ks[0].size(),Ks[1].size());
        if(Ks[0].size()==1&&Ks[1].size()==1)    break;
        if(Ks[0].size()==1){
            if(Ks[1].size()<=3){
                if(Ks[1].front()==Ks[0].front())
                    change(0,1);
                else
                    change(1,1);
            }
            else{
                if(Ks[1].front()==Ks[0].front())
                    change(0,3);
                else
                    change(1,3);
            }
        }
        else if(Ks[1].size()==1){
            if(Ks[0].size()<=3){
                if(Ks[1].front()==Ks[0].front())
                    change(1,0);
                else
                    change(1,1);
            }
            else{
                if(Ks[1].front()==Ks[0].front())
                    change(3,0);
                else
                    change(3,1);
            }
        }
        else if(Ks[0].size()==2){
            if(Ks[1].size()<=3){
                if(Ks[0].front()==Ks[1].front())
                    change(0,1);
                else
                    change(1,1);
            }
            else{
                if(Ks[0].front()==Ks[1].front())
                    change(1,2);
                else
                    change(1,3);
            }
        }
        else if(Ks[1].size()==2){
            if(Ks[0].size()<=3){
                if(Ks[0].front()==Ks[1].front())
                    change(1,0);
                else
                    change(1,1);
            }
            else{
                if(Ks[0].front()==Ks[1].front())
                    change(2,1);
                else
                    change(3,1);
            }
        }
        else{
            if(Ks[0].front()==Ks[1].front()){
                if(Ks[0].size()>Ks[1].size())
                    change(3,2);
                else
                    change(2,3);
            }
            else
                change(1,1);
        }
    }
    printf("%d\n",acnt);
    for(int i=0;i<acnt;i++)
        printf("%d %d\n",a[i].l,a[i].r);

    return 0;
}


 #include <bits/stdc++.h>
using namespace std;
const long long MAX=2e9, N=5e3+10, MOD = 1e9+7;
#define ll long long
#define pi pair<ll,ll>
#define ft first
#define sd second
#define mp make_pair
#define pb push_back

#define VI vector<int>
#define VPI vector<pi>
#define VL vector<ll>
#define int ll
#define PI 3.14159265
#define sz(a) (int)(a.size())
string s, t;
int n;

int bad(string &s, char c){
	int an = s.back() != c;
	for(int i=1; i<s.size(); i++)
        if (s[i] != s[i - 1])++an;
	return an;
}

int ind(int d, string &s){
	if (d == 0)return 0;
	int c = 0;
	for(int i=0; i<s.size();i++){
		if (i + 1 == (int)s.size())return s.size();
		if (s[i] != s[i + 1])++c;
		if (c == d)return i + 1;
	}
	return 0;
}

void trm(string &a, string &b){
	while (!a.empty() && a.back() == 'a')a.pop_back();
	while (!b.empty() && b.back() == 'b')b.pop_back();
}

void kil(string &a, string &b, vector<pair<int, int> > &an){
	trm(a, b);
	while (!a.empty() || !b.empty()){
		an.push_back(make_pair(a.size(), b.size()));
		swap(a, b);
		trm(a, b);
	}
}

vector<pair<int, int> > go(string a, string b){
	vector<pair<int, int> > an;
	int abad = bad(a, 'a'), bbad = bad(b, 'b');
	int df = abs(abad - bbad);
	int need = df >> 1;
	if (need == 0)kil(a, b, an);
	else {
		string *bg = &a, *sm = &b;
		if (abad < bbad)swap(bg, sm);
		int bgn = ind(need, *bg);
		if (df & 1 && (*bg)[bgn - 1] != (*sm)[0])++need;
		string na, nb;
		int lsm = 0, lbg = need;
		if (bbad > 0)++lsm, ++lbg;
		if (sm == &a){
			int inda = ind(lsm, a), indb = ind(lbg, b);
			na = b.substr(0, indb) + a.substr(inda);
			nb = a.substr(0, inda) + b.substr(indb);
			an.push_back(make_pair(inda, indb));
		}else {
			int inda = ind(lbg, a), indb = ind(lsm, b);
			na = b.substr(0, indb) + a.substr(inda);
			nb = a.substr(0, inda) + b.substr(indb);
			an.push_back(make_pair(inda, indb));
		}
		kil(na, nb, an);
	}
	return an;
}

#undef int
int main()
{
    #define int ll
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cerr.tie(0);
    cin>>s>>t;
    n=sz(s);
    VPI res1=go(s, t);
//    if(n>20)
//        cout<<"zmiana";
    VPI res2=go(t, s);
    cout<<min(sz(res1), sz(res2))<<"\n";
    cerr<<"\n";
    if(res2.size() < res1.size())
        for(pi i:res2)
            cout<<i.sd<<" "<<i.ft<<"\n";
    else
        for(pi i:res1)
            cout<<i.ft<<" "<<i.sd<<"\n";
}
/*
aaaaaaaaaaaaaaaaa
ababababababababa
*/


#include <bits/stdc++.h>

using namespace std;

string a, b;
vector<int> l1, l2;

int get_cnt(const string &s) {
	for (int i = 0; i < (int) s.size(); i++) {
		if (s[i] != s[0]) return i;
	}
	return (int) s.size();
}

void op(int c1, int c2) {
	l1.push_back(c1);
	l2.push_back(c2);
	string ra = a.substr(0, c1);
	string rb = b.substr(0, c2);
	a = rb + a.substr(c1);
	b = ra + b.substr(c2);
}

deque<int> getv(const string &s) {
	deque<int> res;
	for (int i = 0; i < (int) s.size(); ) {
		int pos = i;
		while (pos < (int) s.size() && s[pos] == s[i]) pos++;
		res.push_back(pos - i);
		i = pos;
	}
	return res;
}

int solve() {
	int s1 = 0, s2 = 0;
	deque<int> v1 = getv(a);
	deque<int> v2 = getv(b);
	bool f = true;
	while (1) {
		int c1 = v1.front(), c2 = v2.front();
		if ((int) v1.size() == 1 && (int) v2.size() == 1) break;
		if (f && (int) a.size() && (int) b.size() && a[0] == b[0]) {
			l1.push_back(c1);
			l2.push_back(0);
			v1.pop_front();
			s2 += c1;
		}
		else {
			l1.push_back(s1 + c1);
			l2.push_back(s2 + c2);
			v1.pop_front(); v2.pop_front();
			if (v1.empty()) v1.push_back(0);
			if (v2.empty()) v2.push_back(0);
			swap(s1, s2);
			s1 += c2; s2 += c1;
		}
		f = false;
	}
	return (int) l1.size();
}

int get_l(const string &s, int num) {
	if (num == 0) return 0;
	int res = 0;
	for (int i = 0; i < (int) s.size(); ) {
		int pos = i;
		while (s[pos] == s[i]) pos++;
		i = pos;
		res++;
		if (res == num) return pos;
	}
}

void first_op(int c1, int c2) {
	op(get_l(a, c1), get_l(b, c2));
}

int sol(const string &s) {
	int res = 0;
	for (int i = 0; i < (int) s.size(); ) {
		int pos = i;
		while (pos < (int) s.size() && s[pos] == s[i]) pos++;
		i = pos;
		res++;
	}
	return res;
}

bool inv;

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

	cin >> a >> b;
	int c1 = sol(a), c2 = sol(b);
	if (c1 < c2) {
		swap(a, b); swap(c1, c2); inv = true;
	}
	if (a[0] == b[0]) {
		int len = 0;
		while (1) {
			if (len == 0) len = 1, c1--;
			else len += 2, c1 -= 2, c2 += 2;
			if (c1 <= c2 + 1) break;
		}
		int len2 = 0;
		if (c1 + 2 == c2) len--, len2++;
		first_op(len, len2);
	}
	else if (c1 > c2 + 2) {
		int sum = (c1 + c2 - 2) / 2;
		if (c1 % 2 != c2 % 2) {
			if ((c1 - c2) % 4 == 1) first_op(c1 - sum - 1, 1);
			else first_op(c1 - sum, 1);
		}
		else first_op(c1 - sum, 1);
	}

	solve();
	cout << l1.size() << '\n';
	for (int i = 0; i < (int) l1.size(); i++) {
		if (inv) swap(l1[i], l2[i]);
		cout << l1[i] << ' ' << l2[i] << '\n';
	}
}


#include <bits/stdc++.h>

using namespace std;

string s, t;
vector< pair<char, int> > a, b;
vector< pair<int, int> > bleach;
bool flag = false;

void add(vector< pair<char, int> > &tren, pair<char, int> s) {
    if (!tren.empty() && tren.back().first == s.first) tren.back().second += s.second;
    else tren.push_back(s);
}

inline void addchar(vector< pair<char, int> > &tren, char s) {
    add(tren, make_pair(s, 1));
}

int pop(vector< pair<char, int> > &tren, int kol) {
    int sol = 0;
    for (int i = 0; i < kol; i++) {
        sol += tren.back().second;
        tren.erase(tren.end() - 1);
    }
    return sol;
}

void query(int acx, int acy) {
    //printf("query: %d %d\n", acx, acy);
    vector< pair<char, int> > ta, tb;
    for (int i = acx - 1; i >= 0; i--) ta.push_back(a[a.size() - 1 - i]);
    for (int i = acy - 1; i >= 0; i--) tb.push_back(b[b.size() - 1 - i]);
    int kolx = pop(a, acx);
    int koly = pop(b, acy);
    if (flag) swap(kolx, koly);
    bleach.push_back(make_pair(kolx, koly));

    for (int i = 0; i < ta.size(); i++) add(b, ta[i]);
    for (int i = 0; i < tb.size(); i++) add(a, tb[i]);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> s >> t;

    reverse(s.begin(), s.end());
    reverse(t.begin(), t.end());
    for (int i = 0; i < s.size(); i++) addchar(a, s[i]);
    for (int i = 0; i < t.size(); i++) addchar(b, t[i]);

    while (a.size() != 1 || b.size() != 1) {
        int la = a.size();
        int lb = b.size();

        if (la < lb) {
            swap(la, lb);
            swap(a, b);
            flag ^= true;
        }
        const char kuraca = a.back().first;
        const char kuracb = b.back().first;

        //printf("%d %d -> %c %c\n", la, lb, kuraca, kuracb);
        //printf("%d\n", la + lb);
        if (kuraca != kuracb) {
            if (lb <= 2) {
                if (la <= 3) query(1, 1);
                else query(3, 1);
            } else query(1, 1);
        } else {
            if (lb == 1) {
                if (la <= 3) query(1, 0);
                else query(3, 0);
            } else if (lb == 2) {
                if (la == 2) query(1, 0);
                else query(2, 1);
            } else query(3, 2);
        }
        //flag = false;
    }

    printf("%d\n", bleach.size());
    for (int i = 0; i < bleach.size(); i++)
        printf("%d %d\n", bleach[i].first, bleach[i].second);
    return 0;
}


/*
    author:  Maksim1744
    created: 01.11.2020 17:50:30
*/

#include <bits/stdc++.h>

using namespace std;

#define ll   long long
#define ld   long double

#define mp   make_pair
#define pb   push_back
#define eb   emplace_back

#define sum(a)     ( accumulate ((a).begin(), (a).end(), 0ll))
#define mine(a)    (*min_element((a).begin(), (a).end()))
#define maxe(a)    (*max_element((a).begin(), (a).end()))
#define mini(a)    ( min_element((a).begin(), (a).end()) - (a).begin())
#define maxi(a)    ( max_element((a).begin(), (a).end()) - (a).begin())
#define lowb(a, x) ( lower_bound((a).begin(), (a).end(), (x)) - (a).begin())
#define uppb(a, x) ( upper_bound((a).begin(), (a).end(), (x)) - (a).begin())

template<typename T>             vector<T>& operator--            (vector<T>& v){for (auto& i : v) --i;            return  v;}
template<typename T>             vector<T>& operator++            (vector<T>& v){for (auto& i : v) ++i;            return  v;}
template<typename T>             istream& operator>>(istream& is,  vector<T>& v){for (auto& i : v) is >> i;        return is;}
template<typename T>             ostream& operator<<(ostream& os,  vector<T>& v){for (auto& i : v) os << i << ' '; return os;}
template<typename T, typename U> istream& operator>>(istream& is, pair<T, U>& p){is >> p.first >> p.second;        return is;}
template<typename T, typename U> ostream& operator<<(ostream& os, pair<T, U>& p){os << p.first << ' ' << p.second; return os;}
template<typename T, typename U> pair<T,U> operator-(pair<T,U> a, pair<T,U> b){return mp(a.first-b.first, a.second-b.second);}
template<typename T, typename U> pair<T,U> operator+(pair<T,U> a, pair<T,U> b){return mp(a.first+b.first, a.second+b.second);}
template<typename T, typename U> void umin(T& a, U b){if (a > b) a = b;}
template<typename T, typename U> void umax(T& a, U b){if (a < b) a = b;}

#ifdef HOME
#define TAG_LENGTH       25
#define LR_LEFT          left
#define LR_RIGHT         right
#define LR_VALUE         value
#define LR_SECOND_VALUE  mn
#include "C:/C++ libs/print.cpp"
#else
#define showl            42;
#define shows            42;
#define show(...)        42;
#define showm(...)       42;
#define showt(...)       42;
#define printTree(...)   42;
#define printGraph(...)  42;
#define printLRTree(...) 42;
#define printMatrix(...) 42;
#define printWGraph(...) 42;
#define debug     if (false)
#endif

auto start_time = clock();

int a[3005][3005];

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

    int n, k;
    cin >> n >> k;
    vector<int> sz(n);
    for (int i = 0; i < n; ++i) {
        int t;
        cin >> t;
        for (int j = 0; j < t; ++j) {
            int u;
            cin >> u;
            if (j <= k) a[i][j] = u;
        }
        sz[i] = min(k, t);
    }

    // cerr << (double)(clock() - start_time) / CLOCKS_PER_SEC << endl;
    vector<vector<ll>> pref(n);
    for (int i = 0; i < n; ++i) {
        pref[i].reserve(sz[i]);
        pref[i].pb(a[i][0]);
        for (int j = 1; j < sz[i]; ++j) {
            pref[i].pb(pref[i].back() + a[i][j]);
        }
    }

    // cerr << (double)(clock() - start_time) / CLOCKS_PER_SEC << endl;

    vector<vector<ll>> pos(n, vector<ll>(k + 1));

    vector<pair<ll, int>> v;
    v.reserve(n + k);
    for (int ln = 1; ln <= k; ++ln) {
        v.clear();
        for (int i = 0; i < n; ++i) {
            if (pref[i].size() >= ln)
                v.eb(pref[i][ln - 1], i);
        }
        sort(v.rbegin(), v.rend());
        for (int i = 0; i < v.size(); ++i) {
            pos[v[i].second][ln] = i;
        }
    }

    // cerr << (double)(clock() - start_time) / CLOCKS_PER_SEC << endl;

    vector<vector<ll>> only_full(n + 1, vector<ll>(k + 1, 0)), partial(n + 1, vector<ll>(k + 1, 0));
    for (int i = 0; i < n; ++i) {
        ll sm = pref[i].back();
        only_full[i + 1] = only_full[i];
        partial[i + 1] = partial[i];
        for (int j = k - (int)sz[i]; j >= 0; --j) {
            only_full[i + 1][j + sz[i]] = max(only_full[i + 1][j + sz[i]], only_full[i][j] + sm);
            partial[i + 1][j + sz[i]] = max(partial[i + 1][j + sz[i]], partial[i][j] + sm);
        }
        for (int ln = 1; ln <= sz[i]; ++ln) {
            int cbefore = pos[i][ln - 1] * ln;
            if (cbefore > k) continue;
            for (int j = 0; j + ln <= k; ++j)
                partial[i + 1][j + ln] = max(partial[i + 1][j + ln], only_full[i][j] + pref[i][ln - 1]);
        }
    }
    // shows;
    // printMatrix(only_full);
    // shows;
    // printMatrix(partial);
    // shows;
    cout << max(only_full[n][k], partial[n][k]) << '\n';

    // cerr << (double)(clock() - start_time) / CLOCKS_PER_SEC << endl;

    return 0;
}


// Created by Nikolay Budin

#ifdef DEBUG
#  define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define ff first
#define ss second
#define szof(x) ((int)x.size())
#ifndef LOCAL
#  define cerr __get_ce
#endif

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef unsigned long long ull;

using namespace __gnu_pbds;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename K, typename V> using ordered_map = tree<K, V, less<K>, rb_tree_tag, tree_order_statistics_node_update>;

int const INF = (int)1e9 + 1e3;
ll const INFL = (ll)1e18 + 1e6;
#ifdef LOCAL
	mt19937 tw(9450189);
#else
	mt19937 tw(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif
uniform_int_distribution<ll> ll_distr;
ll rnd(ll a, ll b) { return ll_distr(tw) % (b - a + 1) + a; }

void solve() {
	int n, k;
	cin >> n >> k;
	vector<vector<int>> arr;
	vector<vector<ll>> pref;
	for (int i = 0; i < n; ++i) {
		int t;
		cin >> t;
		arr.push_back({});
		for (int j = 0; j < t; ++j) {
			int num;
			cin >> num;
			arr[i].push_back(num);
		}
		if (szof(arr[i]) > k) {
			arr[i].resize(k);
		}
		pref.push_back({0});
		for (int num : arr[i]) {
			pref[i].push_back(pref[i].back() + num);
		}
	}

	int bpv = 1;
	int bp = 1;
	while (bpv < n) {
		bpv *= 2;
		++bp;
	}

	vector<vector<pair<int, ll>>> here(bpv * 2);

	auto add_seg = [&](int l, int r, int sz, ll val) {
		l += bpv; r += bpv;
		while (l < r) {
			if (l & 1) {
				here[l++].push_back({sz, val});
			}
			if (r & 1) {
				here[--r].push_back({sz, val});
			}
			l /= 2; r /= 2;
		}
	};

	for (int i = 0; i < n; ++i) {
		add_seg(0, i, szof(arr[i]), pref[i].back());
		add_seg(i + 1, n, szof(arr[i]), pref[i].back());
	}

	vector<vector<ll>> mem_layers(bp, vector<ll>(k + 1));
	vector<ll> dp(k + 1, -INFL);
	dp[0] = 0;
	ll ans = 0;

	function<void(int, int, int, int)> dfs = [&](int v, int vl, int vr, int d) {
		copy(dp.begin(), dp.end(), mem_layers[d].begin());
		for (auto obj : here[v]) {
			for (int i = k - obj.ff; i >= 0; --i) {
				dp[i + obj.ff] = max(dp[i + obj.ff], dp[i] + obj.ss);
			}
		}
		if (vl + 1 == vr) {
			if (vl < n) {
				// cerr << vl << endl;
				// for (auto num : dp) {
				// 	cerr << num << " ";
				// }
				// cerr << endl;
				for (int i = 0; i < szof(pref[vl]); ++i) {
					ans = max(ans, dp[k - i] + pref[vl][i]);
				}
			}
			copy(mem_layers[d].begin(), mem_layers[d].end(), dp.begin());
			return;
		}

		int vm = (vl + vr) / 2;
		dfs(v * 2, vl, vm, d + 1);
		dfs(v * 2 + 1, vm, vr, d + 1);
		copy(mem_layers[d].begin(), mem_layers[d].end(), dp.begin());
	};

	dfs(1, 0, bpv, 0);

	cout << ans << "\n";
}

int main() {
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed;
#endif
	cout << setprecision(15) << fixed;
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int test_count = 1;
	// cin >> test_count;
	for (int test = 1; test <= test_count; ++test) {
		solve();
	}

#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}


#ifndef LOCAL
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma,tune=native")
#endif

#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <set>
#include <map>
#include <cassert>
#include <numeric>
#include <string>
#include <cstring>
#include <cmath>
using namespace std;

#ifdef LOCAL
	#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
	#define eprintf(...) 42
#endif

typedef long long int int64;

const int K = 3000;
const int N = 3005;

int sz[N];
int a[N][N];
long long sum[N];

struct Seg
{
    int l, r, id;

    Seg() : l(), r(), id() {}

    Seg(int _l, int _r, int _id) : l(_l), r(_r), id(_id) {}
};

struct Dp
{
    long long dp[N];

    Dp()
    {
        memset(dp, 0, sizeof dp);
    }

    void operator += (int id)
    {
        for (int i = N - sz[id] - 1; i >= 0; i--)
            dp[i + sz[id]] = max(dp[i + sz[id]], dp[i] + sum[id]);
    }
};

int k;

long long ans = 0;

void solve(int l, int r, vector <Seg> &segs, Dp &dp)
{
    if (l == r)
    {
        long long psum = 0;
        for (int i = 0; i <= min(k, sz[l]); i++)
        {
            if (i != 0)
                psum += a[l][i - 1];
            ans = max(ans, psum + dp.dp[k - i]);
        }
        return;
    }
    int m = (l + r) / 2;
    vector <Seg> lsegs, rsegs;
    Dp ldp = dp, rdp = dp;

    for (Seg seg : segs)
    {
        if (seg.l <= l && seg.r >= m)
           ldp += seg.id;
        else if (seg.l <= m)
            lsegs.push_back(seg);

        if (seg.l <= m + 1 && seg.r >= r)
            rdp += seg.id;
        else if (seg.r >= m + 1)
            rsegs.push_back(seg);
    }

    solve(l, m, lsegs, ldp);
    solve(m + 1, r, rsegs, rdp);

}

vector <Seg> segs;

void addSeg(int l, int r, int id)
{
    segs.push_back(Seg(l, r, id));
}

int main(int,  char **)
{
#ifdef LOCAL
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
#endif

    int n;
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++)
    {
        int t;
        scanf("%d", &t);
        for (int j = 0; j < t; j++)
        {
            int x;
            scanf("%d", &x);
            if (j < K)
            {
                sum[i] += x;
                a[i][j] = x;
            }
        }
        sz[i] = min(t, K);
    }

    for (int i = 0; i < n; i++)
    {
        if (i != 0)
            addSeg(0, i - 1, i);
        if (i != n - 1)
            addSeg(i + 1, n - 1, i);
    }

    Dp dp = Dp();
    solve(0, n - 1, segs, dp);

    printf("%lld\n", ans);

	return 0;
}


//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma GCC optimize("unroll-loops")

#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <assert.h>
#include <memory.h>
#include <time.h>
#include <bitset>

// #include "atcoder/convolution.hpp"
// #include "atcoder/dsu.hpp"
// #include "atcoder/fenwicktree.hpp"
// #include "atcoder/lazysegtree.hpp"
// #include "atcoder/math.hpp"
// #include "atcoder/maxflow.hpp"
// #include "atcoder/mincostflow.hpp"
// #include "atcoder/modint.hpp"
// #include "atcoder/scc.hpp"
// #include "atcoder/segtree.hpp"
// #include "atcoder/string.hpp"
// #include "atcoder/twosat.hpp"

#define uint unsigned int
#define ll long long
#define ull unsigned long long
#define ld long double
#define rep(i, l, r) for (int i = (l); i < (r); i++)
#define repb(i, r, l) for (int i = (r); i > (l); i--)
#define sz(a) (int)a.size()
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define rank qwertyuio
#define next dfghjk
#define prev fhsgfhjf
#define plus fsghsf
#define minus ytryr

using namespace std;

inline bool setmin(int &x, int y) { return (y < x) ? x = y, 1 : 0; }
inline bool setmax(int &x, int y) { return (y > x) ? x = y, 1 : 0; }
inline bool setmin(ll &x, ll y) { return (y < x) ? x = y, 1 : 0; }
inline bool setmax(ll &x, ll y) { return (y > x) ? x = y, 1 : 0; }

const int N = 3000 + 13;
const int inf = (int)1e9 + 1;
const ll big = (ll)1e18 + 1;
const int P = 239;
const int P1 = 31;
const int P2 = 57;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const int MOD2 = 998244353;
const ld eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;

int n, k;

vector<int> a[N];
ll sum[N];

ll ans = 0;

ll dp[N][N];
int p = 0;

void apply(int i) {
    memcpy(dp[p + 1], dp[p], sizeof(ll) * (k + 1));
    int sss = sz(a[i]);
    rep(j, sss, k + 1) {
        setmax(dp[p + 1][j], dp[p][j - sss] + sum[i]);
    }
    p++;
}

void solve(int l, int r) {
    if (r - l == 1) {
        ll tot = 0;
        rep(c, -1, min(k, sz(a[l]))) {
            if (c >= 0) {
                tot += a[l][c];
            }
            setmax(ans, tot + dp[p][k - (c + 1)]);
        }
        return;
    }
    int m = (l + r) / 2;
    int ppp = p;
    rep(i, m, r) {
        apply(i);
    }
    solve(l, m);

    p = ppp;
    rep(i, l, m) {
        apply(i);
    }
    solve(m, r);
}

int main()
{
    //freopen("circus.in", "r", stdin);
    //freopen("circus.out", "w", stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    //ll TL = 10.95 * CLOCKS_PER_SEC;
    //clock_t time = clock();
    cin >> n >> k;
    rep(i, 0, n) {
        int c;
        cin >> c;
        a[i].resize(c);
        sum[i] = 0;
        rep(j, 0, c) {
            cin >> a[i][j];
            sum[i] += a[i][j];
        }
    }
    dp[p][0] = 0;
    solve(0, n);
    cout << ans << "\n";
    return 0;
}


#include <bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define ford(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)

using namespace std;

typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn = 3100, LOG = 15;
vi64 a[maxn];
i64 s[maxn];
i64 dp[LOG][maxn];

int n, k;

i64 ans = 0;

void dnc(int L, int R, int z) {
    if (R - L == 1) {
        i64 pr = 0;
        int ub = min((int)a[L].size(), k);
        forn(i, ub + 1) {
            uax(ans, pr + dp[z][k - i]);
            if (i < ub) pr += a[L][i];
        }
        return;
    }
    int M = (L + R) / 2;
    {
        forn(i, k + 1) dp[z + 1][i] = dp[z][i];
        fore(i, L, M - 1) {
            int sz = a[i].size();
            ford(j, k - sz + 1) uax(dp[z + 1][j + sz], dp[z + 1][j] + s[i]);
        }
        dnc(M, R, z + 1);
    }
    {
        forn(i, k + 1) dp[z + 1][i] = dp[z][i];
        fore(i, M, R - 1) {
            int sz = a[i].size();
            ford(j, k - sz + 1) uax(dp[z + 1][j + sz], dp[z + 1][j] + s[i]);
        }
        dnc(L, M, z + 1);
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.precision(10);
    cout << fixed;
#ifdef LOCAL_DEFINE
    freopen("input.txt", "rt", stdin);
#endif

    cin >> n >> k;
    forn(i, n) {
        int l;
        cin >> l;
        a[i].resize(l);
        for (i64 &x: a[i]) cin >> x, s[i] += x;
    }

    forn(i, k + 1) dp[0][i] = -1e18;
    dp[0][0] = 0;
    dnc(0, n, 0);
    cout << ans << '\n';

#ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
    return 0;
}


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

typedef long long ll;

const ll INF = (ll)1e18 + 41;

void solve() {
    int n, k;
    cin >> n >> k;

    vector<ll> dp(k + 1, 0);
    vector<ll> maxUseless(k + 1, -INF);

    vector<vector<ll>> prefs(n);

    for (int i = 0; i < n; i++) {
        ll sum = 0;
        int sz; cin >> sz;
        vector<pair<int, ll>> pref;
        for (int j = 0; j < sz; j++) {
            int x; cin >> x; sum += x;
            if (j + 1 <= k)
                prefs[i].push_back(sum);
        }
    }

    mt19937 rnd(3431);
    shuffle(prefs.begin(), prefs.end(), rnd);

    for (int i = 0; i < n; i++) {
        vector<pair<int, ll>> a;
        const auto &pp = prefs[i];
        for (int j = 0; j < (int)pp.size(); j++) if (pp[j] > maxUseless[j + 1]) {
            a.emplace_back(j + 1, pp[j]);
        }
        vector<bool> isA(a.size(), false);

        for (int pos = k; pos > 0; pos--) {
            ll oldDp = dp[pos];
            for (int j = 0; j < (int)a.size(); j++) {
                int len = a[j].first;
                if (pos < len) continue;
                ll val = a[j].second;
                if (oldDp < dp[pos - len] + val) isA[j] = true;
                if (dp[pos] < dp[pos - len] + val) dp[pos] = dp[pos - len] + val;
            }
        }

        for (int j = 0; j < (int)a.size(); j++) {
            if (!isA[j]) {
                maxUseless[a[j].first] = max(maxUseless[a[j].first], a[j].second);
            }
        }
    }

    cout << dp[k] << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
#ifdef SERT
    freopen("a.in", "r", stdin);
    t = 1;
#endif
    while (t--) solve();
}


#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
    #define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
    #define eprintf(...) 42
#endif

using ll = long long;
using ld = long double;
using D = double;
using uint = unsigned int;
template<typename T>
using pair2 = pair<T, T>;
using pii = pair<int, int>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second

const int maxn = 3005;
const int treesize = 1 << 12;

vector<pair<int, ll>> ops[2 * treesize];
vector<ll> ks;
int n, k;
int a[maxn][maxn];
ll answer = 0;
int len[maxn];
ll sum[maxn];

void apply(pair<int, ll> t)
{
	for (int i = k - t.fi; i >= 0; i--) ks[i + t.fi] = max(ks[i + t.fi], ks[i] + t.se);
}

void add(int cur, int cl, int cr, int l, int r, pair<int, ll> t)
{
	if (cl > r || cr < l) return;
	if (cl >= l && cr <= r)
	{
		ops[cur].pb(t);
		return;
	}
	int cm = (cl + cr) / 2;
	add(cur * 2, cl, cm, l, r, t);
	add(cur * 2 + 1, cm + 1, cr, l, r, t);
}

void go(int cur, int cl, int cr, int l, int r)
{
	if (cl > r) return;
	vector<ll> was = ks;
	for (auto t : ops[cur]) apply(t);

	if (cl == cr)
	{
		ll cursum = 0;
		for (int i = 0; i <= len[cl]; i++)
		{
			answer = max(answer, ks[k - i] + cursum);
			cursum += a[cl][i];
		}
	} else
	{
		int cm = (cl + cr) / 2;
		go(cur * 2, cl, cm, l, r);
		go(cur * 2 + 1, cm + 1, cr, l, r);
	}

	ks = was;
}

int main()
{
	scanf("%d%d", &n, &k);
	for (int i =0 ; i < n; i++)
	{
		scanf("%d", &len[i]);
		for (int j =0 ; j < len[i]; j++)
		{
			if (j < k) scanf("%d", &a[i][j]);
			else scanf("%*d");
		}
		len[i] = min(len[i], k);
	}
	for (int i = 0; i < n; i++) sum[i] = accumulate(a[i], a[i] + len[i], 0LL);
	for (int i =0; i < n; i++)
	{
		add(1, 0, treesize - 1, 0, i - 1, {len[i], sum[i]});
		add(1, 0, treesize - 1, i + 1, n - 1, {len[i], sum[i]});
	}
	ks.resize(k + 1);
	go(1, 0, treesize - 1, 0, n - 1);
	cout << answer << endl;
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>

using namespace std;

//defines
typedef long long ll;
typedef long double ld;
#define TIME clock() * 1.0 / CLOCKS_PER_SEC
#define y0 _y0
#define kill _kill

//permanent constants
const ld pi = acos(-1.0);
const int day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int digarr[10] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
const int dxo[8] = {-1, -1, -1, 0, 1, 1, 1, 0};
const int dyo[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
const int alf = 26;
const int two = 2;
const ld eps = 1e-10;
const ll INF = (ll)(2e18 + 239);
const int BIG = (int)(1e9 + 239);
const int MOD = 998244353;
const ll MOD2 = (ll)MOD * (ll)MOD;

//random
#ifdef ONPC
mt19937_64 rnd(239);
#else
mt19937_64 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

//constants
const int M = (int)(2e5 + 239);
const int N = (int)(2e3 + 10);
const int L = 20;
const int T = (1 << 20) + 239;
const int B = 510;
const int X = 3010;

vector<ll> v[X];
int n, k;
ll ans;

void func(int l, int r, vector<ll> w) {
    if (r - l == 1) {
        for (int i = 0; i < v[l].size(); i++)
            if (w[k - i] != -INF)
                ans = max(ans, w[k - i] + v[l][i]);
        return;
    }
    int mid = (l + r) / 2;
    vector<ll> w_go = w;
    for (int i = l; i < mid; i++)
        for (int j = k - (int)v[i].size() + 1; j >= 0; j--)
            if (w_go[j] != -INF)
                w_go[j + (int)v[i].size() - 1] = max(w_go[j + (int)v[i].size() - 1], w_go[j] + v[i].back());
    func(mid, r, w_go);
    w_go = w;
    for (int i = mid; i < r; i++)
        for (int j = k - (int)v[i].size() + 1; j >= 0; j--)
            if (w_go[j] != -INF)
                w_go[j + (int)v[i].size() - 1] = max(w_go[j + (int)v[i].size() - 1], w_go[j] + v[i].back());
    func(l, mid, w_go);
}

int32_t main()
{
#ifdef ONPC
    freopen("input", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> n >> k;
    for (int i = 0; i < n; i++) {
        int t;
        cin >> t;
        v[i].resize(t + 1);
        v[i][0] = 0;
        for (int j = 0; j < t; j++) {
            ll x;
            cin >> x;
            v[i][j + 1] = v[i][j] + x;
        }
        if (t >= k) {
            v[i].resize(k + 1);
        }
    }
    vector<ll> w(k + 1, -INF);
    w[0] = 0;
    ans = 0;
    func(0, n, w);
    cout << ans << "\n";
    return 0;
}


#include <stdio.h>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <complex>
#include <map>
#include <unordered_map>
#include <queue>
#include <array>
#include <bitset>
#include <chrono>
#include <random>
using namespace std;
typedef long double ld;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<pii> vii;
typedef vector<string> vs;
//const int mod = ;

const int N = 1 << 12;
ll d[2][N][3001];

void umax(ll& x, ll y) {
  x = max(x, y);
}

const int DEBUG = 0;

int main() {
  //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  std::ios::sync_with_stdio(false); std::cin.tie(0);
  //int n = 3000, k = 3000;
  for (int tt = 0; tt < (DEBUG ? 100 : 1); ++tt) {
  int n = 10, k = rand() % 10;
  if (!DEBUG) cin >> n >> k;
  vvi a(n);
  vi l(n);
  vl sum(n);
  for (int i = 0; i < n; ++i) {
    //int t = 300;
    int t = 1 + rand() % 10;
    if (!DEBUG) cin >> t;
    a[i].resize(t);
    l[i] = t;
    for (int j = 0; j < t; ++j) {
      if (!DEBUG) cin >> a[i][j];
      else a[i][j] = j > 0 ? a[i][j - 1] + rand() % 5 : rand() % 2;
      sum[i] += a[i][j];
    }
  }
  int pw = 1;
  while (pw < n) pw *= 2;
  while (l.size() < pw) {
    l.push_back(0);
    sum.push_back(0);
  }
  memset(d[0], 0, sizeof(d[0]));
  int pr = 0, nx = 1;
  while (pw > 1) {
    pw /= 2;
    for (int s = 0; s < l.size(); s += 2 * pw) {
      memcpy(d[nx][s], d[pr][s], sizeof(d[nx][s]));
      memcpy(d[nx][s + pw], d[pr][s], sizeof(d[nx][s]));
      for (int i = s; i < s + pw; ++i) for (int j = k; j >= l[i]; --j) {
        umax(d[nx][s + pw][j], d[nx][s + pw][j - l[i]] + sum[i]);
      }
      for (int i = s + pw; i < s + 2 * pw; ++i) for (int j = k; j >= l[i]; --j) {
        umax(d[nx][s][j], d[nx][s][j - l[i]] + sum[i]);
      }
    }
    swap(pr, nx);
  }
  ll res = 0;
  for (int i = 0; i < n; ++i) {
    ll s = 0;
    for (int j = 0; j < min(k + 1, (int)a[i].size() + 1); ++j) {
      res = max(res, d[pr][i][k - j] + s);
//      cerr << res << ' ' << i << ' ' << j << ' ' << s << ' ' << d[pr][i][k - j] << endl;
      if (j < a[i].size()) s += a[i][j];
    }
  }
  cout << res << endl;
  if (DEBUG) {
    vl v(k + 1);
    for (int i = 0; i < n; ++i) {
      ll s = 0;
      vl res = v;
      for (int j = 0; j < min(k + 1, (int)a[i].size() + 1); ++j) {
        vl v1 = v;
        for (int t = k; t >= j; --t) {
          v1[t] = max(v1[t], v1[t - j] + s);
        }
        for (int t = 0; t <= k; ++t) res[t] = max(res[t], v1[t]);
        if (j < a[i].size()) s += a[i][j];
      }
      v = res;
    }
    cerr << v[k] << endl;
    if (v[k] != res) {
      cout << n << ' ' << k << endl;
      for (int i = 0; i < n; ++i) {
        for (int x : a[i]) cout << x << ' '; cout << endl;
      }
    }
    assert(v[k] == res);
  }
  }
  return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops", "no-stack-protector")

#include <bits/stdc++.h>

using namespace std;

#define all(a) (a).begin(), (a).end()
#define sz(a) (int)(a).size()

using ll = long long;
using ld = long double;
// using ld = __float128;
using pii = pair<int, int>;
using uint = unsigned int;
using ull = unsigned long long;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
default_random_engine generator;

void solve();

int main() {
#ifdef LOCAL
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << setprecision(15) << fixed;
    cerr << setprecision(15) << fixed;

    int tests = 1;
    // cin >> tests;

    for (int test = 1; test <= tests; ++test) {
        // cout << "Case #" << test << ": ";
        solve();
    }

#ifdef LOCAL
    cerr << "Time: " << double(clock()) / CLOCKS_PER_SEC << endl;
#endif
}

// -----------------------------------------------------------------

const int MAXN = 3030;

ll pref[MAXN][MAXN];
ll suff[MAXN][MAXN];

void solve() {
    int n, k;
    cin >> n >> k;
    vector<vector<int>> a(n);
    for (int i = 0; i < n; ++i) {
        int m;
        cin >> m;
        a[i].resize(m);
        for (int &x : a[i]) {
            cin >> x;
        }
    }

    for (int i = 0; i <= k; ++i) {
        pref[0][i] = -1;
    }
    pref[0][0] = 0;

    for (int i = 0; i < n; ++i) {
        ll sum = 0;
        for (int x : a[i]) {
            sum += x;
        }
        for(int j = 0; j <= k; ++j) {
            pref[i + 1][j] = pref[i][j];
        }
        for (int j = 0; j + sz(a[i]) <= k; ++j) {
            if (pref[i][j] == -1) {
                continue;
            }
            pref[i + 1][j + sz(a[i])] = max(pref[i + 1][j + sz(a[i])], pref[i][j] + sum);
        }
    }

    for (int i = 0; i <= k; ++i) {
        suff[n][i] = -1;
    }
    suff[n][0] = 0;

    for (int i = n - 1; i >= 0; --i) {
        ll sum = 0;
        for (int x : a[i]) {
            sum += x;
        }
        for(int j = 0; j <= k; ++j) {
            suff[i][j] = suff[i + 1][j];
        }
        for (int j = 0; j + sz(a[i]) <= k; ++j) {
            if (suff[i + 1][j] == -1) {
                continue;
            }
            suff[i][j + sz(a[i])] = max(suff[i][j + sz(a[i])], suff[i + 1][j] + sum);
        }
    }

    vector<vector<pair<ll, int>>> arr(k + 1);
    for (int i = 0; i < n; ++i) {
        ll sum = 0;
        for (int j = 0; j < sz(a[i]); ++j) {
            sum += a[i][j];
            if (j + 1 <= k) {
                arr[j + 1].push_back({sum, i});
            }
        }
    }

    ll res = pref[n][k];
    for (int i = 1; i <= k; ++i) {
        sort(all(arr[i]), greater());
        arr[i].resize(min(sz(arr[i]), k / i + 1));

        for (auto [s, p] : arr[i]) {
            for (int j = 0; j <= k - i; ++j) {
                if (pref[p][j] == -1 || suff[p + 1][k - i - j] == -1) {
                    continue;
                }
                res = max(res, pref[p][j] + suff[p + 1][k - i - j] + s);
            }
        }
    }

    cout << res << endl;

}


#include <bits/stdc++.h>

using namespace std;

const int MX = 3000;

long long sum[MX], dp[MX + 1], ans;
vector<int> a[MX];
int k;

void solve(int l, int r) {
	if (l == r) {
		ans = max(dp[k], ans);

		long long here = 0;
		for (int x = 0; x < k && x < a[l].size(); x++) {
			here += a[l][x];
			ans = max(dp[k - x - 1] + here, ans);
		}

		return;
	}

	vector<long long> save(dp, dp + k + 1);

	int c = (l + r) / 2;

	for (int i = l; i <= c; i++) {
		int sz = a[i].size();

		for (int x = k; x - sz >= 0; x--) {
			dp[x] = max(dp[x], dp[x - sz] + sum[i]);
		}
	}

	solve(c + 1, r);

	for (int x = 0; x <= k; x++) dp[x] = save[x];

	for (int i = c + 1; i <= r; i++) {
		int sz = a[i].size();

		for (int x = k; x - sz >= 0; x--) {
			dp[x] = max(dp[x], dp[x - sz] + sum[i]);
		}
	}

	solve(l, c);

	for (int x = 0; x <= k; x++) dp[x] = save[x];
}

int main() {
	int n;
	ignore = scanf("%d %d", &n, &k);
	for (int i = 0, m; i < n; i++) {
		ignore = scanf("%d", &m);
		for (int j = 0, x; j < m; j++) {
			ignore = scanf("%d", &x);

			sum[i] += x;
			a[i].push_back(x);
		}
	}

	solve(0, n - 1);

	printf("%lld\n", ans);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(x) (x).begin (),(x).end()
#define sqrt(x) sqrt(abs(x))
#define re return
#define sz(x) ((int)(x).size ())
#define prev PREV
#define next NEXT

using ll = long long;
using ii = pair<int, int>;
using ld = long double;
using D = double;
using vi = vector<int>;
using vii = vector<ii>;
using vvi = vector<vi>;
using vs = vector<string>;

template<typename T> T abs (T x) { re x < 0 ? -x : x; }
template<typename T> T sgn (T x) { re x < 0 ? -1 : (x > 0 ? 1 : 0); }
template<typename T> T sqr (T x) { re x * x; }
template<typename T> T gcd (T a, T b) { re a ? gcd (b % a, a) : b; }

int n;
int m;
int t[3000];
ll s[3000][3001];
ll res[3001][6001];
int prev[3001][6001];
int was[3001];

int out (int i, int j) {
	if (i == 0) re 0;
	if (prev[i][j]) {
		was[i - 1] = 1;
		out (i - 1, j - t[i - 1]);
	} else {
		out (i - 1, j);
	}
}

int main () {
	scanf ("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		int tt;
		scanf ("%d", &tt);
		t[i] = min (m, tt);
		s[i][0] = 0;
		ll cur = 0;
		for (int j = 0; j < tt; j++) {
			int x;
			scanf ("%d", &x);
			cur += x;
			if (j < t[i]) s[i][j + 1] = cur;
		}
	}
	for (int i = 0; i <= n; i++)
		for (int j = 0; j <= 2 * m; j++)
			res[i][j] = -1e18;
	res[0][0] = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j <= 2 * m; j++) {
			if (res[i + 1][j] < res[i][j]) {
				res[i + 1][j] = res[i][j];
				prev[i + 1][j] = 0;
			}
			if (j + t[i] <= 2 * m && res[i + 1][j + t[i]] < res[i][j] + s[i][t[i]]) {
				res[i + 1][j + t[i]] = res[i][j] + s[i][t[i]];
				prev[i + 1][j + t[i]] = 1;
			}
//			printf ("%d %d = %lld\n", i, j, res[i][j]);
		}
	ll ans = 0;
	for (int j = 0; j <= 2 * m; j++) {
		if (res[n][j] < 0) continue;
		for (int i = 0; i < n; i++) was[i] = 0;
		out (n, j);
//		printf ("%d = %lld\n", j, res[n][j]);
//		for (int i = 0; i < n; i++) printf ("%d ", was[i]);
//		printf ("\n");
		if (j < m) {
			for (int i = 0; i < n; i++)
				if (!was[i] && j + t[i] >= m)
					ans = max (ans, res[n][j] + s[i][m - j]);
		} else {
			for (int i = 0; i < n; i++)
				if (was[i] && t[i] >= (j - m))
					ans = max (ans, res[n][j] - s[i][t[i]] + s[i][t[i] - (j - m)]);
		}
//		printf ("%lld\n", ans);
	}
	printf ("%lld\n", ans);
	cerr << clock () << endl;
	re 0;
}


/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#include <iostream>
#include <fstream>

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <vector>

#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
#define mp make_pair

using namespace std;

typedef long long int64;
typedef vector<int> vi;
typedef pair<int, int> ii;

constexpr int BUBEN = 50;

class TaskC {
 public:
  void solveOne(istream &in, ostream &out) {
    int n, k;
    in >> n >> k;
    vector<vector<int64>> a(n);
    vector<int64> asum(n);
    for (int i = 0; i < n; ++i) {
      int m;
      in >> m;
      for (int j = 0; j < m; ++j) {
        int64 x;
        in >> x;
        a[i].push_back(x);
        asum[i] += x;
      }
    }
    int64 res = 0;
    for (int i = 0; i < n;) {
      int j = min(n, i + BUBEN);
      vector<int64> best(k + 1, 0);
      for (int v = 0; v < n; ++v) {
        if (v >= i && v < j) continue;
        int cnt = a[v].size();
        int64 score = asum[v];
        for (int old = k - cnt; old >= 0; --old) {
          best[old + cnt] = max(best[old + cnt], best[old] + score);
        }
      }
      vector<int64> cbest(k + 1, 0);
      for (int u = i; u < j; ++u) {
        for (int t = 0; t <= k; ++t) cbest[t] = best[t];
        for (int v = i; v < j; ++v) if (v != u) {
          int cnt = a[v].size();
          int64 score = asum[v];
          for (int old = k - cnt; old >= 0; --old) {
            cbest[old + cnt] = max(cbest[old + cnt], cbest[old] + score);
          }
        }
        int64 sofar = 0;
        for (int take = 0; take <= k && take <= a[u].size(); ++take) {
          res = max(res, sofar + cbest[k - take]);
          if (take < a[u].size()) {
            sofar += a[u][take];
          }
        }
      }
      i = j;
    }
    out << res << "\n";
  }

  void solve(std::istream &in, std::ostream &out) {
    int nt = 1;
    for (int it = 0; it < nt; ++it) {
      solveOne(in, out);
    }
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  TaskC solver;
  std::istream& in(std::cin);
  std::ostream& out(std::cout);
  solver.solve(in, out);
  return 0;
}


/**
 *    author:  tourist
 *    created: 01.11.2020 17:14:09
**/
#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<vector<int>> a(n);
  vector<int> sz(n);
  vector<long long> sum(n);
  for (int i = 0; i < n; i++) {
    int foo;
    cin >> foo;
    a[i].resize(foo);
    sz[i] = foo;
    sum[i] = 0;
    for (int j = 0; j < foo; j++) {
      cin >> a[i][j];
      sum[i] += a[i][j];
    }
  }
  const long long inf = (long long) 1e18;
  vector<vector<long long>> save(30, vector<long long>(k + 1, -inf));
  vector<long long> dp(k + 1, -inf);
  dp[0] = 0;
  long long ans = 0;
  function<void(int, int, int)> Solve = [&](int level, int from, int to) {
    if (from == to) {
      long long took = 0;
      for (int i = 0; i <= k; i++) {
        ans = max(ans, took + dp[k - i]);
        if (i == (int) a[from].size()) {
          break;
        }
        took += a[from][i];
      }
      return;
    }
    for (int j = 0; j <= k; j++) {
      save[level][j] = dp[j];
    }
    int mid = (from + to) >> 1;
    {
      for (int i = from; i <= mid; i++) {
        for (int j = k - sz[i]; j >= 0; j--) {
          dp[j + sz[i]] = max(dp[j + sz[i]], dp[j] + sum[i]);
        }
      }
      Solve(level + 1, mid + 1, to);
      for (int j = 0; j <= k; j++) {
        dp[j] = save[level][j];
      }
    }
    {
      for (int i = mid + 1; i <= to; i++) {
        for (int j = k - sz[i]; j >= 0; j--) {
          dp[j + sz[i]] = max(dp[j + sz[i]], dp[j] + sum[i]);
        }
      }
      Solve(level + 1, from, mid);
      for (int j = 0; j <= k; j++) {
        dp[j] = save[level][j];
      }
    }
  };
  Solve(0, 0, n - 1);
  cout << ans << '\n';
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;

const int maxn = 3005;
vector<ll> pr[maxn];
vector<int> w;
vector<ll> c;
int k;
ll ans = 0;

void apply(vector<ll>& d, int w, ll c) {
  for (int i = (int) d.size() - w - 1; i >= 0; --i) {
    d[i + w] = max(d[i + w], d[i] + c);
  }
}

vector<ll> dmem[40];

void rec(int l, int r, int depth) {
  const auto& d = dmem[depth];
  if (l + 1 == r) {
    for (int i = 0; i <= min(k, w[l]); ++i) {
      ans = max(ans, d[k - i] + pr[l][i]);
    }
    return;
  }
  int c = (l + r) / 2;
  auto& d2 = dmem[depth + 1];
  for (int i = 0; i < (int) d2.size(); ++i) {
    d2[i] = d[i];
  }
  for (int i = l; i < c; ++i) {
    apply(d2, w[i], ::c[i]);
  }
  rec(c, r, depth + 1);
  for (int i = 0; i < (int) d2.size(); ++i) {
    d2[i] = d[i];
  }
  for (int i = c; i < r; ++i) {
    apply(d2, w[i], ::c[i]);
  }
  rec(l, c, depth + 1);
}

signed main() {
#ifdef LOCAL
  assert(freopen("c.in", "r", stdin));
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n >> k;
  w.resize(n);
  c.resize(n);
  for (int i = 0; i < n; ++i) {
    cin >> w[i];
    pr[i].resize(w[i] + 1);
    for (int j = 0; j < w[i]; ++j) {
      int x;
      cin >> x;
      c[i] += x;
      pr[i][j + 1] = pr[i][j] + x;
    }
  }
  for (int i = 0; i < 40; ++i) {
    dmem[i].resize(k + 1);
  }
  rec(0, n, 0);
  cout << ans << '\n';
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double ldb;
typedef pair<ll, ll> pll;
typedef pair<int, int>pii;

const ll maxx = 100000 + 7;
const ll maxn = 100+ 7;
const ll mod = 998244353;
const ll maxs = 5 * (1E5) + 7;
const ll maxm =30+ 7;
const ll maxk = 800 + 7;
const ll maxw = 100 + 7;
const ll maxh = 100 + 7;
const ldb pi = 3.1415926535898;

const int inf = 1e9+7;
const ldb eps = 1e-8;
//#define __TREE
#ifdef __TREE
#define lc(xx) (xx<<1)
#define rc(xx) ((xx<<1)|1)
#endif

#define _for(i,a,b) for(ll i=(a);i<(b);i++)
#define msz(ss) memset(ss,0,sizeof(ss))
#define msllz(ss) memset(ss,(ll)0,sizeof(ss))
#define mszull(ss) memset(ss,(ull)0,sizeof(ss))
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _dep(i,a,b) for(int i=(a);i>=(b);i--)
#define msllneg(ss) memset(ss,(ll)-1,sizeof(ss))
#define msitt(xx) memset(xx,1,sizeof(xx))
#define IO ios::sync_with_stdio(false);cout.tie(0);cin.tie(0)

ostream& operator << (ostream & os, pll &rhs)
{
	os << rhs.first << " " << rhs.second << endl;
	return os;
}

ll qw(ll a, ll b)
{
	ll ans = 1;
	if (a == 0)
		return 0ll;
	while (b)
	{
		if (b & 1)
		{
			ans = (ans%mod*a%mod) % mod;
			ans %= mod;
		}
		b >>= 1;
		a = (a%mod*a%mod) % mod;
		a %= mod;
	}
	ans %= mod;
	return ans;
}

template<class T>
T min3(T a, T b, T c)
{
	return min(min(a, b), c);
}
template<class T>
T max3(T a, T b, T c)
{
	return max(max(a, b), c);
}

ll dp[maxn][100|1][2][1 << 4][1 << 4];    //pos limit dt x�ı��� y�ı���
ll vis[maxn][100|1][2][1 << 4][1 << 4];
ll dig[maxn];
ll ncase;
ll n;

ll dfs(ll pos, ll dt, ll limit, ll mx, ll my, ll x, ll y)
{
	if (pos == n)
		return (dt == 0) && (my&mx);
	ll &ans = dp[pos][dt + x][limit][mx][my];
	if (vis[pos][dt + x][limit][mx][my] == ncase)
		return ans;
	vis[pos][dt + x][limit][mx][my] = ncase;
	ll up = limit ? dig[pos] : 9;
	ans = 0;
	_rep(i, 0, 9)
	{
		_rep(j, 0, up)
		{
			ll ndt = dt * 10 - i*y + j*x;
			if (ndt <= -x||ndt>= y)continue;
			ll tmx = 0, tmy = 0;
			if ((j!=0) && (j%y == 0)) tmy = (1 << ((j / y) - 1));
			if ((i!=0) && (i%x == 0)&&((i/x)*y<=9)) tmx = (1 << ((i / x) - 1));
			ans += dfs(pos + 1, ndt, limit&&(j == up), mx|tmx, my|tmy, x, y)%mod;
			ans %= mod;
		}
	}
	ans %= mod;
	return ans;
}

string str;
ll ans = 0;
void init()
{
	//cin >> str;
	n = str.length();
	ans = 0;
	_for(i, 0, str.length())
	{
		dig[i] = str[i] - '0';
		ans = (ans*10+dig[i])%mod;
	}
}

ll gcd(ll x, ll y)
{
	return y == 0 ? x : gcd(y,x%y);
}
void solve()
{
	ncase = 0;
	_rep(x,1, 9)
		_rep(y, x + 1, 9)if (gcd(x, y) == 1) ++ncase,ans += 2*dfs(0, 0, 1, 0, 0, x, y)%mod,ans %= mod;
	cout << ans << endl;
}

int main(void)
{
#ifdef OJ
	freopen("buffcraft.in", "r", stdin);
	freopen("a.txt", "w", stdout);
#endif
	while (cin >> str)
	{
		init();
		solve();
		//cout <<"time :"<<" "<<clock() << endl;
	}
}


/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author zjsdut
 */

#define NDEBUG
extern constexpr bool show_all_failed_tests = false;
#ifndef CP_UTILS
#define CP_UTILS
#include <algorithm>
#include <bitset>
#include <climits>
#include <cmath>
#include <cstring>
#include <map>
#include <numeric>
#include <set>
//
// Created by zjsdu on 5/28/2020.
//

#ifndef JHELPER_EXAMPLE_PROJECT_LIBRARY_ALIAS_HPP_
#define JHELPER_EXAMPLE_PROJECT_LIBRARY_ALIAS_HPP_
#include <string>
#include <cassert>
#include <queue>
#ifndef JHELPER_EXAMPLE_PROJECT_LIBRARY_IO_HPP_
#define JHELPER_EXAMPLE_PROJECT_LIBRARY_IO_HPP_
#include <iostream>
#include <vector>
#include <tuple>
struct fast_ios {
  fast_ios() {
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
    std::cout.precision(10);
    std::cout << std::fixed;
  };
} fast_ios_;
namespace io {
template<typename... Ts>
std::istream &operator>>(std::istream &in, std::tuple<Ts...> &t);
template<typename T, typename U>
std::istream &operator>>(std::istream &in, std::pair<T, U> &p) {
  in >> p.first >> p.second;
  return in;
}

template<typename T>
std::istream &operator>>(std::istream &stream, std::vector<T> &vec) {
  for (auto &x : vec)
    stream >> x;
  return stream;
}

template<typename... Ts>
std::istream &operator>>(std::istream &in, const std::tuple<Ts...> &t) {
  std::apply([&in](auto &... args) { ((in >> args), ...); }, t);
  return in;
}

template<class... Args> void scan(Args &... args) {
  ((std::cin >> args), ...);
}

template<typename T>
std::ostream &operator<<(std::ostream &out, const std::vector<T> &vec) {
  bool first = true;
  for (const T &t : vec) {
    if (first)
      first = false;
    else
      out << ' ';
    out << t;
  }
  return out;
}

template<typename T, typename U>
std::ostream &operator<<(std::ostream &out, const std::pair<T, U> &p) {
  out << p.first << ' ' << p.second;
  return out;
}

template<typename T>
std::ostream &operator<<(std::ostream &out,
                         const std::vector<std::vector<T>> &t) {
  bool is_first = true;
  for (const auto &row : t) {
    if (is_first)
      is_first = false;
    else
      out << '\n';
    out << row;
  }
  return out;
}

template<typename... Args> void pt(Args &&... args) {
  ((std::cout << args << ' '), ...);
}

template<typename First, typename... Args>
void pl(const First &first, const Args &... args) {
  std::cout << first;
  ((std::cout << ' ' << args), ...);
  std::cout << '\n';
}

template<typename... Args> void pn(const Args &... args) {
  ((std::cout << args << '\n'), ...);
}
}// namespace io
inline int ri() {
  int x;
  std::cin >> x;
  return x;
}
#endif// JHELPER_EXAMPLE_PROJECT_LIBRARY_IO_HPP_

using ll = long long;
using ull = unsigned long long;
using vl = std::vector<ll>;
using vb = std::vector<bool>;
using vi = std::vector<int>;
using vs = std::vector<std::string>;
using pii = std::pair<int, int>;
using pli = std::pair<ll, int>;
using pil = std::pair<int, ll>;
using pll = std::pair<ll, ll>;
using vii = std::vector<pii>;
template<typename T, typename U = std::less<T>>
using pq = std::priority_queue<T, std::vector<T>, U>;
template<typename... Ts> using vt = std::vector<std::tuple<Ts...>>;
template<typename T> class vv {
  std::vector<std::vector<T>> data;

 public:
  explicit vv(int n) {
    assert(n > 0);
    data.assign(n, std::vector<T>{});
  }
  vv(int n, int m, T init = T{}) {
    assert(n > 0 && m > 0);
    data.assign(n, std::vector<T>(m, init));
  }
  std::vector<T> &operator[](size_t i) {
    assert(i < data.size());
    return data[i];
  }
  void fill(T val) {
    for (auto &row : data)
      std::fill(row.begin(), row.end(), val);
  }
  friend std::istream &operator>>(std::istream &in, vv<T> &val) {
    return io::operator>>(in, val.data);
  }
  friend std::ostream &operator<<(std::ostream &out, const vv<T> &val) {
    return io::operator<<(out, val.data);
  }
  friend auto begin(vv<T> &val) { return val.data.begin(); }
  friend auto end(vv<T> &val) { return val.data.end(); }
  friend auto rbegin(vv<T> &val) { return val.data.rbegin(); }
  friend auto rend(vv<T> &val) { return val.data.rend(); }
};
#define TOKENPASTE(x, y) x##y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define rng3(i, a, b)                                                          \
  for (std::common_type<decltype(a), decltype(b)>::type                        \
           i = a,                                                              \
           TOKENPASTE2(r_end_, __LINE__) = b;                                  \
       i < TOKENPASTE2(r_end_, __LINE__); ++i)
#define rng2(i, n) rng3(i, 0, n)
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define rng(...) GET_MACRO(__VA_ARGS__, rng3, rng2)(__VA_ARGS__)
#define up(i, a, b)                                                            \
  for (std::common_type<decltype(a), decltype(b)>::type                        \
           i = a,                                                              \
           TOKENPASTE2(r_end_, __LINE__) = b;                                  \
       i <= TOKENPASTE2(r_end_, __LINE__); ++i)
#define down(i, b, a)                                                          \
  for (std::common_type<decltype(a), decltype(b)>::type                        \
           i = b,                                                              \
           TOKENPASTE2(r_end_, __LINE__) = a;                                  \
       i >= TOKENPASTE2(r_end_, __LINE__); --i)
#define rep(n)                                                                 \
  for (auto TOKENPASTE2(_iter_, __LINE__) = n;                                 \
       TOKENPASTE2(_iter_, __LINE__) > 0; --TOKENPASTE2(_iter_, __LINE__))
#define FOR(x, cont) for (const auto &x : cont)
#define For(x, cont) for (auto &x : cont)
#define ALL(x) begin(x), end(x)
// hat off to 300iq
#define RALL(x) rbegin(x), rend(x)
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define ep emplace
#define SZ(x) (int) (x).size()
#define rp(...) return pl(__VA_ARGS__)
#define rpn(...) return pn(__VA_ARGS__)
#define adv(i, n)                                                              \
  for (auto TOKENPASTE2(_n_, __LINE__) = n; i < TOKENPASTE2(_n_, __LINE__); ++i)
#define INT(...) int __VA_ARGS__; scan(__VA_ARGS__)
#define LL(...) long long __VA_ARGS__; scan(__VA_ARGS__)
#define STR(...) std::string __VA_ARGS__; scan(__VA_ARGS__)
#endif// JHELPER_EXAMPLE_PROJECT_LIBRARY_ALIAS_HPP_

inline void Yn(bool p) {
  std::cout << (p ? "Yes\n" : "No\n");
}
inline void YN(bool p) {
  std::cout << (p ? "YES\n" : "NO\n");
}
inline void yn(bool p) {
  std::cout << (p ? "yes\n" : "no\n");
}
template<typename T> T &inc(T &cont) {
  for (auto &e : cont)
    ++e;
  return cont;
}
template<typename T> T &dec(T &cont) {
  for (auto &e : cont)
    --e;
  return cont;
}
template<typename A, typename B> inline bool chkmin(A &a, const B &b) {
  return b < a ? a = b, true : false;
}

template<typename A, typename B> inline bool chkmax(A &a, const B &b) {
  return a < b ? a = b, true : false;
}

template<typename T> struct reversion_wrapper { T &iterable; };
template<typename T> auto begin(reversion_wrapper<T> w) {
  using std::rbegin;
  return rbegin(w.iterable);
}
template<typename T> auto end(reversion_wrapper<T> w) {
  using std::rend;
  return rend(w.iterable);
}
template<typename T> reversion_wrapper<T> reverse(T &&iterable) {
  return {iterable};
}
template<typename T, typename U> T ceil(T x, U y) {
  assert(y > 0);
  if (x > 0)
    x += y - 1;
  return x / y;
}

template<typename T, typename U> T floor(T x, U y) {
  assert(y > 0);
  if (x < 0)
    x -= y - 1;
  return x / y;
}

template<class...> struct typelist {};

template<class T, class... Ts>
constexpr bool any_same = (std::is_same_v<T, Ts> || ...);

template<class F> struct y_combinator {
  template<class... TLs> struct ref {
    y_combinator &self;
    template<class... Args> decltype(auto) operator()(Args &&... args) const {
      using G = std::conditional_t<any_same<typelist<Args...>, TLs...>,
                                   ref<TLs...>, ref<TLs..., typelist<Args...>>>;
      return self.f(G{self}, std::forward<Args>(args)...);
    }
  };
  F f;
  template<class... Args> decltype(auto) operator()(Args &&... args) {
    return ref<>{*this}(std::forward<Args>(args)...);
  }
};
template<class F> y_combinator(F) -> y_combinator<F>;
#ifndef debug
#define debug(...) 42
#endif
#ifndef show
#define show(...) 42
#endif
using namespace io;
using namespace std;
#endif// CP_UTILS

class UnionFind {
  std::vector<int> par, sz;
  int nTree;

public:
  explicit UnionFind(int n) : par(n), sz(n, 1), nTree(n) { // 0-indexed
    std::iota(par.begin(), par.end(), 0);
  }
  void init() {
    std::fill(par.begin(), par.end(), 1);
    nTree = par.size();
    std::iota(par.begin(), par.end(), 0);
  }
  int n_tree() const { return nTree; }

  int size(int x) { return sz[root(x)]; }

  int root(int x) { return x == par[x] ? x : par[x] = root(par[x]); }

  bool unite(int x, int y) {
    int rx = root(x), ry = root(y);
    if (rx != ry) {
      par[rx] = ry;
      --nTree;
      sz[ry] += sz[rx];
      return true;
    }
    return false;
  }

  bool is_root(int x) const { return par[x] == x; }
  bool same(int x, int y) { return root(x) == root(y); }
};

template<typename int_t> inline int_t lowbit(int_t x) {
  return x & -x;
}

inline int h_bit(unsigned long long x) {
  return int(sizeof(unsigned long long) * 8 - __builtin_clzll(x));
}

unsigned long long pow2(unsigned long long x) {// round up to power of 2
  if (x == 0)
    return 1;
  return x == lowbit(x) ? x : 1ull << h_bit(x);
}

template<typename T> inline int bit(T a, int i) {
  return a >> i & 1;
}
template<typename T> inline T get_mid(T l, T r) {
  assert(l <= r);
  return l + (r - l >> 1);
}

#define popcnt(x) __builtin_popcountll((x))

void solve() {
  INT(n);
  STR(a, b);
  vector<int> reach(20);
  UnionFind dsu(20);
  rng (i, n)
    if (a[i] != b[i]) {
      reach[a[i] - 'a'] |= 1 << b[i] - 'a';
      dsu.unite(a[i] - 'a', b[i] - 'a');
    }
  int m = 20;
  vv<int> comps(m);
  rng (i, m)
    comps[dsu.root(i)].pb(i);
  int ans = 0;
  FOR (comp, comps) {
    int cnt = SZ(comp);
    if (cnt <= 1) {
      continue;
    }
    debug(comp);
    vb is_dag(1 << cnt);
    is_dag[0] = true;
    rng (s, 1, 1 << cnt) {
      int t = 0;
      rng (i, cnt)
        if (bit(s, i))
          t |= 1 << comp[i];
      rng (i, cnt)
        if (bit(s, i) and is_dag[s ^ 1 << i] and (t & reach[comp[i]]) == 0) {
          is_dag[s] = true;
          break;
        }
    }
    int x = 100;
    rng (i, 1, 1 << cnt)
      if (is_dag[i])
        chkmin(x, 2 * cnt - popcnt(i) - 1);
    ans += x;
  }

  pl(ans);
}
/*
 * Make sure that your laptop is plugged in or the build may be slow.
 *
 * Don't settle for a solution if it feels too clunky, take a moment and see if
 * you can make it simpler.
 */

int main() {
  int n;
cin >> n;
for(int i = 0; i < n; ++i) {
	solve();
}

  return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

#define            ll              long long
#define            pb              push_back
#define            mp              make_pair
#define            loop(i,a,n)     for(int i=a;i<n;++i)
#define            min3(a,b,c)     min(a,min(b,c))
#define            max3(a,b,c)     max(a,max(b,c))
#define            min4(a,b,c,d)   min(a,min(b,min(c,d)))
#define            max4(a,b,c,d)   max(a,max(b,max(c,d)))
#define            fast            ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define            pii             pair<int,int>
#define            pll             pair<ll,ll>
#define            pli             pair<ll,int>
#define            pil             pair<int,ll>
#define            FF              first
#define            SS              second
#define            PI              acos(-1.0)

using namespace std;
using namespace __gnu_pbds;

typedef tree<int , null_type,less<int>,
       rb_tree_tag, tree_order_statistics_node_update> anik;

const int MOD = 1e9 + 7;
const ll MX= 1e9;
const ll INF = 1e9;

char s[42];

main()
{
    int t;
    cin>>t;
    while(t--)
    {

        cin>>s;
        int k=strlen(s)-4,year=atoi(s+4),f=0,tenpow=10;
        loop(i,0,k-1)
        {
            f+=tenpow;
            tenpow*=10;

        }
        while(year< 1989+f)year+=tenpow;
        cout<<year<<endl;
    }
}


#define _CRT_SECURE_NO_DEPRECATE
#pragma comment(linker, "/STACK:167772160000")
#include <iostream>
#include <fstream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <string>
#include <list>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <iomanip>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <sstream>
#include <assert.h>
#include <functional>
#include <climits>
#include <cstring>
#define double long double
typedef long long ll;
typedef std::pair<ll, ll> pll;
typedef std::pair<int, int> pii;
//typedef std::pair<long double,long double> pdd;
#define fori(N)          for(int i = 0; i<N; i++)
#define forj(N)         for(int j = 0; j<N; j++)
#define fork(N)         for(int k = 0; k<N; k++)
#define fori1(N)          for(int i = 1; i<=N; i++)
#define forj1(N)         for(int j = 1; j<=N; j++)
#define fork1(N)         for(int k = 1; k<=N; k++)
#define PI (2*asin(1))
#define v vector
#define ll long long
#define print(n) printf("%d ", (n));
#define printll(n) printf("%I64d ", (n));
#define printline() printf("\n");
#define read(n) scanf("%d", &n);
#define read2(n, m) scanf("%d%d", &n, &m);
#define readll(n) scanf("%I64d", &n);
#define mp make_pair
using namespace std;
const int maxn = 200000;
map<int, int>used;
stack<int>destroy;

inline ll intersect(ll a, ll b) {
	if (a > b)return 0;
	return (b - a + 1)*(b - a+2) / 2;

}

ll update(int a, int b) {
	if (a > b)return 0;
	int frm = a;
	ll ret = intersect(a, b);
	map<int, int>::iterator it = used.upper_bound(a);
	if (it != used.begin()) {
		it--;
		if (it->second >= b)return 0;
		if (it->second >= a) {
			ret -= intersect(a, it->second);
			frm = it->second;
		}
		it++;
	}
	while (it != used.end() && it->second <= b) {
		destroy.push(it->first);
//		frm = max(it->first, frm);
		ret -= intersect(it->first, it->second) - intersect(it->first, frm);
		frm = it->second;

		it++;
	}
	if (it != used.end()) {
		ret -= intersect(it->first, b) - intersect(it->first, frm);

	}
	while (!destroy.empty()) {
		used.erase(destroy.top());
		destroy.pop();

	}
	used[a] = b;
	return ret;

}
int primes[100000];
int primeCount;
bool isPrime[maxn+1010];
v<int>places[maxn + 1];
v<int>trueplaces[maxn + 1];
int a[maxn + 10];

int min1, min2, max1, max2;

void upd(int x) {
	if (x == min1 || x == max1)return;
	int b = x;
	if (b < min1) swap(b, min1);
	min2 = min(min2, b);
	if (x > max1) swap(x, max1);
	max2 = max(max2, x);

}

int main()
{
#if defined(_DEBUG) || defined(_RELEASE)
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//(File".in", "r", stdin); freopen(File".out", "w", stdout);
	//freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif
	ll answer = 0;
	fori1(maxn)isPrime[i] = 1;
	isPrime[1] = 0;
	fori1(maxn+1000) {
		if (!isPrime[i])continue;
		primes[primeCount++] = i;
		for (int j = 2 * i; j <= maxn + 1000; j += i)isPrime[j] = 0;

	}
	int n; cin >> n;
	fori(n)cin >> a[i];
	fori(n)places[a[i]].push_back(i);
	for (int i = maxn; i > 0; i--) {
		max1 = max2 = -2E9;
		min1 = min2 = 2E9;
		for (int j = 0; i*primes[j] <= maxn; j++) {
			fork(trueplaces[primes[j]*i].size()) upd(trueplaces[primes[j] * i][k]);

		}
		fork(places[i].size())upd(places[i][k]);
		if (max1 > -1E9)trueplaces[i].push_back(max1);
		if (max2 > -1E9)trueplaces[i].push_back(max2);
		if (min1 < 1E9)trueplaces[i].push_back(min1);
		if (min2 < 1E9)trueplaces[i].push_back(min2);
		if (max2 < 0)continue;
		answer += i*update(min2 + 1, n - 1);
		answer += i*update(0, max2-1);
		answer += i*update(min1 + 1, max1 - 1);
	}
	cout << answer;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define X first
#define Y second
#define MP make_pair
#define PCI pair<char,int>
#define PII pair<int,int>
#define PIII pair<pair<int,int>,int>
#define PCCI pair<pair<char,char>,int>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;

const int maxn = 2e5+10;
int n,a[maxn],num[maxn],l[2][maxn],r[2][maxn];
ll ans[maxn],Ans;
vector<int> fen[maxn],s[maxn];
int mx[maxn<<2],mi[maxn<<2],cov[maxn<<2];
ll sum[maxn<<2];

void up(int rt){
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
    mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void build(int l,int r,int rt){
    cov[rt]=0;
    if(l==r){
        mx[rt]=mi[rt]=l;
        sum[rt]=l;
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    up(rt);
}

void down(int rt,int len){
    if(cov[rt]){
        cov[rt<<1]=cov[rt<<1|1]=mi[rt<<1]=mi[rt<<1|1]=mx[rt<<1]=mx[rt<<1|1]=cov[rt];
        sum[rt<<1]=1ll*(len+1)/2ll*cov[rt];
        sum[rt<<1|1]=1ll*len/2ll*cov[rt];
        cov[rt]=0;
    }
}

void upd(int L,int R,int x,int l,int r,int rt){
    if(L>r||R<l||mi[rt]>=x) return;
    int m=(l+r)>>1;
    if(L<=l&&r<=R&&mx[rt]<=x){
        mi[rt]=mx[rt]=cov[rt]=x;
        sum[rt]=1ll*x*(r-l+1);
        return;
    }
    down(rt,r-l+1);
    if(L<=m) upd(L,R,x,lson);
    if(R>m) upd(L,R,x,rson);
    up(rt);
}

int main(){
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++){
        s[a[i]].push_back(i);
    }
    for(int i=1;i<=2e5;i++){
        for(int j=i;j<=2e5;j+=i){
            for(int k=0;k<s[j].size();k++){
                fen[s[j][k]].push_back(i);
                num[i]++;
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<fen[i].size();j++){
            int x=fen[i][j];
            if(!l[0][x]) l[0][x]=i;
            else if(!l[1][x]) l[1][x]=i;
        }
    }
    for(int i=n;i>=1;i--){
        for(int j=0;j<fen[i].size();j++){
            int x=fen[i][j];
            if(!r[0][x]) r[0][x]=i;
            else if(!r[1][x]) r[1][x]=i;
        }
    }
    build(1,n,1);
    ans[0]=2;
    for(int i=2e5;i>=1;i--){
        ans[i]=1ll*(n+1)*n-sum[1]-1;
        if(num[i]>=2){
            //printf("%d %I64d %I64d\n",i,sum[1],ans[i]);
            upd(1,l[0][i],r[1][i],1,n,1);
            upd(l[0][i]+1,l[1][i],r[0][i],1,n,1);
            upd(l[1][i]+1,n,n+1,1,n,1);
        }
    }
    for(int i=2e5;i>=1;i--){
        ans[i]=ans[i]-ans[i-1];
        //if(ans[i]) printf("%d %I64d\n",i,ans[i]);
        Ans+=1ll*i*ans[i];
    }
    printf("%I64d\n",Ans);
    return 0;
}