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

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];

ifstream fi("in");

pair<int*,ll> dfs(int i, int j) {
    if (i>j)
        return {new int[500001],0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<int*,ll> ans1 = dfs(s+1,j);
    pair<int*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        ans1.first[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    ans2.first[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n,num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    int *ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


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

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];

ifstream fi("in");

pair<deque<ii>*,ll> dfs(int i, int j) {
    if (i>j)
        return {new deque<ii>,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<deque<ii>*,ll> ans1 = dfs(s+1,j);
    pair<deque<ii>*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        (*ans1.first).pf({s-i+1,mi});
        free(ans2.first);
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    (*ans2.first).pb({j-s+1,mi});
    free(ans1.first);
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n,num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    deque<ii>* ans = dfs(1,n).first;
    for (auto [a,b] : *ans) {
        for (int i = 0; i < a; ++i) cout << b << " ";
    }
    cout << "\n";
    return 0;
}


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

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];

ifstream fi("in");

pair<map<int,int>*,ll> dfs(int i, int j) {
    if (i>j)
        return {new map<int,int>,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<map<int,int>*,ll> ans1 = dfs(s+1,j);
    pair<map<int,int>*,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        (*ans1.first)[i] = mi+1;
        return {ans1.first, ll(s-i+1)*ll(mi)+ans1.second};
    }
    (*ans2.first)[s] = mi+1;
    return {ans2.first, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n,num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    map<int,int>* ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!(*ans)[i]) (*ans)[i]=(*ans)[i-1];
        cout << (*ans)[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


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

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<array<int, 500001>,ll> dfs(int i, int j) {
    cnt++;
    array<int, 500001> res;
    if (i>j) return {res,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<array<int, 500001>,ll> ans1 = dfs(s+1,j);
    pair<array<int, 500001>,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        res = ans1.first;
        res[i] = mi+1;
        return {res, ll(s-i+1)*ll(mi)+ans1.second};
    }
    res = ans2.first;
    res[s] = mi+1;
    return {res, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    array<int, 500001> ans = dfs(1,n).first;
    for (int i = 1; i <= n; ++i) {
        if (!ans[i]) ans[i]=ans[i-1];
        cout << ans[i]-1 << " ";
    }
    cout << "\n";
    return 0;
}


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

#define mp          make_pair
#define pb          push_back
#define pf          push_front
#define cin         fi
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<deque<ii>,ll> dfs(int i, int j) {
    cnt++;
    deque<ii> res;
    if (i==j) {
        res.pb({1,sp[0][i].first});
        return {res,sp[0][i].first};
    }
    else if (i>j) return {res,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<deque<ii>,ll> ans1 = dfs(s+1,j);
    pair<deque<ii>,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        res = ans1.first;
        res.pf({s-i+1,mi});
        return {res, ll(s-i+1)*ll(mi)+ans1.second};
    }
    res = ans2.first;
    res.pb({j-s+1,mi});
    return {res, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    deque<ii> ans = dfs(1,n).first;
    for (ii i: ans) for (int j = 0; j < i.first; ++j) cout << i.second << " ";
    cout << "\n" << cnt << "\n";
    return 0;
}


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

#define mp          make_pair
#define pb          push_back
#define pf          push_front
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
ii sp[19][500001];
//Use sparse table!
//UPD: this code's crazy!
//UPD2: TLE on test 9 although it should be o(nlogn)
//UPD3: it's because merging two stl vectors teks o(n) time
//UPD4: let's see

ll cnt = 0;

ifstream fi("in");

pair<deque<ii>,ll> dfs(int i, int j) {
    cnt++;
    deque<ii> res;
    if (i==j) {
        res.pb({1,sp[0][i].first});
        return {res,sp[0][i].first};
    }
    else if (i>j) return {res,0};
    int s, p = log2(j-i+1), mi = min(sp[p][i].first,sp[p][j-int(pow(2,p))+1].first);
    if (sp[p][j-int(pow(2,p))+1].first==mi) s = sp[p][j-int(pow(2,p))+1].second;
    else s = sp[p][i].second;
    pair<deque<ii>,ll> ans1 = dfs(s+1,j);
    pair<deque<ii>,ll> ans2 = dfs(i,s-1);
    if (ll(s-i+1)*ll(mi)+ans1.second>ll(j-s+1)*ll(mi)+ans2.second) {
        res = ans1.first;
        res.pf({s-i+1,mi});
        return {res, ll(s-i+1)*ll(mi)+ans1.second};
    }
    res = ans2.first;
    res.pb({j-s+1,mi});
    return {res, ll(j-s+1)*ll(mi)+ans2.second};
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, num;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> num;
        sp[0][i] = {num,i};
    }
    for (int i = 1; i <= log2(n); ++i) {
        for (int j = 1; j <= n-int(pow(2,i))+1; ++j) {
            if (sp[i-1][j].first<sp[i-1][j+int(pow(2,i-1))].first) sp[i][j] = sp[i-1][j];
            else sp[i][j] = sp[i-1][j+int(pow(2,i-1))];
        }
    }
    deque<ii> ans = dfs(1,n).first;
    for (ii i: ans) for (int j = 0; j < i.first; ++j) cout << i.second << " ";
    return 0;
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n;
ll peak, res = 0;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    // if (L>i-1){
    //     if (sum+vr>res){ res = sum+vr; peak = i; }
    // }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    // if (i+1>R){
    //     if (sum+vl>res){ res = sum+vl; peak = i; }
    // }
    return;
}

void solve(){
    cin >> n;
    vll a(n, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


/*6
1 5 2 100 1 5 2
9
1 3 4 7 2 5 100 4 10 5 */

/*
seg tree ka logc h ki .. Hume Peak point nikalna h
Ab ek hai value variable. jo ye batata h agar ye index peak hua to kitni value ayegi, bas is index (& peak obvio
ko nikalna h
phle [l,r] paas kiya.
seg tree ne btaya ki minimum element konsa h.
say index indexmini pe hai min. element. (l l+1 ... indexmini ..... r-1 r ) kush aisa dikhega
to ab 2 options
1. l se indexmini tak sabko a[ind] (joki minimum element hai), vo kardo, aage ka paas krdo
iski value add  krke solve2(indexmini+1,r,value+value1);

2. indexmini se r tak sabko a[ind] (joki minimum element hai), vo kardo aage ka paas krdo
iski value add  krke
solve2(l,indexmini-1,value+value2);

Bas phir Peak milgya tab to nikal lo !

*/

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define x first
#define y second
#define all(x) x.begin(),x.end()
#define f(i,a,b) for(ll i=a;i<b;++i)
#define rof(i,a,b) for(ll i=a;i>b;i--)
#define endl "\n"
ll mod=1e9+7;
 ll a[500001];int seg[4*500001];
ll n;//=500001;

ll peak,maxi=-1;
void built(int l,int r,int index)
{
    if(l==r)
    {seg[index]=l;return;}
    int m=l+(r-l)/2;

    built(l,m,2*index);
    built(m+1,r,2*index+1);

    if(a[seg[2*index]]<a[seg[2*index+1]])
    	seg[index]=seg[2*index];
    else seg[index]=seg[2*index+1];
}

int query(int l,int r,int s,int e,int index)
{

     if(s>r||e<l) return -1;
     if(s>=l&&e<=r) return seg[index];
     int m=s+(e-s)/2;
     int d1=query(l,r,s,m,2*index);
     int d2=query(l,r,m+1,e,2*index+1);

     if(d1==-1) return d2;
     if(d2==-1) return d1;
     if(a[d1]<a[d2]) return d1;
     else return d2;

   }

void solve2(ll l,ll r,ll value)
{
if(l>r) return;
	if(l==r)
	{
		if(value+a[l]>maxi) {
			maxi=a[l]+value;peak=l;return;
		}
		return;
	}

int indexmini=query(l,r,0,n-1,1);
ll value1=a[indexmini]*(indexmini-l+1);

solve2(indexmini+1,r,value+value1);
// if(indexmini+1>r)
// {
// 	if(value+value1>maxi) {
// 			maxi=value+value1;peak=indexmini;
// 		}
// }

ll value2=a[indexmini]*(r-indexmini+1);

solve2(l,indexmini-1,value+value2);
// if(l>indexmini-1)
// {
// 	if(value+value2>maxi) {
// 			maxi=value+value2;peak=l;
// 		}
// }

}

void solve()
{
    cin>>n;

    f(i,0,n) {cin>>a[i];}

built(0,n-1,1);

solve2(0,n-1,0);
ll ans[n];
ans[peak]=a[peak];
f(i,peak+1,n)
{
	ans[i]=min(ans[i-1],a[i]);
}
for(int i=peak-1;i>=0;i--)
{
	ans[i]=min(a[i],ans[i+1]);
}
f(i,0,n) cout<<ans[i]<<" ";

}

int main()
{

ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll t=1;
 //   cin>>t;
    while(t--)
    {
     solve();
    }
cerr << "Time elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n;
ll peak, res = -1;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    // cout << a[i] << "\n";
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    // if (L>i-1){
    //     if (sum+vr>res){ res = sum+vr; peak = i; }
    // }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    // if (i+1>R){
    //     if (sum+vl>res){ res = sum+vl; peak = i; }
    // }
}

void solve(){
    cin >> n;
    vll a(n+5, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n;
ll peak, res = -1;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    if (L>i-1){
        if (sum+vr>res){ res = sum+vr; peak = i; }
    }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    if (i+1>R){
        if (sum+vl>res){ res = sum+vl; peak = i; }
    }
    return;
}

void solve(){
    cin >> n;
    vll a(n, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 1000000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 500005, M = 1e9+7;
int tt;
ll n, m[mxN];

void solve(){
    cin >> n;
    F0R(i, n)
        cin >> m[i];
    vll tmp(n), ans(n); ll res = 0;
    for(int i = 0; i < n; i++){
        // iterate over the highest point
        tmp[i] = m[i];
        for(int j = i-1; j >= 0; j--){
            tmp[j] = min(tmp[j+1], m[j]);
        }
        for(int j = i+1; j<n; j++){
            tmp[j] = min(tmp[j-1], m[j]);
        }
        ll cnt = 0;
        for(int i = 0; i < n; i++)
            cnt += tmp[i];
        if (cnt > res){
            res = cnt;
            ans = tmp;
        }
    }
    for(int i = 0; i < n; i++)
        cout << ans[i] << " ";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n, peak, res = 0;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
    }
    int i = st.rmq(L, R);
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    if (L>i-1){
        if (sum+vr>res){ res = sum+vr; peak = i; }
    }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    if (i+1>R){
        if (sum+vl>res){ res = sum+vl; peak = i; }
    }
    return;
}

void solve(){
    cin >> n;
    vll a(n, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


/*6
1 5 2 100 1 5 2
9
1 3 4 7 2 5 100 4 10 5 */

/*
seg tree ka logc h ki .. Hume Peak point nikalna h
Ab ek hai value variable. jo ye batata h agar ye index peak hua to kitni value ayegi, bas is index (& peak obvio
ko nikalna h
phle [l,r] paas kiya.
seg tree ne btaya ki minimum element konsa h.
say index indexmini pe hai min. element. (l l+1 ... indexmini ..... r-1 r ) kush aisa dikhega
to ab 2 options
1. l se indexmini tak sabko a[ind] (joki minimum element hai), vo kardo, aage ka paas krdo
iski value add  krke solve2(indexmini+1,r,value+value1);

2. indexmini se r tak sabko a[ind] (joki minimum element hai), vo kardo aage ka paas krdo
iski value add  krke
solve2(l,indexmini-1,value+value2);

Bas phir Peak milgya tab to nikal lo !

*/

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define x first
#define y second
#define all(x) x.begin(),x.end()
#define f(i,a,b) for(ll i=a;i<b;++i)
#define rof(i,a,b) for(ll i=a;i>b;i--)
#define endl "\n"
ll mod=1e9+7;
 ll a[500001];int seg[4*500001];
ll n;//=500001;

ll peak,maxi=-1;
void built(int l,int r,int index)
{
    if(l==r)
    {seg[index]=l;return;}
    int m=l+(r-l)/2;

    built(l,m,2*index);
    built(m+1,r,2*index+1);

    if(a[seg[2*index]]<a[seg[2*index+1]])
    	seg[index]=seg[2*index];
    else seg[index]=seg[2*index+1];
}

int query(int l,int r,int s,int e,int index)
{

     if(s>r||e<l) return -1;
     if(s>=l&&e<=r) return seg[index];
     int m=s+(e-s)/2;
     int d1=query(l,r,s,m,2*index);
     int d2=query(l,r,m+1,e,2*index+1);

     if(d1==-1) return d2;
     if(d2==-1) return d1;
     if(a[d1]<a[d2]) return d1;
     else return d2;

   }

void solve2(ll l,ll r,ll value)
{
if(l>r) return;
	if(l==r)
	{
		if(value+a[l]>maxi) {
			maxi=a[l]+value;peak=l;return;
		}
		return;
	}

int indexmini=query(l,r,0,n-1,1);
ll value1=a[indexmini]*(indexmini-l+1);

solve2(indexmini+1,r,value+value1);
if(indexmini+1>r)
{
	if(value+value1>maxi) {
			maxi=value+value1;peak=indexmini;
		}
}

ll value2=a[indexmini]*(r-indexmini+1);

solve2(l,indexmini-1,value+value2);
if(l>indexmini-1)
{
	if(value+value2>maxi) {
			maxi=value+value2;peak=l;
		}
}

}

void solve()
{
    cin>>n;

    f(i,0,n) {cin>>a[i];}

built(0,n-1,1);

solve2(0,n-1,0);
ll ans[n];
ans[peak]=a[peak];
f(i,peak+1,n)
{
	ans[i]=min(ans[i-1],a[i]);
}
for(int i=peak-1;i>=0;i--)
{
	ans[i]=min(a[i],ans[i+1]);
}
f(i,0,n) cout<<ans[i]<<" ";

}

int main()
{

ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll t=1;
 //   cin>>t;
    while(t--)
    {
     solve();
    }
cerr << "Time elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 1000000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 1005, M = 1e9+7;
int tt;
ll n, m[mxN];

void solve(){
    cin >> n;
    F0R(i, n)
        cin >> m[i];
    vll tmp(n), ans(n); ll res = 0;
    for(int i = 0; i < n; i++){
        // iterate over the highest point
        tmp[i] = m[i];
        for(int j = i-1; j >= 0; j--){
            tmp[j] = min(tmp[j+1], m[j]);
        }
        for(int j = i+1; j<n; j++){
            tmp[j] = min(tmp[j-1], m[j]);
        }
        ll cnt = 0;
        for(int i = 0; i < n; i++)
            cnt += tmp[i];
        if (cnt > res){
            res = cnt;
            ans = tmp;
        }
    }
    for(int i = 0; i < n; i++)
        cout << ans[i] << " ";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n;
ll peak, res = -1;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    cout << a[i] << "\n";
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    // if (L>i-1){
    //     if (sum+vr>res){ res = sum+vr; peak = i; }
    // }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    // if (i+1>R){
    //     if (sum+vl>res){ res = sum+vl; peak = i; }
    // }
}

void solve(){
    cin >> n;
    vll a(n+5, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n;
ll peak, res = -1;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    // if (L>i-1){
    //     if (sum+vr>res){ res = sum+vr; peak = i; }
    // }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    // if (i+1>R){
    //     if (sum+vl>res){ res = sum+vl; peak = i; }
    // }
    return;
}

void solve(){
    cin >> n;
    vll a(n, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n;
ll peak, res = -1;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    // cout << a[i] << "\n";
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    // if (L>i-1){
    //     if (sum+vr>res){ res = sum+vr; peak = i; }
    // }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    // if (i+1>R){
    //     if (sum+vl>res){ res = sum+vl; peak = i; }
    // }
}

void solve(){
    cin >> n;
    vll a(n+5, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], ans[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], ans[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n, peak, res = 0;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
    }
    int i = st.rmq(L, R);
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    return;
}

void solve(){
    cin >> n;
    vll a(n, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n, peak, res = 0;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    // if (L>i-1){
    //     if (sum+vr>res){ res = sum+vr; peak = i; }
    // }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    // if (i+1>R){
    //     if (sum+vl>res){ res = sum+vl; peak = i; }
    // }
    return;
}

void solve(){
    cin >> n;
    vll a(n, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


#include <ctime>
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <map>
#include <array>
#include <unordered_map>
#include <unordered_set>
#include <string.h>
#include <numeric>
#include <chrono>
#include <cstdio>
#include <string>

using namespace std;

typedef long long ll;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef pair<ll, int> lli;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;
typedef set<int> si;

const int INF = 2147483647;
const ll llinf = 10000000000000000ll;
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define R0F(i,a) for (int i = a-1; i >= 0; --i)
#define FOREACH(i,x) for (auto& i: x)

#define pr make_pair
#define pb push_back
#define rsz resize
#define all(x) begin(x), end(x)

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

// math macros
ll gcd(ll a , ll b){
   if(b==0) return a;
   a%=b;
   return gcd(b,a);
}

ll lcm(ll a, ll b){
    return a*b/gcd(a, b);
}

bool isPrime(ll num) {
  ll n = num;
  if (n <= 1) return false;
  else if (n == 2) return true;
  ll prime = 1;
  for(int i = 2; i <= sqrt(abs(n)); i++){
    if (n%i == 0){
      prime = 0;
      break;
    }
  }
  return (prime ? true : false);
}

void setIO(string name) {
	freopen(("./codeforces/"+ name + ".in").c_str(),"r",stdin);
	freopen(("./codeforces/"+ name + ".out").c_str(),"w",stdout);
}

const int mxN = 100005, M = 1e9+7;
int tt, n, peak, res = 0;

class SegmentTree {
private:
    vll st, A;
    int n;
    int left (int p) { return p << 1; } // given pos, return 2*pos as index
    int right (int p) { return (p<<1)+1; }

    void build(int p, int L, int R){ // O(n)
        // p represents current node pos
        // L and R are bounds of original A array
        if (L == R) // one index
            st[p] = L; // only one value so its minimum
        else {
            build(left(p), L, (L+R)/2);
            build(right(p), (L+R)/2+1, R);
            int p1 = st[left(p)], p2 = st[right(p)]; // choose minimum
            st[p] = (A[p1] <= A[p2]) ? p1 : p2;
        }
    }

    int rmq(int p, int L, int R, int i, int j){ // O(log n)
        // p is current node, L and R are bounds, i and j are query idx
        if (i > R || j < L) return -1; // not in bounds
        if (L >= i && R <= j) return st[p]; // query range is larger than arr

        // compute min on left and right side
        int p1 = rmq(left(p), L, (L+R)/2, i, j);
        int p2 = rmq(right(p), (L+R)/2+1, R, i, j);
        if (p1 == -1) return p2;
        if (p2 == -1) return p1;
        return (A[p1] <= A[p2]) ? p1 : p2;
    }
public:
    SegmentTree(const vll &_A) { // constructor
        A = _A; n = A.size();
        st.assign(4*n, 0); // use assign for vectors already created
        build(1, 0, n-1); // p = 1 (root = 1)
    }
    int rmq(int i, int j) { return rmq(1, 0, n-1, i, j); }
};

void solve2(vll a, SegmentTree st, ll L, ll R, ll sum){
    if (L > R) return;
    if (L == R){
        if (sum+a[L] > res){
            res = sum+a[L];
            peak = L;
        }
        return;
    }
    int i = st.rmq(L, R);
    // choose the right side to make min
    ll vr = (R-i+1)*(a[i]);
    solve2(a, st, L, i-1, sum+vr);
    if (L>i-1){
        if (sum+vr>res){ res = sum+vr; peak = i; }
    }
    // check case if R < L
    ll vl = (i-L+1)*(a[i]);
    solve2(a, st, i+1, R, sum+vl);
    if (i+1>R){
        if (sum+vl>res){ res = sum+vl; peak = i; }
    }
    return;
}

void solve(){
    cin >> n;
    vll a(n, 0);
    F0R(i, n)
        cin >> a[i];
    SegmentTree st = SegmentTree(a);
    solve2(a, st, 0ll, (ll)n-1, 0ll);
    // trick is to find the optimal peak first, then find the arr
    vll ans(n, 0); ans[peak] = a[peak];
    for(int i = peak-1; i >= 0; i--){
        ans[i] = min(a[i], a[i+1]);
    }
    for(int i = peak+1; i < n; i++)
        ans[i] = min(a[i], a[i-1]);
    for(int i =0; i < n; i++)
        cout << ans[i] << " ";
    cout << "\n";
    // cout << peak << " " << res << "\n";
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0);
    // setIO("practice");
    // cin >> tt;
    tt = 1;
    F0R(i, tt){
        // cout << "Case #" << i+1 << ": ";
        solve();
    }
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[6*MAX],s[6*MAX][20],res[6*MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else {
                    if(s[j][i-1] == s[j+(1<<(i-1))][i-1])
                        s[j][i] = min(s[j][i-1],s[j+(1<<(i-1))][i-1]);
                    else
                        s[j][i] = s[j][i-1];
                }

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1),i;
    if (a[s[l][j]] < a[ s[r - (1 << j) + 1][j] ])
        i = s[l][j];
    else
        i = s[r - (1 << j) + 1][j];

    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1 + (r-i+1)*a[i] >= s2 + (i-l+1)*a[i]){
        FOR(k,i,r+1) res[k]=a[i];
        s1+=(r-i+1)*a[i] ; s2 =0;
    }
    else {
        s2+=(i-l+1)*a[i]; s1=0;
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else
               s[j][i] = s[j][i-1] ;

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1);
    int i = s[l][j];
    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1 + (r-i+1)*a[i] >= s2 + (i-l+1)*a[i]){
        s2=a[i]*(r-i+1);
        FOR(k,i,r+1) res[k]=a[i];
    }
    else {
        s1 = a[i]*(i-l+1);
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);
    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else
                s[j][i] = s[j][i-1] ;

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1);
    int i = s[l][j];
    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1 + (r-i+1)*a[i] >= s2 + (i-l+1)*a[i]){
        s2=a[i]*(r-i+1);
        FOR(k,i,r+1) res[k]=a[i];
    }
    else {
        s1 = a[i]*(i-l+1);
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else {
                    if(s[j][i-1] == s[j+(1<<(i-1))][i-1])
                        s[j][i] = min(s[j][i-1],s[j+(1<<(i-1))][i-1]);
                    else
                        s[j][i] = s[j][i-1];
                }

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1);
    int i = s[l][j];
    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1 + (r-i+1)*a[i] >= s2 + (i-l+1)*a[i]){
        s2=a[i]*(r-i+1);
        FOR(k,i,r+1) res[k]=a[i];
        s1+=(r-i+1)*a[i] ; s2 =0;
    }
    else {
        s2+=(i-l+1)*a[i]; s1=0;
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else {
                    if(s[j][i-1] == s[j+(1<<(i-1))][i-1])
                        s[j][i] = min(s[j][i-1],s[j+(1<<(i-1))][i-1]);
                    else
                        s[j][i] = s[j][i-1];
                }

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1),i;
    if (a[s[l][j]] < a[ s[r - (1 << j) + 1][j] ])
        i = s[l][j];
    else
        i = s[r - (1 << j) + 1][j];

    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1 + (r-i+1)*a[i] >= s2 + (i-l+1)*a[i]){
        FOR(k,i,r+1) res[k]=a[i];
        s1+=(r-i+1)*a[i] ; s2 =0;
    }
    else {
        s2+=(i-l+1)*a[i]; s1=0;
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else
                s[j][i] = s[j][i-1] ;

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1);
    int i = s[l][j];
    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1>=s2){
        s2=a[i]*(r-i+1);
        FOR(k,i,r+1) res[k]=a[i];
    }
    else {
        s1 = a[i]*(i-l+1);
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else {
                    if(s[j][i-1] == s[j+(1<<(i-1))][i-1])
                        s[j][i] = min(s[j][i-1],s[j+(1<<(i-1))][i-1]);
                    else
                        s[j][i] = s[j][i-1];
                }

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1);
    int i = s[l][j];
    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1 + (r-i+1)*a[i] >= s2 + (i-l+1)*a[i]){
        s2=a[i]*(r-i+1);
        FOR(k,i,r+1) res[k]=a[i];
    }
    else {
        s1 = a[i]*(i-l+1);
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
int a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else
                s[j][i] = s[j][i-1] ;

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1);
    int i = s[l][j];
    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1>=s2){

        s2=a[i]*(r-i+1);
        FOR(k,i,r+1) res[k]=a[i];
    }
    else {
        s1 = a[i]*(i-l+1);
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


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

#define fastio ios_base::sync_with_stdio(0); cin.tie(0)
#define LL long long
#define mod 1000000007
#define FOR(i, j, k) for (int i=j ; i<k ; i++)
#define ROF(i, j, k) for (int i=j ; i>=k ; i--)

const long long INF = 1e18;
const long long MAX = 1e5+10;
LL a[MAX],s[MAX][20],res[MAX];
void buildSparseTree(int n){
    FOR(i,0,n)
        s[i][0] = i;

    for(int i = 1; 1<<i<=n;i++)
        for(int j = 0; j+(1<<i)<=n;j++)
            if(a[ s[j][i-1] ] > a[ s[j+(1<<(i-1))][i-1] ])
                s[j][i] =  s[j+(1<<(i-1))][i-1] ;
            else {
                    if(s[j][i-1] == s[j+(1<<(i-1))][i-1])
                        s[j][i] = min(s[j][i-1],s[j+(1<<(i-1))][i-1]);
                    else
                        s[j][i] = s[j][i-1];
                }

}
LL f(int l,int r){
    if(r<l) return -1;
    if(l==r) {res[l]=a[s[l][0]]; return a[s[l][0]];}
    int j = log2(r-l+1);
    int i = s[l][j];
    LL s1 = f(l,i-1);
    LL s2 = f(i+1,r);

    if(s1 + (r-i+1)*a[i] >= s2 + (i-l+1)*a[i]){
        s2=a[i]*(r-i+1);
        FOR(k,i,r+1) res[k]=a[i];
        s1+=(r-i+1)*a[i] ; s2 =0;
    }
    else {
        s2+=(i-l+1)*a[i]); s1=0;
        FOR(k,l,i+1) res[k]=a[i];
    }
    return s1+s2;
}

int main(){
    fastio;
    int n; cin>>n;
    FOR(i,0,n) cin>>a[i];
    buildSparseTree(n);
    LL s =  f(0,n-1);

    FOR(i,0,n) cout<<res[i]<<" ";
}


#include <bits/stdc++.h>

using namespace std;
const int MAXN = 500100;

int n, id, a[MAXN], pfx[MAXN], sfx[MAXN], ans[MAXN];
long long maxans = 0ll;

int first_major(int l, int r, int x){
	while(l < r){
		int m = (l + r) >> 1;
		if(a[m] > x)
			r = m;
		else
			l = m + 1;
	}
	return r;
}

int main(){
	cin >> n;
	for(int i = 1;i <= n;i++)
		cin >> a[i];

	pfx[1] = a[1], sfx[n] = a[n];
	for(int i = 2;i <= n;i++){
		int j = first_major(1, i, a[i]);
		pfx[i] = pfx[j - 1] + (i - j + 1) * a[i];
	}
	for(int i = n - 1;i >= 1;i--){
		int j = first_major(i, n, a[i]);
		sfx[i] = sfx[j + 1] + (j - i + 1) * a[i];
	}

	for(int i = 1;i <= n;i++){
		if(a[i] >= a[i - 1] && a[i] >= a[i + 1] && 0ll + pfx[i - 1] + sfx[i + 1] + a[i] > maxans)
			maxans = 0ll + pfx[i - 1] + sfx[i + 1] + a[i], id = i;
	}

	ans[id] = a[id];
	for(int i = id - 1;i >= 1;i--)
		ans[i] = min(a[i], ans[i + 1]);
	for(int i = id + 1;i <= n;i++)
		ans[i] = min(a[i], ans[i - 1]);
	for(int i = 1;i <= n;i++)
		cout << ans[i] << " ";
}


#include <bits/stdc++.h>

using namespace std;
const int MAXN = 500100;

int n, id, a[MAXN], pfx[MAXN], sfx[MAXN], ans[MAXN];
long long maxans = 0ll;

struct no{
	int l, r, mid, x, lz;
	no *fe, *fd;

	no(int l, int r, int v[]) : l(l), r(r), mid((l + r) >> 1), x(v[l]), lz(0) {
		if(l != r)
			fe = new no(l, mid, v), fd = new no(mid + 1, r, v), x = max(fe->x, fd->x);
	}

	void refresh(){
		if(lz != 0){
			fe->x = lz, fd->x = lz, fe->lz = lz, fd->lz = lz, lz = 0;
		}
	}

	int get(int a, int b){
		if(b < l || r < a)
			return 0;
		if(a <= l && r <= b)
			return x;
		return max(fe->get(a, b), fd->get(a, b));
	}

	void update(int a, int b, int k){
		if(b < l || r < a)
			return;
		refresh();
		if(a <= l && r <= b)
			return void(x = k);
		fe->update(a, b, k), fd->update(a, b, k);
		fe->refresh(), fd->refresh();
		x = max(fe->x, fd->x);
	}
};

int first_major(int l, int r, int x, no &seg){
	while(l < r){
		int m = (l + r) >> 1;
		if(seg.get(m, m) > x)
			r = m;
		else
			l = m + 1;
	}
	return r;
}

int main(){
	cin >> n;
	for(int i = 1;i <= n;i++)
		cin >> a[i];
	no seg(1, n, a);

	pfx[1] = a[1], sfx[n] = a[n];
	for(int i = 2;i <= n;i++){
		int j = first_major(1, i, a[i], seg);
		pfx[i] = pfx[j - 1] + (i - j + 1) * a[i];
		seg.update(j, i, a[i]);
	}
	for(int i = n - 1;i >= 1;i--){
		int j = first_major(i, n, a[i], seg);
		sfx[i] = sfx[j + 1] + (j - i + 1) * a[i];
		seg.update(i, j, a[i]);
	}

	for(int i = 1;i <= n;i++){
		if(a[i] >= a[i - 1] && a[i] >= a[i + 1] && 0ll + pfx[i - 1] + sfx[i + 1] + a[i] > maxans)
			maxans = 0ll + pfx[i - 1] + sfx[i + 1] + a[i], id = i;
	}

	ans[id] = a[id];
	for(int i = id - 1;i >= 1;i--)
		ans[i] = min(a[i], ans[i + 1]);
	for(int i = id + 1;i <= n;i++)
		ans[i] = min(a[i], ans[i - 1]);
	for(int i = 1;i <= n;i++)
		cout << ans[i] << " ";
}


#include <bits/stdc++.h>

using namespace std;
const int MAXN = 500100;

int n, id, a[MAXN], ans[MAXN], first_left[MAXN], first_right[MAXN];
long long pfx[MAXN], sfx[MAXN], maxans = 0ll;

int main(){
	scanf("%d", &n);
	for(int i = 1;i <= n;i++)
		scanf("%d", &a[i]);

	stack<pair<int, int>> s;
	for(int i = n;i >= 1;i--){
		while(!s.empty() && s.top().first > a[i])
			first_left[s.top().second] = i, s.pop();
		s.push({a[i], i});
	}
	s = stack<pair<int, int>>();
	for(int i = 1;i <= n;i++){
		while(!s.empty() && s.top().first > a[i])
			first_right[s.top().second] = i, s.pop();
		s.push({a[i], i});
	}

	for(int i = 1;i <= n;i++){
		if(first_left[i] == 0)
			first_left[i] = 0;
		pfx[i] = pfx[first_left[i] ] + 1ll * (i -  first_left[i]) * a[i];
	}
	for(int i = n;i >= 1;i--){
		if(first_right[i] == 0)
			first_right[i] = n + 1;
		sfx[i] = sfx[first_right[i]] + 1ll * (first_right[i] - i) * a[i];
	}

	for(int i = 1;i <= n;i++)
		if(a[i] >= a[i - 1] && a[i] >= a[i + 1] && maxans < 0ll + pfx[i - 1] + sfx[i + 1] + a[i])
			maxans = 0ll + pfx[i - 1] + sfx[i + 1] + a[i], id = i;

	ans[id] = a[id];
	for(int i = id - 1;i >= 1;i--)
		ans[i] = min(a[i], ans[i + 1]);
	for(int i = id + 1;i <= n;i++)
		ans[i] = min(a[i], ans[i - 1]);

	for(int i = 1;i <= n;i++)
		printf("%d ", ans[i]);
}


#include <bits/stdc++.h>

using namespace std;
const int MAXN = 500100;

int n, id, a[MAXN], ans[MAXN], first_left[MAXN], first_right[MAXN];
long long pfx[MAXN], sfx[MAXN], maxans = 0ll;

int main(){
	scanf("%d", &n);
	for(int i = 1;i <= n;i++)
		scanf("%d", &a[i]);

	stack<pair<int, int>> s;
	for(int i = n;i >= 1;i--){
		while(!s.empty() && s.top().first > a[i])
			first_left[s.top().second] = i, s.pop();
		s.push({a[i], i});
	}
	s = stack<pair<int, int>>();
	for(int i = 1;i <= n;i++){
		while(!s.empty() && s.top().first > a[i])
			first_right[s.top().second] = i, s.pop();
		s.push({a[i], i});
	}

	for(int i = 1;i <= n;i++){
		if(first_left[i] == 0)
			first_left[i] = i - 1;
		pfx[i] = pfx[first_left[i] ] + 1ll * (i -  first_left[i]) * a[i];
	}
	for(int i = n;i >= 1;i--){
		if(first_right[i] == 0)
			first_right[i] = i + 1;
		sfx[i] = sfx[first_right[i]] + 1ll * (first_right[i] - i) * a[i];
	}

	for(int i = 1;i <= n;i++)
		if(a[i] >= a[i - 1] && a[i] >= a[i + 1] && maxans < 0ll + pfx[i - 1] + sfx[i + 1] + a[i])
			maxans = 0ll + pfx[i - 1] + sfx[i + 1] + a[i], id = i;

	ans[id] = a[id];
	for(int i = id - 1;i >= 1;i--)
		ans[i] = min(a[i], ans[i + 1]);
	for(int i = id + 1;i <= n;i++)
		ans[i] = min(a[i], ans[i - 1]);

	for(int i = 1;i <= n;i++)
		printf("%d ", ans[i]);
}


#include <bits/stdc++.h>

using namespace std;
const int MAXN = 500100;

int n, id, maxh, a[MAXN], ans[MAXN];

int main(){
	cin >> n;
	for(int i = 1;i <= n;i++){
		cin >> a[i];
		if(maxh < a[i])
			maxh = a[i], id = i;
	}

	ans[id] = maxh;
	for(int i = id - 1;i >= 1;i--)
		ans[i] = min(a[i], ans[i + 1]);
	for(int i = id + 1, lasth = maxh;i <= n;i++)
		ans[i] = min(a[i], ans[i - 1]);
	for(int i = 1;i <= n;i++)
		cout << ans[i] << " ";
}


#include <bits/stdc++.h>

using namespace std;
const int MAXN = 500100;

#define int long long
long long n, id, a[MAXN];
long long pfx[MAXN], sfx[MAXN], ans[MAXN];
long long maxans = 0ll;

struct no{
	int l, r, mid, x, lz;
	no *fe, *fd;

	no(int l, int r, int v[]) : l(l), r(r), mid((l + r) >> 1), x(v[l]), lz(0) {
		if(l != r)
			fe = new no(l, mid, v), fd = new no(mid + 1, r, v), x = max(fe->x, fd->x);
	}

	void refresh(){
		if(lz != 0 && l != r)
			fe->x = lz, fd->x = lz, fe->lz = lz, fd->lz = lz;
		lz = 0;
	}

	int get(int a, int b){
		if(b < l || r < a)
			return 0;
		refresh();
		if(a <= l && r <= b)
			return x;
		refresh();
		return max(fe->get(a, b), fd->get(a, b));
	}

	void update(int a, int b, int k){
		if(b < l || r < a)
			return;
		refresh();
		if(a <= l && r <= b)
			return void((x = k, lz = k));
		refresh();
		fe->update(a, b, k), fd->update(a, b, k);
		fe->refresh(), fd->refresh();
		x = max(fe->x, fd->x);
	}

	void print(){
		refresh();
		if(l != r){
			fe->print();
			fd->print();
		}
		else
			cout << x << " ";
	}
} *seg;

int first_major(int l, int r, int x){
	// seg->print();
	// cout << "\n";
	while(l < r){
		int m = (l + r) >> 1;
		// dbg(l, r, seg->get(m, m), x);
		if(seg->get(m, m) > x)
			r = m;
		else
			l = m + 1;
	}
	// cout << "SAI\n";
	return r;
}

signed main(){
	cin >> n;
	for(int i = 1;i <= n;i++)
		cin >> a[i];
	seg = new no(1, n, a);
	// seg->print();
	// cout << "\n";

	pfx[1] = a[1], sfx[n] = a[n];
	for(int i = 2;i <= n;i++){
		int j = first_major(1, i, a[i]);
		pfx[i] = pfx[j - 1] + 1ll * (i - j + 1) * a[i];
		// dbg(j, i, a[i]);
		seg->update(j, i, a[i]);
		// cout << "updated\n";
	}
	seg = new no(1, n, a);
	for(int i = n - 1;i >= 1;i--){
		int j = first_major(i, n, a[i]);
		sfx[i] = sfx[j + 1] + 1ll * (j - i + 1) * a[i];
		seg->update(i, j, a[i]);
	}

	for(int i = 1;i <= n;i++){
		if(a[i] >= a[i - 1] && a[i] >= a[i + 1] && 0ll + pfx[i - 1] + sfx[i + 1] + a[i] > maxans)
			maxans = 0ll + pfx[i - 1] + sfx[i + 1] + a[i], id = i;
	}

	ans[id] = a[id];
	for(int i = id - 1;i >= 1;i--)
		ans[i] = min(a[i], ans[i + 1]);
	for(int i = id + 1;i <= n;i++)
		ans[i] = min(a[i], ans[i - 1]);
	for(int i = 1;i <= n;i++)
		cout << ans[i] << " ";
}


#include <bits/stdc++.h>

using namespace std;
const int MAXN = 500100;

int n, id, a[MAXN], pfx[MAXN], sfx[MAXN], ans[MAXN];
long long maxans = 0ll;

struct no{
	int l, r, mid, x, lz;
	no *fe, *fd;

	no(int l, int r, int v[]) : l(l), r(r), mid((l + r) >> 1), x(v[l]), lz(0) {
		if(l != r)
			fe = new no(l, mid, v), fd = new no(mid + 1, r, v), x = max(fe->x, fd->x);
	}

	void refresh(){
		if(lz != 0){
			fe->x = lz, fd->x = lz, fe->lz = lz, fd->lz = lz, lz = 0;
		}
	}

	int get(int a, int b){
		if(b < l || r < a)
			return 0;
		if(a <= l && r <= b)
			return x;
		return max(fe->get(a, b), fd->get(a, b));
	}

	void update(int a, int b, int k){
		if(b < l || r < a)
			return;
		refresh();
		if(a <= l && r <= b)
			return void(x = k);
		fe->update(a, b, k), fd->update(a, b, k);
		fe->refresh(), fd->refresh();
		x = max(fe->x, fd->x);
	}
};

int first_major(int l, int r, int x, no &seg){
	while(l < r){
		int m = (l + r) >> 1;
		if(seg.get(m, m) > x)
			r = m;
		else
			l = m + 1;
	}
	return r;
}

int main(){
	cin >> n;
	for(int i = 1;i <= n;i++)
		cin >> a[i];
	no seg(1, n, a);

	pfx[1] = a[1], sfx[n] = a[n];
	for(int i = 2;i <= n;i++){
		int j = first_major(1, i, a[i], seg);
		pfx[i] = pfx[j - 1] + (i - j + 1) * a[i];
		seg.update(j, i, a[i]);
	}
	seg = no(1, n, a);
	for(int i = n - 1;i >= 1;i--){
		int j = first_major(i, n, a[i], seg);
		sfx[i] = sfx[j + 1] + (j - i + 1) * a[i];
		seg.update(i, j, a[i]);
	}

	for(int i = 1;i <= n;i++){
		if(a[i] >= a[i - 1] && a[i] >= a[i + 1] && 0ll + pfx[i - 1] + sfx[i + 1] + a[i] > maxans)
			maxans = 0ll + pfx[i - 1] + sfx[i + 1] + a[i], id = i;
	}

	ans[id] = a[id];
	for(int i = id - 1;i >= 1;i--)
		ans[i] = min(a[i], ans[i + 1]);
	for(int i = id + 1;i <= n;i++)
		ans[i] = min(a[i], ans[i - 1]);
	for(int i = 1;i <= n;i++)
		cout << ans[i] << " ";
}


#include <bits/stdc++.h>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for(int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for(int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef tuple<int, int, ll, int> query;

const int MAX = 1e5 + 5;
constexpr int SQRT_MAX = sqrt(MAX) + 5;
int BLOCK_SIZE;
int N, Q;
int a[MAX], b[MAX], ans[MAX];

typedef struct hull {
	int ptr;
	vector<int> slope, yy, id;

	hull() {
		ptr = 0;
	}

	inline bool bad(int l1, int l2, int l3) {
		return (((ll) (slope[l1] - slope[l3])) * ((ll) (yy[l2] - yy[l1]))) > (((ll) (slope[l1] - slope[l2])) * ((ll) (yy[l3] - yy[l1])));
	}

	void add(int m, int y, int i) {
		slope.push_back(m);
		yy.push_back(y);
		id.push_back(i);
		while((int) slope.size() >= 3 && bad(slope.size() - 3, slope.size() - 2, slope.size() - 1)) {
			slope.erase(slope.end() - 2);
			yy.erase(yy.end() - 2);
			id.erase(id.end() - 2);
		}
	}

	pair<ll, int> query(ll x) {
		if(ptr >= (int) slope.size()) {
			ptr = slope.size() - 1;
		}
		while(ptr < (int) slope.size() - 1 && slope[ptr] * x + yy[ptr] < slope[ptr + 1] * x + yy[ptr + 1]) {
			ptr++;
		}
		if(N == 100000) {
			debug(slope[ptr]);
			debug(yy[ptr]);
			debug(slope[ptr] * x + yy[ptr]);
		}
		return make_pair(slope[ptr] * x + yy[ptr], id[ptr]);
	}

} hull;

hull hulls[SQRT_MAX];

int main() {
	scanf("%d %d", &N, &Q);
	fori(i, 1, N + 1) {
		scanf("%d %d", b + i, a + i);
	}

	BLOCK_SIZE = sqrt(N);
	vector<query> queries;
	fori(i, 1, Q + 1) {
		int l, r, t;
		scanf("%d %d %d", &l, &r, &t);
		queries.emplace_back(l, r, t, i);
	}
    /*
    l = 14178

	r = 99942

	t = 89269
*/
// cur -> 44720
// ans -> 67282

	int bid = 1;
	int start = 1;
	while(1) {
		int ending = min(N, BLOCK_SIZE * bid);
		vector< tuple<int, int, int> > guys;
		fori(i, start, ending + 1) {
			guys.emplace_back(a[i], b[i], i);
		}
		sort(guys.begin(), guys.end());
		for(auto &each : guys) {
			int aa, bb, id;
			tie(aa, bb, id) = each;
			hulls[bid].add(aa, bb, id);
		}
		if(ending == N) {
			break;
		}
		start = BLOCK_SIZE * bid + 1;
		bid++;
	}

	if(N == 100000) {
		ll cur = 44720;
		ll an = 67282;
		ll tt = 89269;
		debug(a[44720] * tt + b[44720]);
		debug(a[44720]);
		debug(b[44720]);
		debug(a[67282] * tt + b[67282]);
		int curblock = cur / BLOCK_SIZE + (cur % BLOCK_SIZE != 0);
		debug(curblock);
		debug(hulls[curblock].query(tt).first);
		debug(hulls[curblock].query(tt).second);
		int ansblock = an / BLOCK_SIZE + (an % BLOCK_SIZE != 0);
		debug(ansblock);
		debug(hulls[ansblock].query(tt).first);
		debug(hulls[ansblock].query(tt).second);
	}

	sort(queries.begin(), queries.end(), [] (const query &lhs, const query &rhs) {
		return get<2>(lhs) < get<2>(rhs);
	});

	for(auto &each : queries) {
		int l, r, id;
		ll t;
		tie(l, r, t, id) = each;
		int l_block = l / BLOCK_SIZE + (l % BLOCK_SIZE != 0);
		int r_block = r / BLOCK_SIZE + (r % BLOCK_SIZE != 0);
		ll best = -1;
		int idx = -1;
		int l_edge = (l_block == r_block) ? r : min(N, l_block * BLOCK_SIZE);
		int r_edge = (l_block == r_block) ? l : (r_block - 1) * BLOCK_SIZE + 1;
		fori(i, l, l_edge + 1) {
			if(a[i] * t + b[i] > best) {
				best = a[i] * t + b[i];
				idx = i;
			}
		}
		fori(i, r_edge, r + 1) {
			if(a[i] * t + b[i] > best) {
				best = a[i] * t + b[i];
				idx = i;
			}
		}
		l_block++;
		r_block--;
		fori(i, l_block, r_block + 1) {
			auto q = hulls[i].query(t);
			if(q.first > best) {
				best = q.first;
				idx = q.second;
			}
		}
		ans[id] = idx;
	}

	fori(i, 1, Q + 1) {
		printf("%d\n", ans[i]);
	}

	return 0;
}


#include <bits/stdc++.h>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for(int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for(int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef tuple<int, int, int, int> query;

const int MAX = 1e5 + 5;
constexpr int SQRT_MAX = sqrt(MAX) + 5;
int BLOCK_SIZE;
int N, Q;
int a[MAX], b[MAX], ans[MAX];

typedef struct hull {
	int ptr;
	vector<int> slope, yy, id;

	hull() {
		ptr = 0;
	}

	inline bool bad(int l1, int l2, int l3) {
		return (((ll) (slope[l1] - slope[l3])) * ((ll) (yy[l2] - yy[l1]))) > (((ll) (slope[l1] - slope[l2])) * ((ll) (yy[l3] - yy[l1])));
	}

	void add(int m, int y, int i) {
		slope.push_back(m);
		yy.push_back(y);
		id.push_back(i);
		while((int) slope.size() >= 3 && bad(slope.size() - 3, slope.size() - 2, slope.size() - 1)) {
			slope.erase(slope.end() - 2);
			yy.erase(yy.end() - 2);
			id.erase(id.end() - 2);
		}
	}

	pair<ll, int> query(ll x) {
		if(ptr >= (int) slope.size()) {
			ptr = slope.size() - 1;
		}
		while(ptr < (int) slope.size() - 1 && slope[ptr] * x + yy[ptr] < slope[ptr + 1] * x + yy[ptr + 1]) {
			ptr++;
		}
		return make_pair(slope[ptr] * x + yy[ptr], id[ptr]);
	}

} hull;

hull hulls[SQRT_MAX];

int main() {
	scanf("%d %d", &N, &Q);
	fori(i, 1, N + 1) {
		scanf("%d %d", b + i, a + i);
	}

	BLOCK_SIZE = sqrt(N);
	vector<query> queries;
	fori(i, 1, Q + 1) {
		int l, r, t;
		scanf("%d %d %d", &l, &r, &t);
		queries.emplace_back(l, r, t, i);
	}

	int bid = 1;
	int start = 1;
	while(1) {
		int ending = min(N, BLOCK_SIZE * bid);
		vector< tuple<int, int, int> > guys;
		fori(i, start, ending + 1) {
			guys.emplace_back(a[i], b[i], i);
		}
		sort(guys.begin(), guys.end());
		for(auto &each : guys) {
			int aa, bb, id;
			tie(aa, bb, id) = each;
			hulls[bid].add(aa, bb, id);
		}
		if(ending == N) {
			break;
		}
		start = BLOCK_SIZE * bid + 1;
		bid++;
	}

	sort(queries.begin(), queries.end(), [] (const query &lhs, const query &rhs) {
		return get<2>(lhs) < get<2>(rhs);
	});

	for(auto &each : queries) {
		int l, r, id;
		ll t;
		tie(l, r, t, id) = each;
		int l_block = l / BLOCK_SIZE + (l % BLOCK_SIZE != 0);
		int r_block = r / BLOCK_SIZE + (r % BLOCK_SIZE != 0);
		int l_edge = -(1 << 30);
		int r_edge = 1 << 30;
		ll best = -1;
		int idx = -1;
		if(l != (l_block - 1) * BLOCK_SIZE + 1) {
			l_edge = min(N, l_block * BLOCK_SIZE);
			l_block++;
		}
		if(r != r_block * BLOCK_SIZE && r != N) {
			r_edge = (r_block - 1) * BLOCK_SIZE + 1;
			r_block--;
		}
		fori(i, l, l_edge + 1) {
			if(a[i] * t + b[i] > best) {
				best = a[i] * t + b[i];
				idx = i;
			}
		}
		fori(i, r_edge, r + 1) {
			if(a[i] * t + b[i] > best) {
				best = a[i] * t + b[i];
				idx = i;
			}
		}
		fori(i, l_block, r_block + 1) {
			auto q = hulls[i].query(t);
			if(q.first > best) {
				best = q.first;
				idx = q.second;
			}
		}
		ans[id] = idx;
	}

	fori(i, 1, Q + 1) {
		printf("%d\n", ans[i]);
	}

	return 0;
}


#include <bits/stdc++.h>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for(int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for(int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef tuple<int, int, int, int> query;

const int MAX = 1e5 + 5;
constexpr int SQRT_MAX = sqrt(MAX) + 5;
int BLOCK_SIZE;
int N, Q;
int a[MAX], b[MAX], ans[MAX];

typedef struct hull {
	int ptr;
	vector<int> slope, yy, id;

	hull() {
		ptr = 0;
	}

	inline bool bad(int l1, int l2, int l3) {
		return (((ll) (slope[l1] - slope[l3])) * ((ll) (yy[l2] - yy[l1]))) > (((ll) (slope[l1] - slope[l2])) * ((ll) (yy[l3] - yy[l1])));
	}

	void add(int m, int y, int i) {
		slope.push_back(m);
		yy.push_back(y);
		id.push_back(i);
		while((int) slope.size() >= 3 && bad(slope.size() - 3, slope.size() - 2, slope.size() - 1)) {
			slope.erase(slope.end() - 2);
			yy.erase(yy.end() - 2);
			id.erase(id.end() - 2);
		}
	}

	pair<ll, int> query(ll x) {
		if(ptr >= (int) slope.size()) {
			ptr = slope.size() - 1;
		}
		while(ptr < (int) slope.size() - 1 && slope[ptr] * x + yy[ptr] < slope[ptr + 1] * x + yy[ptr + 1]) {
			ptr++;
		}
		return make_pair(slope[ptr] * x + yy[ptr], id[ptr]);
	}

} hull;

hull hulls[SQRT_MAX];

int main() {
	scanf("%d %d", &N, &Q);
	fori(i, 1, N + 1) {
		scanf("%d %d", b + i, a + i);
	}

	BLOCK_SIZE = sqrt(N);
	vector<query> queries;
	fori(i, 1, Q + 1) {
		int l, r, t;
		scanf("%d %d %d", &l, &r, &t);
		queries.emplace_back(l, r, t, i);
	}

	int bid = 1;
	int start = 1;
	while(1) {
		int ending = min(N, BLOCK_SIZE * bid);
		vector< tuple<int, int, int> > guys;
		fori(i, start, ending + 1) {
			guys.emplace_back(a[i], b[i], i);
		}
		sort(guys.begin(), guys.end());
		for(auto &each : guys) {
			int aa, bb, id;
			tie(aa, bb, id) = each;
			hulls[bid].add(aa, bb, id);
		}
		if(ending == N) {
			break;
		}
		start = BLOCK_SIZE * bid + 1;
		bid++;
	}

	sort(queries.begin(), queries.end(), [] (const query &lhs, const query &rhs) {
		return get<2>(lhs) < get<2>(rhs);
	});

	for(auto &each : queries) {
		int l, r, id;
		ll t;
		tie(l, r, t, id) = each;
		int l_block = l / BLOCK_SIZE + (l % BLOCK_SIZE != 0);
		int r_block = r / BLOCK_SIZE + (r % BLOCK_SIZE != 0);
		ll best = -1;
		int idx = -1;
		if(l_block == r_block) {
			fori(i, l, r + 1) {
				if(a[i] * t + b[i] > best) {
					best = a[i] * t + b[i];
					idx = i;
				}
			}
			ans[id] = idx;
			continue;
		}
		int l_edge = min(N, l_block * BLOCK_SIZE);
		int r_edge = (r_block - 1) * BLOCK_SIZE + 1;
		fori(i, l, l_edge + 1) {
			if(a[i] * t + b[i] > best) {
				best = a[i] * t + b[i];
				idx = i;
			}
		}
		fori(i, r_edge, r + 1) {
			if(a[i] * t + b[i] > best) {
				best = a[i] * t + b[i];
				idx = i;
			}
		}
		l_block++;
		r_block--;
		fori(i, l_block, r_block + 1) {
			auto q = hulls[i].query(t);
			if(q.first > best) {
				best = q.first;
				idx = q.second;
			}
		}
		ans[id] = idx;
	}

	fori(i, 1, Q + 1) {
		printf("%d\n", ans[i]);
	}

	return 0;
}