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

typedef long long ll;
typedef pair<ll, ll> P;


#define rep(i,n) for(ll (i)=0; (i)<(ll)(n); (i)++)
#define frep(i,m,n) for(ll (i)=(m); (i)<=(ll)(n); (i)++)
#define rrep(i,n) for(ll (i)=(n)-1; (i)>-1; (i)--)
#define frrep(i,m,n) for(ll (i)=(n); (i)>(ll)(m); (i)--)
#define ALL(x) (x).begin(), (x).end()
#define PB(x) push_back(x)
#define MP(x, y) make_pair(x, y)

const ll INF = 100100100100100100;
const ll MOD = 1000000007;
const ll TREE_SIZE = 100100;

// get abs
ll my_abs(ll a);
// a^n
ll a_n(ll a, ll n);
// get gcd
ll my_gcd(ll a, ll b);
// a^(-1) % MOD 
ll inv(ll a);
// (a+b+c)%MOD
ll madd(ll a, ll b, ll c);
// (a-b)%MOD
ll msub(ll a, ll b);
// (a*b*c)%MOD
ll mtime(ll a, ll b, ll c);
// make vector of (n!)%MOD, (n!)^(-1)%MOD
void factorial_map(vector<ll> &n, vector<ll> &ninv);
// map of result of factorization
void factorization(ll n, map<ll, ll> &a);
// calculate GCD of 2 numbers using result of factorization
ll gcd_map(map<ll, ll> a, map<ll, ll> b);
// calculate LCM of 2 numbers using result of factorization
ll lcm_map(map<ll, ll> a, map<ll, ll> b);
// list of prime (is_prime.size() = n + 1, primes.size() = 0)
// primes: list of prime numbers
// is_prime: is_prime[i] == "if i is a prime number"
void prime_list(ll n, vector<ll> &primes, vector<bool> &is_prime);

struct edge {ll to, cost;};
class Unionfind {
    public:
        vector<ll> par, siz, rank;
        Unionfind();
        ll root(ll x);
        void merge(ll x, ll y);
        bool issame(ll x, ll y);
        ll size(ll x);
};


int main() {
    ll h, w, k; cin >> h  >> w >> k;
    vector<string> s(h); // ケーキ
    vector<vector<ll>> ans(h, vector<ll>(w, 0)); // 出力
    ll col = 1; // 色番号
    rep(i, h) cin >> s[i];
    rep(i, h) {
        ll index = 0;
        bool exist = false;
        rep(j, w) {
            if(s[i][j] == '#') {
                exist = true;
                while(index <= j) {
                    ans[i][index]= col;
                    index++;
                }
                col++;
            }
        }
        if(ans[i][w-1] == 0 && exist) {
            ll tmp = w-1;
            while(ans[i][tmp] == 0) {
                ans[i][tmp] = col-1;
                tmp--;
            }
        }
    }
    
    rep(i, h) {
        rep(j, w) {
            if(ans[i][j] == 0) {
                ll index = i;
                while(index < h && ans[index][j] == 0) {
                    index++;
                }
                if(index < h) ans[i][j] = ans[index][j];
            }
        }
    }
    for(ll i = h-1; i >= 0; i--) {
        rep(j, w) {
            if(ans[i][j] == 0) {
                ll index = i;
                while(index >= 0 && ans[index][j] == 0) {
                    index--;
                }
                if(index >= 0) ans[i][j] = ans[index][j];
            }
        }
    }
    
    rep(i, h) {
        rep(j, w) {
            cout << ans[i][j] << ' ';
        }
        cout << endl;
    }

    return 0;
}

ll my_abs(ll a) {
    if(a >= 0) return a;
    else return -1 *a;
}

ll a_n(ll a, ll n) { 
    if(n == 0) return 1;
    
    ll ret = a, count = 1;
    while(count * 2 < n) {
        ret *= ret;
        count *= 2;
    }
    if(count == n) return ret;
    else return (ret * a_n(a, n-count));
}

ll my_gcd(ll a, ll b) {
    if(b == 0) return a;
    return my_gcd(b, a%b);
}

ll inv(ll a) {
    return a_n(a, MOD-2);
}

