#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <numeric>
#include <algorithm>
#include <cstring>
#include <cassert>
using namespace std;

const int N = 30;
const int Q = 1000;
const int di[4] = {-1, 1, 0, 0};
const int dj[4] = {0, 0, -1, 1};
const int REV[4] = {1, 0, 3, 2};
const string DIR = "UDLR";

struct Edge {
    int i, j, k;
};

struct Path {
    int cost;
    bool used[30][30][2];
    vector<Edge> edge;

    Path() : cost(0), edge(0) {
        memset(used, 0, sizeof(used));
    }

    void add_edge(const Edge& e) {
        assert(not used[e.i][e.j][e.k] and "Invalid Edge");
        used[e.i][e.j][e.k] = true;
        edge.push_back(e);
    }
};

class EstimatedGrid {
private:
    int weight[30][30][2];
    vector<Path> sample_path;

public:
    EstimatedGrid() {
        for (int i=0; i<N; ++i) {
            for (int j=0; j<N; ++j) {
                weight[i][j][0] = 5000;
                weight[i][j][1] = 5000;
            }
        }
    }

    Edge get_edge(int i, int j, int d) {
        if (DIR[d] == 'U') return Edge{i - 1, j, 0};
        if (DIR[d] == 'D') return Edge{i, j, 0};
        if (DIR[d] == 'L') return Edge{i, j - 1, 1};
        if (DIR[d] == 'R') return Edge{i, j, 1};
        assert(false and "Invalid Direction");
    }

    vector<int> estimated_shortest_path(int si, int sj, int ti, int tj) {
        struct State {
            int i, j, c;
            bool operator > (const State& o) const { return c > o.c; }
        };

        vector<vector<int>> cost(N, vector<int>(N, 1L << 30));
        vector<vector<int>> memo(N, vector<int>(N, -1));

        priority_queue<State, vector<State>, greater<State>> que;
        que.push(State{si, sj, 0});
        cost[si][sj] = 0;

        while (!que.empty()) {
            State sta = que.top(); que.pop();

            if (cost[sta.i][sta.j] < sta.c) continue;
            if (sta.i == ti and sta.j == tj) break;

            for (int d=0; d<4; ++d) {
                int ni = sta.i + di[d];
                int nj = sta.j + dj[d];

                if (ni < 0 or ni >= N) continue;
                if (nj < 0 or nj >= N) continue;
                
                Edge e = get_edge(sta.i, sta.j, d);
                int nc = sta.c + weight[e.i][e.j][e.k];
                if (cost[ni][nj] > nc) {
                    que.push(State{ni, nj, nc});
                    cost[ni][nj] = nc;
                    memo[ni][nj] = d;
                }
            }
        }

        vector<int> P;
        int i = ti, j = tj;
        while (memo[i][j] != -1) {
            P.push_back(memo[i][j]);
            int d = REV[memo[i][j]];
            i += di[d];
            j += dj[d];
        }
        reverse(P.begin(), P.end());
        return P;
    }

    string path_to_string(const vector<int>& P) {
        string ret = "";
        for (int d : P) ret += DIR[d];
        return ret;
    }

    void add_path(
        int si, int sj, int ti, int tj,
        const vector<int>& P, int cost
    ) {
        Path path;
        path.cost = cost;
        int i = si, j = sj;
        for (int d : P) {
            Edge e = get_edge(i, j, d);
            path.add_edge(e);
            i += di[d];
            j += dj[d];
        }
        assert(i == ti and j == tj);
        sample_path.push_back(path);
    }
};