ll madd(ll a, ll b, ll c) {
    ll ret = (a+b) % MOD;
    return (ret+c) % MOD;
}

ll msub(ll a, ll b) {
    if(a < b) return (a-b+MOD) % MOD;
    else return (a-b) % MOD;
}

ll mtime(ll a, ll b, ll c) {
    ll ret = (a*b) % MOD;
    return (ret*c) % MOD;
}

Unionfind::Unionfind() {
    par.resize(TREE_SIZE);
    siz.resize(TREE_SIZE);
    rank.resize(TREE_SIZE);
    rep(i, TREE_SIZE) {
        par[i] = i;
        siz[i] = 1;
        rank[i] = 0;
    }
}
ll Unionfind::root(ll x) {
    if(par[x] == x) return x;
    else {
        return par[x] = root(par[x]);
    }
}
void Unionfind::merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if(x == y) return;
    if(rank[x] < rank[y]) {
        par[x] = y;
        siz[y] += siz[x];
    }
    else {
        par[y] = x;
        siz[x] += siz[y];
        if(rank[x] == rank[y]) rank[x]++;
    }
}
bool Unionfind::issame(ll x, ll y) {
    return root(x) == root(y);
}
ll Unionfind::size(ll x) {
    return siz[root(x)];
}

// s:スタート地点, G:グラフの構造, d:各節点への距離
void dijkstra(ll s, vector<vector<edge>> &G, vector<ll> &d) {
    priority_queue<P, vector<P>, greater<P>> que;
    d[s] = 0;
    que.push(P(0, s));

    while(!que.empty()) {
        P p = que.top();
        que.pop();

        ll v = p.second;
        if(d[v] < p.first) continue;
        for(ll i = 0; i < G[v].size(); i++) {
            edge e = G[v][i];
            if(d[e.to] > d[v] + e.cost) {
                d[e.to] = d[v] + e.cost;
                que.push(P(d[e.to], e.to));
            }
        }
    }
}

void factorial_map(vector<ll> &n, vector<ll> &ninv) {
    n[0] = 1;
    for(ll i = 1; i < n.size(); i++) n[i] = (n[i-1] * i) % MOD;
    ninv[n.size()-1] = inv(n[n.size()-1]);
    for(ll i = n.size() - 2; i > -1; i--) ninv[i] = (ninv[i+1] * (i+1)) % MOD;
}

void factorization(ll n, map<ll, ll> &a) {
    while((n%2) == 0) {
        n /= 2;
        if(a.count(2)) a.at(2)++;
        else a[2] = 1;
    }
    for(ll i = 3; i*i <= n; i+=2) {
        while((n%i) == 0) {
            n /= i;
            if(a.count(i)) a.at(i)++;
            else a[i] = 1;
        }
    }
    if(n != 1) a[n] = 1;
}

ll gcd_map(map<ll, ll> a, map<ll, ll> b) {
    ll ret = 1;
    for(auto p : a) {
        auto key = p.first;
        auto value = p.second;
        if(b.count(key)) {
            if(value > b.at(key)) ret *= a_n(key, b.at(key));
            else ret *= a_n(key, value);
        }
    }
    return ret;
}

ll lcm_map(map<ll, ll> a, map<ll, ll> b) {
    ll ret = 1;
    for(auto p: a) {
        auto key = p.first;
        auto value = p.second;
        if(b.count(key)) {
            if(value > b.at(key)) ret *= a_n(key, value);
            else ret *= a_n(key, b.at(key));
        }
        else {
            ret *= a_n(key, value);
        }
    }
    for(auto p: b) {
        auto key = p.first;
        auto value = p.second;
        if(a.count(key)) {
            continue;
        }
        else {
            ret *= a_n(key, value);
        }
    }
    return ret;
}

void prime_list(ll n, vector<ll> &primes, vector<bool> &is_prime) {
    ll p = 0;
    rep(i, n + 1) is_prime[i] = true;
    is_prime[0] = false;
    is_prime[1] = false;
    for(ll i = 2; i <= n; i++) {
        if(is_prime[i]) {
            primes.push_back(i);
            for(ll j = 2*i; j <= n; j += i) is_prime[j] = false;
        }
    }
}


Measured memory_bytes: 4484