int main() {
    EstimatedGrid G;
    for (int q=0; q<Q; ++q) {
        int si, sj, ti, tj;
        cin >> si >> sj >> ti >> tj;
        vector<int> P = G.estimated_shortest_path(si, sj, ti, tj);
        cout << G.path_to_string(P) << endl;
        int cost;
        cin >> cost;
        G.add_path(si, sj, ti, tj, P, cost);
    }
}
// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
#define ALL(x) (x).begin(),(x).end()
#define mem(x,y) memset(x,y,sizeof x)
#define sz(x) (int)(x).size()
#define ln std::puts("")
#define lsp std::putchar(32)
#define pb push_back
#define MP std::make_pair
#ifdef _LOCAL_
#define dbg(x) std::cerr<<__func__<<"\tLine:"<<__LINE__<<' '<<#x<<": "<<x<<"\n"
#define dprintf(x...) std::fprintf(stderr,x)
#else
#define dbg(x) 42
#define dprintf(x...) 42
#endif
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,b,a) for(int i=(b);i>=(a);--i)
template <class t> inline void read(t &s){s=0;
reg int f=1;reg char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c))s=(s<<3)+(s<<1)+(c^48),c=getchar();s*=f;return;}
template<class t,class ...A> inline void read(t &x,A &...a){read(x);read(a...);}
template <class t> inline void write(t x){if(x<0)putchar('-'),x=-x;
int buf[21],top=0;while(x)buf[++top]=x%10,x/=10;if(!top)buf[++top]=0;
while(top)putchar(buf[top--]^'0');return;}
inline void setIn(std::string s){freopen(s.c_str(),"r",stdin);return;}
inline void setOut(std::string s){freopen(s.c_str(),"w",stdout);return;}
inline void setIO(std::string s=""){setIn(s+".in");setOut(s+".out");return;}
template <class t>inline bool ckmin(t&x,t y){if(x>y){x=y;return 1;}return 0;}
template <class t>inline bool ckmax(t&x,t y){if(x<y){x=y;return 1;}return 0;}
inline int lowbit(int x){return x&(-x);}
const int MaxN=3050;

const int Mod=1e9+7;
const int Mod_Is_Prime=1;

namespace MINT
{
	inline long long exgcd(long long a,long long b,long long &x,long long &y)
	{long long c;return (!b)?(x=1,y=0,a):(c=exgcd(b,a%b,y,x),y-=a/b*x,c);}
}
struct mint
{
	int x;
	mint(){x=0;}
	template <class T> mint(T v){x=(v%Mod+Mod)%Mod;}
	inline int val() const{return x;}
	inline mint operator ++ (){return (++x)>=Mod&&(x-=Mod);}
	inline mint operator -- (){return (--x)<0&&(x+=Mod);}
	inline mint operator + (const mint &nt) const
	{return (x+nt.x)>=Mod?(x+nt.x-Mod):(x+nt.x);}
	inline mint operator - (const mint &nt) const
	{return x<nt.x?(x+Mod-nt.x):(x-nt.x);}
	inline mint operator * (const mint &nt) const{return 1LL*x*nt.x%Mod;}
	inline mint& operator += (const mint &nt){return *this=*this+nt;}
	inline mint& operator -= (const mint &nt){return *this=*this-nt;}
	inline mint& operator *= (const mint &nt){return *this=*this*nt;}
	inline mint fpow(long long b) const
	{
		assert(b>=0);
		reg mint a=*this,res=1;
		for(;b;b>>=1,a*=a)if(b&1)res*=a;
		return res;
	}
	inline mint inv() const
	{
		if(Mod_Is_Prime)return fpow(Mod-2);
		long long X,Y,G=MINT::exgcd(x,Mod,X,Y);
		assert(G==1);
		return (X%Mod+Mod)%Mod;
	}
	inline mint operator / (const mint &nt) const{return nt.inv()*x;}
	inline mint operator /= (const mint &nt){return *this=*this/nt;}
	inline mint operator == (const mint &nt)const{return x==nt.x;}
	inline mint operator != (const mint &nt)const{return x!=nt.x;}
};

int a[MaxN],s[MaxN],n;
mint f[MaxN][MaxN],w[MaxN][MaxN];
signed main(void)
{
	read(n);
	for(int i=1;i<=n;++i)read(a[i]),s[i]=s[i-1]+a[i];
	f[0][0]=1,w[1][0]=1;
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=i;++j)f[i][j]+=w[j][s[i]%j];
		if(i<n)for(int j=0;j<=i;++j)w[j+1][s[i]%(j+1)]+=f[i][j];
	}
	reg mint ans=0;
	for(int i=1;i<=n;++i)ans+=f[n][i];
	write(ans.val()),ln;
	return 0;
}

/*
 * Check List:
 * 1. Input / Output File (OI)
 * 2. long long 
 * 3. Special Test such as n=1
 * 4. Array Size
 * 5. Memory Limit (OI) int is 4 and longlong is 8
 * 6. Mod (a*b%p*c%p not a*b*c%p  ,  (a-b+p)%p not a-b )
 * 7. Name ( int k; for(int k...))
 * 8. more tests , (T=2 .. more)
 * 9. blank \n after a case
*/





